<?php

namespace DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Factory;

use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Infrastructure\Service\Dependency\Resolver\Abstraction\DependencyResolverInterface;
use RuntimeException;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\ConditionalLogic\Conditions\Abstraction\Condition;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Form\Fields\Component\ConditionalLogicComponent;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\ConditionalLogic\Fields\Abstraction\Field;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\ConditionalLogic\Conditions\Abstraction\ConditionWithValue;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Modificator\SingleModificatorCollection;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Form\Fields\ExportMapperFormFields;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Modificator\SingleModificator;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Modificator\Value\FixedValueModificator;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Modificator\Value\PercentValueModificator;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Modificator\ValueModificator;
class ModificatorFactory
{
    /**
     * @var DependencyResolverInterface
     */
    private $resolver;
    public function __construct(DependencyResolverInterface $dependency_resolver)
    {
        $this->resolver = $dependency_resolver;
    }
    public function create_modificator_collection(array $conditions): SingleModificatorCollection
    {
        $collection = new SingleModificatorCollection();
        $conditions = $this->convert_modificator_array($conditions);
        foreach ($conditions as $condition) {
            $single_condition = $this->create_single_modificator($condition);
            $collection->add_condition($single_condition);
        }
        return $collection;
    }
    private function create_single_modificator(array $condition): SingleModificator
    {
        $field = $this->get_field($condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_TYPE]);
        $single_condition = $this->get_condition($condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC], isset($condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC_VALUE]) ? $condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC_VALUE] : '');
        $value_modificator = $this->get_value_modificator($condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH], isset($condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH_VALUE]) ? $condition[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH_VALUE] : '');
        return $this->resolver->resolve(SingleModificator::class, ['field' => $field, 'condition' => $single_condition, 'value_modificator' => $value_modificator]);
    }
    private function get_field(string $field_name): Field
    {
        $fields_classes = ConditionalLogicComponent::get_product_fields();
        foreach ($fields_classes as $class) {
            if ($class::get_name() === $field_name) {
                return $this->resolver->resolve($class);
            }
        }
        throw new RuntimeException(sprintf('Field name %s is not defined', $field_name));
    }
    private function get_condition(string $field_type, string $field_value): Condition
    {
        $fields_classes = ConditionalLogicComponent::get_supported_value_types();
        foreach ($fields_classes as $class) {
            if ($class::get_name() === $field_type) {
                $condition = $this->resolver->resolve($class);
                if ($condition instanceof ConditionWithValue) {
                    $condition->set_value($field_value);
                }
                return $condition;
            }
        }
        throw new RuntimeException(sprintf('Field condition %s is not defined', $field_type));
    }
    private function get_value_modificator(string $field_type, string $field_value): ValueModificator
    {
        $fields_classes = [FixedValueModificator::class, PercentValueModificator::class];
        foreach ($fields_classes as $class) {
            if ($class::get_name() === $field_type) {
                $modificator = $this->resolver->resolve($class);
                if ($modificator instanceof ValueModificator) {
                    $modificator->set_parameter($field_value);
                }
                return $modificator;
            }
        }
        throw new RuntimeException(sprintf('Field modificator %s is not defined', $field_type));
    }
    private function convert_modificator_array(array $conditions): array
    {
        $result = [];
        if (isset($conditions[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_TYPE])) {
            foreach ($conditions[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_TYPE] as $key => $type) {
                if (isset($conditions[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC][$key])) {
                    $value_type = $conditions[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC][$key];
                    $mod_math = $conditions[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH][$key];
                    $mod_math_val = $conditions[ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH_VALUE][$key];
                    if (isset($conditions[$value_type][$key])) {
                        $value = $conditions[$value_type][$key];
                        $result[] = [ExportMapperFormFields::PRODUCT_ADVANCED_MOD_TYPE => $type, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC => $value_type, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC_VALUE => $value, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH => $mod_math, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH_VALUE => $mod_math_val];
                    } else {
                        $result[] = [ExportMapperFormFields::PRODUCT_ADVANCED_MOD_TYPE => $type, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_LOGIC => $value_type, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH => $mod_math, ExportMapperFormFields::PRODUCT_ADVANCED_MOD_MATH_VALUE => $mod_math_val];
                    }
                }
            }
        }
        return $result;
    }
}
