<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Infrastructure\Api\Resource;

use App\Administration\Application\Query\GetAssignmentsForTeacher\TeacherAssignmentDto;
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Administration\Domain\Model\SchoolClass\ClassId;
use App\Administration\Domain\Model\Subject\SubjectId;
use App\Administration\Domain\Model\TeacherAssignment\TeacherAssignment;
use App\Administration\Domain\Model\User\UserId;
use App\Administration\Infrastructure\Api\Resource\TeacherAssignmentResource;
use App\Shared\Domain\Tenant\TenantId;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class TeacherAssignmentResourceTest extends TestCase
{
    private const string TENANT_ID = '550e8400-e29b-41d4-a716-446655440001';
    private const string TEACHER_ID = '550e8400-e29b-41d4-a716-446655440010';
    private const string CLASS_ID = '550e8400-e29b-41d4-a716-446655440020';
    private const string SUBJECT_ID = '550e8400-e29b-41d4-a716-446655440030';
    private const string ACADEMIC_YEAR_ID = '550e8400-e29b-41d4-a716-446655440040';

    #[Test]
    public function fromDomainMapsCorrectly(): void
    {
        $createdAt = new DateTimeImmutable('2026-02-10 10:00:00');

        $assignment = TeacherAssignment::creer(
            tenantId: TenantId::fromString(self::TENANT_ID),
            teacherId: UserId::fromString(self::TEACHER_ID),
            classId: ClassId::fromString(self::CLASS_ID),
            subjectId: SubjectId::fromString(self::SUBJECT_ID),
            academicYearId: AcademicYearId::fromString(self::ACADEMIC_YEAR_ID),
            createdAt: $createdAt,
        );

        $resource = TeacherAssignmentResource::fromDomain($assignment);

        self::assertSame((string) $assignment->id, $resource->id);
        self::assertSame(self::TEACHER_ID, $resource->teacherId);
        self::assertSame(self::CLASS_ID, $resource->classId);
        self::assertSame(self::SUBJECT_ID, $resource->subjectId);
        self::assertSame(self::ACADEMIC_YEAR_ID, $resource->academicYearId);
        self::assertSame('active', $resource->status);
        self::assertEquals($createdAt, $resource->startDate);
        self::assertNull($resource->endDate);
        self::assertEquals($createdAt, $resource->createdAt);
    }

    #[Test]
    public function fromDomainMapsRemovedAssignment(): void
    {
        $createdAt = new DateTimeImmutable('2026-02-10 10:00:00');
        $removedAt = new DateTimeImmutable('2026-02-11 14:00:00');

        $assignment = TeacherAssignment::creer(
            tenantId: TenantId::fromString(self::TENANT_ID),
            teacherId: UserId::fromString(self::TEACHER_ID),
            classId: ClassId::fromString(self::CLASS_ID),
            subjectId: SubjectId::fromString(self::SUBJECT_ID),
            academicYearId: AcademicYearId::fromString(self::ACADEMIC_YEAR_ID),
            createdAt: $createdAt,
        );
        $assignment->retirer($removedAt);

        $resource = TeacherAssignmentResource::fromDomain($assignment);

        self::assertSame('removed', $resource->status);
        self::assertEquals($removedAt, $resource->endDate);
    }

    #[Test]
    public function fromDtoMapsCorrectly(): void
    {
        $createdAt = new DateTimeImmutable('2026-02-10 10:00:00');

        $dto = new TeacherAssignmentDto(
            id: '550e8400-e29b-41d4-a716-446655440099',
            teacherId: self::TEACHER_ID,
            classId: self::CLASS_ID,
            subjectId: self::SUBJECT_ID,
            academicYearId: self::ACADEMIC_YEAR_ID,
            status: 'active',
            startDate: $createdAt,
            endDate: null,
            createdAt: $createdAt,
        );

        $resource = TeacherAssignmentResource::fromDto($dto);

        self::assertSame('550e8400-e29b-41d4-a716-446655440099', $resource->id);
        self::assertSame(self::TEACHER_ID, $resource->teacherId);
        self::assertSame(self::CLASS_ID, $resource->classId);
        self::assertSame(self::SUBJECT_ID, $resource->subjectId);
        self::assertSame(self::ACADEMIC_YEAR_ID, $resource->academicYearId);
        self::assertSame('active', $resource->status);
        self::assertEquals($createdAt, $resource->startDate);
        self::assertNull($resource->endDate);
        self::assertEquals($createdAt, $resource->createdAt);
    }
}
