<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Domain\Policy;

use App\Administration\Domain\Policy\ConsentementParentalPolicy;
use App\Shared\Domain\Clock;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class ConsentementParentalPolicyTest extends TestCase
{
    private Clock $clock;
    private ConsentementParentalPolicy $policy;

    protected function setUp(): void
    {
        $this->clock = new class implements Clock {
            public function now(): DateTimeImmutable
            {
                return new DateTimeImmutable('2026-01-31 10:00:00');
            }
        };

        $this->policy = new ConsentementParentalPolicy($this->clock);
    }

    #[Test]
    public function consentementRequisPourUtilisateurDe14Ans(): void
    {
        $dateNaissance = new DateTimeImmutable('2012-01-31');

        self::assertTrue($this->policy->estRequis($dateNaissance));
    }

    #[Test]
    public function consentementRequisPourUtilisateurDe10Ans(): void
    {
        $dateNaissance = new DateTimeImmutable('2016-01-31');

        self::assertTrue($this->policy->estRequis($dateNaissance));
    }

    #[Test]
    public function consentementNonRequisPourUtilisateurDe15Ans(): void
    {
        $dateNaissance = new DateTimeImmutable('2011-01-30');

        self::assertFalse($this->policy->estRequis($dateNaissance));
    }

    #[Test]
    public function consentementNonRequisPourUtilisateurDe16Ans(): void
    {
        $dateNaissance = new DateTimeImmutable('2010-01-31');

        self::assertFalse($this->policy->estRequis($dateNaissance));
    }

    #[Test]
    public function consentementNonRequisSiDateNaissanceNulle(): void
    {
        self::assertFalse($this->policy->estRequis(null));
    }

    #[Test]
    #[DataProvider('agesBordureProvider')]
    public function consentementRequisAuxAgesBordure(
        string $dateNaissance,
        bool $consentementRequis,
        string $description,
    ): void {
        $result = $this->policy->estRequis(new DateTimeImmutable($dateNaissance));

        self::assertSame($consentementRequis, $result, $description);
    }

    /**
     * @return iterable<string, array{string, bool, string}>
     */
    public static function agesBordureProvider(): iterable
    {
        // Current date is 2026-01-31
        yield '14 ans et 364 jours' => [
            '2011-02-01',
            true,
            'Un jour avant 15 ans → consentement requis',
        ];

        yield '15 ans exactement' => [
            '2011-01-31',
            false,
            'Le jour des 15 ans → consentement non requis',
        ];

        yield '15 ans et 1 jour' => [
            '2011-01-30',
            false,
            'Un jour après 15 ans → consentement non requis',
        ];
    }
}
