<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Automation\Trigger\InvocationMatcher;

use idoit\Module\SyneticsFlows\Automation\Automation;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\Invocation;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\ObjectCategoryContext;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\ObjectContext;
use idoit\Module\SyneticsFlows\Model\AutomationDao;

abstract class DaoMatcher implements InvocationMatcher
{
    public function __construct(protected AutomationDao $dao)
    {
    }

    /**
     * @param Invocation $invocation
     *
     * @return iterable<Automation>
     */
    public function findAutomations(Invocation $invocation): iterable
    {
        if (!$this->supports($invocation)) {
            return [];
        }
        $conditions = [
            "automation.status IN ('active','debug')",
        ];
        $context = $invocation->getContext();
        if ($context instanceof ObjectContext) {
            $conditions[] = "(JSON_UNQUOTE(JSON_EXTRACT(automation_trigger, \"$.objectIds\")) is null OR JSON_UNQUOTE(JSON_EXTRACT(automation_trigger, \"$.objectIds\")) = 'null' OR JSON_SEARCH(automation_trigger, 'one', '{$context->getObjectId()}', null, '$.objectIds') is not null)";
            $conditions[] = "(JSON_UNQUOTE(JSON_EXTRACT(automation_trigger, \"$.objectTypes\")) is null OR JSON_UNQUOTE(JSON_EXTRACT(automation_trigger, \"$.objectTypes\")) = 'null' OR JSON_SEARCH(automation_trigger, 'one', '{$context->getObjectType()}', null, '$.objectTypes') is not null)";
        }
        if ($context instanceof ObjectCategoryContext) {
            $conditions[] = "(JSON_UNQUOTE(JSON_EXTRACT(automation_trigger, \"$.category\")) is null OR JSON_UNQUOTE(JSON_EXTRACT(automation_trigger, \"$.category\")) = 'null' OR JSON_SEARCH(automation_trigger, 'one', '{$context->getCategory()}', null, '$.category') is not null)";
        }
        foreach ($this->getExtraConditions($invocation) as $condition) {
            $conditions[] = $condition;
        }

        return $this->dao->getData('AND ' . implode(' AND ', $conditions));
    }

    protected function getExtraConditions(Invocation $invocation): array
    {
        return [];
    }
}
