<?php

declare(strict_types=1);

namespace App\Administration\Application\Query\IsSchoolDay;

use App\Administration\Domain\Model\SchoolCalendar\SchoolCalendarRepository;
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Shared\Domain\Tenant\TenantId;
use DateTimeImmutable;
use InvalidArgumentException;

use function preg_match;

use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler(bus: 'query.bus')]
final readonly class IsSchoolDayHandler
{
    public function __construct(
        private SchoolCalendarRepository $calendarRepository,
    ) {
    }

    public function __invoke(IsSchoolDayQuery $query): bool
    {
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $query->date) !== 1) {
            throw new InvalidArgumentException('La date doit être au format YYYY-MM-DD.');
        }

        [$y, $m, $d] = explode('-', $query->date);
        if (!checkdate((int) $m, (int) $d, (int) $y)) {
            throw new InvalidArgumentException('La date n\'existe pas dans le calendrier.');
        }

        $date = new DateTimeImmutable($query->date);

        // Weekend = pas un jour d'école
        $dayOfWeek = (int) $date->format('N');
        if ($dayOfWeek >= 6) {
            return false;
        }

        $tenantId = TenantId::fromString($query->tenantId);
        $academicYearId = AcademicYearId::fromString($query->academicYearId);

        $calendar = $this->calendarRepository->findByTenantAndYear($tenantId, $academicYearId);

        if ($calendar === null) {
            // Pas de calendrier configuré : on considère que c'est un jour ouvré (lundi-vendredi)
            return true;
        }

        return $calendar->estJourOuvre($date);
    }
}
