<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Scheduler\Validation;

use PpPhp\Core\Platform\Event\Scheduler\EventScheduler;

final class SchedulerVerifier
{
    public function verify(): array
    {
        $scheduler = new EventScheduler();

        $later = $scheduler->dispatchLater('scheduler.later', 0);
        $afterResponse = $scheduler->dispatchAfterResponse('scheduler.after_response');
        $at = $scheduler->dispatchAt('scheduler.at', date('c', time() - 1));
        $every = $scheduler->dispatchEvery('scheduler.every', 'PT1S');

        $snapshot = $scheduler->snapshot();
        $executed = $scheduler->run(static function (): void {});

        $cancelId = $scheduler->dispatchLater('scheduler.cancel', 10);
        $cancelled = $scheduler->cancel($cancelId);

        /*
         * Correct scheduler semantics:
         * - dispatchLater(..., 0), dispatchAfterResponse(), and dispatchAt(past) are due immediately.
         * - dispatchEvery('PT1S') is recurring, but its first run is after the interval, not immediately.
         */
        $checks = [
            'scheduleCreation' => $later !== '' && $afterResponse !== '' && $at !== '' && $every !== '',
            'snapshot' => count($snapshot->events()) >= 4,
            'execution' => $executed >= 3,
            'recurringPending' => $scheduler->statistics()->pending() >= 1,
            'cancel' => $cancelled,
            'statistics' => ($scheduler->statistics()->toArray()['total'] ?? 0) >= 5,
        ];

        $issues = [];
        foreach ($checks as $check => $ok) {
            if (!$ok) {
                $issues[] = ['check' => $check, 'message' => 'Scheduler verification failed: ' . $check];
            }
        }

        return [
            'ok' => !in_array(false, $checks, true),
            'checks' => $checks,
            'issues' => $issues,
            'summary' => [
                'scheduled' => count($snapshot->events()),
                'executed' => $executed,
                'pending' => $scheduler->statistics()->pending(),
                'score' => in_array(false, $checks, true) ? 80 : 100,
            ],
        ];
    }
}
