<?php

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\TimeInvocation;
use idoit\Module\SyneticsFlows\Automation\Trigger\TriggerType\ScheduleTriggerType;
use idoit\Module\SyneticsFlows\Model\AutomationDao;
use idoit\Module\SyneticsFlows\Model\ScheduleDao;
use isys_exception_database;

class TimeInvocationMatcher extends DaoMatcher
{
    public function __construct(protected ScheduleDao $scheduleDao)
    {
        parent::__construct($scheduleDao);
    }

    /**
     * @param Invocation $invocation
     *
     * @return iterable
     * @throws isys_exception_database
     */
    public function findAutomations(Invocation $invocation): iterable
    {
        $automations = parent::findAutomations($invocation);
        $result = [];

        foreach ($automations as $automation) {
            $trigger = $automation->getTrigger();

            if (!$trigger instanceof ScheduleTriggerType) {
                continue;
            }

            if (empty($trigger->getNextStartDate())) {
                continue;
            }
            $scheduledTime = $trigger->getNextStartDate()->format(\DateTime::ATOM);

            if ($this->scheduleDao->isScheduled((int)$automation->getId(), $scheduledTime)) {
                continue;
            }

            $result[] = $automation;
        }
        return $result;
    }

    /**
     * @param Invocation $invocation
     *
     * @return array|string[]
     */
    protected function getExtraConditions(Invocation $invocation): array
    {
        if (!$invocation instanceof TimeInvocation) {
            return [];
        }

        return [
            "JSON_EXTRACT(automation_trigger, \"$.type\") = 'schedule'",
        ];
    }

    /**
     * @param Invocation $invocation
     *
     * @return bool
     */
    public function supports(Invocation $invocation): bool
    {
        return $invocation instanceof TimeInvocation;
    }
}
