<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Service;

use App\Shared\Domain\Clock;
use App\Shared\Infrastructure\Tenant\TenantContext;
use Ramsey\Uuid\Uuid;

/**
 * Résout les identifiants spéciaux 'current' et 'next' en UUID v5 déterministes
 * basés sur le tenant et l'année scolaire.
 *
 * L'année scolaire est calculée selon le calendrier français :
 * septembre → juin (ex: sept 2025 = année 2025-2026).
 */
final readonly class CurrentAcademicYearResolver
{
    /** Namespace UUID v5 dédié aux années scolaires. */
    private const string NAMESPACE = '6ba7b814-9dad-11d1-80b4-00c04fd430c8';

    public function __construct(
        private TenantContext $tenantContext,
        private Clock $clock,
    ) {
    }

    /**
     * @return string|null UUID résolu, ou null si l'identifiant est invalide
     */
    public function resolve(string $academicYearId): ?string
    {
        if (Uuid::isValid($academicYearId)) {
            return $academicYearId;
        }

        $startYear = $this->resolveStartYear($academicYearId);
        if ($startYear === null) {
            return null;
        }

        $tenantId = (string) $this->tenantContext->getCurrentTenantId();
        $name = $tenantId . ':' . $startYear . '-' . ($startYear + 1);

        return Uuid::uuid5(self::NAMESPACE, $name)->toString();
    }

    /**
     * Résout l'année de début scolaire pour un identifiant spécial.
     *
     * @return int|null L'année de début (ex: 2025 pour 2025-2026), ou null si invalide
     */
    public function resolveStartYear(string $academicYearId): ?int
    {
        $offset = match ($academicYearId) {
            'previous' => -1,
            'current' => 0,
            'next' => 1,
            default => null,
        };

        if ($offset === null) {
            return null;
        }

        $now = $this->clock->now();
        $month = (int) $now->format('n');
        $year = (int) $now->format('Y');

        return ($month >= 9 ? $year : $year - 1) + $offset;
    }
}
