<?php

namespace DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\ConditionalLogic;

use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Mapper\ImportMapperService;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Factory\ConditionalLogicFactory;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Form\Fields\ExportOptionsFormFields;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Form\Fields\Component\ConditionalLogicComponent;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\ConditionalLogic\Conditions\Abstraction\ConditionWithValue;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Exception\ConditionalLogicNoValueException;
use RuntimeException;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\ConditionalLogic\Abstraction\ConditionalLogicServiceInterface;
/**
 * Class ConditionalLogicService
 *
 * @package WPDesk\Library\DropshippingExport\Service\Mapper
 */
class ConditionalLogicService implements ConditionalLogicServiceInterface
{
    const VALUES_SEPARATOR = '|';
    /**
     *
     * @var ImportMapperService
     */
    private $mapper;
    /**
     *
     * @var ConditionalLogicFactory
     */
    private $conditional_logic_factory;
    public function __construct(ImportMapperService $mapper, ConditionalLogicFactory $conditional_logic_factory)
    {
        $this->mapper = $mapper;
        $this->conditional_logic_factory = $conditional_logic_factory;
    }
    public function is_valid(): bool
    {
        $raw = $this->mapper->get_raw_option_value(ExportOptionsFormFields::LOGICAL_CONDITIONS);
        $conditions = is_array($raw) ? $raw : [];
        $count = 0;
        $keys_to_check = [ConditionalLogicComponent::FIELD_TYPE, ConditionalLogicComponent::FIELD_VALUE_TYPE, ConditionalLogicComponent::FIELD_VALUE];
        foreach ($keys_to_check as $key) {
            if (isset($conditions[$key]) && is_array($conditions[$key])) {
                $count = max($count, count($conditions[$key]));
            }
        }
        foreach ($conditions as $val) {
            if (is_array($val)) {
                $count = max($count, count($val));
            }
        }
        if ($count === 0) {
            return \true;
        }
        try {
            for ($i = 0; $i < $count; $i++) {
                if (!isset($conditions[ConditionalLogicComponent::FIELD_VALUE][$i])) {
                    continue;
                }
                $field_type = $conditions[ConditionalLogicComponent::FIELD_TYPE][$i] ?? null;
                $condition_type = $conditions[ConditionalLogicComponent::FIELD_VALUE_TYPE][$i] ?? null;
                if ($field_type === null || $condition_type === null) {
                    return \false;
                }
                $condition = $this->conditional_logic_factory->create_by_name($condition_type);
                if ($condition instanceof ConditionWithValue) {
                    $value_key = $condition::get_name();
                    $raw_compare = $conditions[$value_key][$i] ?? null;
                    if ($raw_compare === null || $raw_compare === '') {
                        return \false;
                    }
                    if (method_exists($condition, 'set_value')) {
                        if (is_array($raw_compare)) {
                            $condition->set_value(implode(self::VALUES_SEPARATOR, array_map('strval', $raw_compare)));
                        } else {
                            $condition->set_value(strval($raw_compare));
                        }
                    }
                }
            }
        } catch (ConditionalLogicNoValueException $e) {
            return \false;
        }
        return \true;
    }
    private function is_condition_with_values_valid(ConditionWithValue $condition, string $compare_value): bool
    {
        if (strpos($compare_value, self::VALUES_SEPARATOR) !== \false) {
            $multiple_values = \explode(self::VALUES_SEPARATOR, $compare_value);
            foreach ($multiple_values as $value) {
                if (\method_exists($condition, 'set_value')) {
                    $condition->set_value(strval(trim($value)));
                }
            }
        } else if (\method_exists($condition, 'set_value')) {
            $condition->set_value(\strval($compare_value));
        }
        return \true;
    }
}
