<?php

declare(strict_types=1);

namespace App\Tests\Unit\Scolarite\Domain\Model\Grade;

use App\Administration\Domain\Model\User\UserId;
use App\Scolarite\Domain\Model\Grade\AppreciationCategory;
use App\Scolarite\Domain\Model\Grade\AppreciationTemplate;
use App\Scolarite\Domain\Model\Grade\AppreciationTemplateId;
use App\Shared\Domain\Tenant\TenantId;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class AppreciationTemplateTest extends TestCase
{
    private const string TENANT_ID = '550e8400-e29b-41d4-a716-446655440001';
    private const string TEACHER_ID = '550e8400-e29b-41d4-a716-446655440010';

    #[Test]
    public function creerSetsAllProperties(): void
    {
        $now = new DateTimeImmutable('2026-03-31 10:00:00');

        $template = AppreciationTemplate::creer(
            tenantId: TenantId::fromString(self::TENANT_ID),
            teacherId: UserId::fromString(self::TEACHER_ID),
            title: 'Très bon travail',
            content: 'Très bon travail, continuez ainsi !',
            category: AppreciationCategory::POSITIVE,
            now: $now,
        );

        self::assertSame('Très bon travail', $template->title);
        self::assertSame('Très bon travail, continuez ainsi !', $template->content);
        self::assertSame(AppreciationCategory::POSITIVE, $template->category);
        self::assertSame(0, $template->usageCount);
        self::assertEquals($now, $template->createdAt);
        self::assertEquals($now, $template->updatedAt);
    }

    #[Test]
    public function creerAcceptsNullCategory(): void
    {
        $template = $this->createTemplate(category: null);

        self::assertNull($template->category);
    }

    #[Test]
    public function modifierUpdatesProperties(): void
    {
        $template = $this->createTemplate();
        $modifiedAt = new DateTimeImmutable('2026-03-31 14:00:00');

        $template->modifier(
            title: 'Nouveau titre',
            content: 'Nouveau contenu',
            category: AppreciationCategory::IMPROVEMENT,
            now: $modifiedAt,
        );

        self::assertSame('Nouveau titre', $template->title);
        self::assertSame('Nouveau contenu', $template->content);
        self::assertSame(AppreciationCategory::IMPROVEMENT, $template->category);
        self::assertEquals($modifiedAt, $template->updatedAt);
    }

    #[Test]
    public function incrementerUtilisationIncreasesCount(): void
    {
        $template = $this->createTemplate();

        $template->incrementerUtilisation();
        self::assertSame(1, $template->usageCount);

        $template->incrementerUtilisation();
        self::assertSame(2, $template->usageCount);
    }

    #[Test]
    public function reconstituteRestoresAllProperties(): void
    {
        $id = AppreciationTemplateId::generate();
        $createdAt = new DateTimeImmutable('2026-03-31 10:00:00');
        $updatedAt = new DateTimeImmutable('2026-03-31 14:00:00');

        $template = AppreciationTemplate::reconstitute(
            id: $id,
            tenantId: TenantId::fromString(self::TENANT_ID),
            teacherId: UserId::fromString(self::TEACHER_ID),
            title: 'Titre',
            content: 'Contenu',
            category: AppreciationCategory::NEUTRAL,
            usageCount: 5,
            createdAt: $createdAt,
            updatedAt: $updatedAt,
        );

        self::assertTrue($template->id->equals($id));
        self::assertSame('Titre', $template->title);
        self::assertSame('Contenu', $template->content);
        self::assertSame(AppreciationCategory::NEUTRAL, $template->category);
        self::assertSame(5, $template->usageCount);
        self::assertEquals($createdAt, $template->createdAt);
        self::assertEquals($updatedAt, $template->updatedAt);
    }

    private function createTemplate(?AppreciationCategory $category = AppreciationCategory::POSITIVE): AppreciationTemplate
    {
        return AppreciationTemplate::creer(
            tenantId: TenantId::fromString(self::TENANT_ID),
            teacherId: UserId::fromString(self::TEACHER_ID),
            title: 'Très bon travail',
            content: 'Très bon travail, continuez ainsi !',
            category: $category,
            now: new DateTimeImmutable('2026-03-31 10:00:00'),
        );
    }
}
