<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Infrastructure\Service;

use App\Administration\Infrastructure\Service\FrenchPublicHolidaysCalculator;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class FrenchPublicHolidaysCalculatorTest extends TestCase
{
    private FrenchPublicHolidaysCalculator $calculator;

    protected function setUp(): void
    {
        $this->calculator = new FrenchPublicHolidaysCalculator();
    }

    #[Test]
    public function itReturns11HolidaysForAcademicYear(): void
    {
        $holidays = $this->calculator->pourAnneeScolaire('2024-2025');

        self::assertCount(11, $holidays);
    }

    #[Test]
    public function itReturnsFixedHolidaysFor20242025(): void
    {
        $holidays = $this->calculator->pourAnneeScolaire('2024-2025');
        $dates = array_column($holidays, 'date');

        self::assertContains('2024-11-01', $dates); // Toussaint
        self::assertContains('2024-11-11', $dates); // Armistice
        self::assertContains('2024-12-25', $dates); // Noël
        self::assertContains('2025-01-01', $dates); // Jour de l'an
        self::assertContains('2025-05-01', $dates); // Fête du travail
        self::assertContains('2025-05-08', $dates); // Victoire 1945
        self::assertContains('2025-07-14', $dates); // Fête nationale
        self::assertContains('2025-08-15', $dates); // Assomption
    }

    #[Test]
    public function itCalculatesEasterBasedHolidaysFor2025(): void
    {
        // Pâques 2025 = 20 avril 2025
        $holidays = $this->calculator->pourAnneeScolaire('2024-2025');
        $dates = array_column($holidays, 'date');

        self::assertContains('2025-04-21', $dates); // Lundi de Pâques (20 avril + 1)
        self::assertContains('2025-05-29', $dates); // Ascension (20 avril + 39)
        self::assertContains('2025-06-09', $dates); // Pentecôte (20 avril + 50)
    }

    #[Test]
    public function itCalculatesEasterBasedHolidaysFor2026(): void
    {
        // Pâques 2026 = 5 avril 2026
        $holidays = $this->calculator->pourAnneeScolaire('2025-2026');
        $dates = array_column($holidays, 'date');

        self::assertContains('2026-04-06', $dates); // Lundi de Pâques (5 avril + 1)
        self::assertContains('2026-05-14', $dates); // Ascension (5 avril + 39)
        self::assertContains('2026-05-25', $dates); // Pentecôte (5 avril + 50)
    }

    #[Test]
    public function holidaysAreSortedByDate(): void
    {
        $holidays = $this->calculator->pourAnneeScolaire('2024-2025');
        $dates = array_column($holidays, 'date');

        $sorted = $dates;
        sort($sorted);

        self::assertSame($sorted, $dates);
    }

    #[Test]
    public function eachHolidayHasDateAndLabel(): void
    {
        $holidays = $this->calculator->pourAnneeScolaire('2025-2026');

        foreach ($holidays as $holiday) {
            self::assertArrayHasKey('date', $holiday);
            self::assertArrayHasKey('label', $holiday);
            self::assertMatchesRegularExpression('/^\d{4}-\d{2}-\d{2}$/', $holiday['date']);
            self::assertNotEmpty($holiday['label']);
        }
    }
}
