<?php

declare(strict_types=1);

namespace apexl\Io\modules\cron\Action;

use apexl\Io\includes\HookManager;
use apexl\Io\modules\cron\Collection\ScheduleCollection;
use apexl\Io\modules\cron\cronModule;
use apexl\Io\modules\cron\Interface\CronAction;
use apexl\Io\modules\cron\Service\ActionHandler;
use Arrayy\Arrayy;
use Symfony\Component\Scheduler\Schedule;
use Symfony\Component\Scheduler\Scheduler;
use Throwable;
use function apexl\Io\assertInstanceOf;

final readonly class RunCron
{
    public function __construct() {}

    /**
     * @throws Throwable
     */
    public function run(HookManager $hookManager): void
    {
        /** @var Arrayy $schedules */
        $schedules = $hookManager->processHook(cronModule::HOOK__REGISTER_CRON_TASK, new ScheduleCollection());

        $scheduler = new Scheduler(
            handlers: $this->handlers($schedules),
            schedules: $schedules->values()->toArray(),
        );

        $scheduler->run();
    }

    private function handlers(Arrayy $schedules): array
    {
        return $schedules->reduce(function (array $carry, Schedule $schedule, string $actionClass): array {
            assertInstanceOf($actionClass, CronAction::class);

            return [
                ...$carry,
                ...[$actionClass => new ActionHandler()]
            ];
        })->toArray();
    }
}