<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Api\Resource;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Post;
use App\Administration\Application\Query\GetAssignmentsForTeacher\TeacherAssignmentDto;
use App\Administration\Domain\Model\TeacherAssignment\TeacherAssignment;
use App\Administration\Infrastructure\Api\Processor\CreateTeacherAssignmentProcessor;
use App\Administration\Infrastructure\Api\Processor\RemoveTeacherAssignmentProcessor;
use App\Administration\Infrastructure\Api\Provider\TeacherAssignmentItemProvider;
use App\Administration\Infrastructure\Api\Provider\TeacherAssignmentsByClassProvider;
use App\Administration\Infrastructure\Api\Provider\TeacherAssignmentsByTeacherProvider;
use App\Administration\Infrastructure\Api\Provider\TeacherAssignmentsCollectionProvider;
use DateTimeImmutable;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * API Resource pour la gestion des affectations enseignants.
 *
 * @see Story 2.8 - Affectation Enseignants aux Classes et Matières
 * @see FR78 - Affecter enseignant à classe et matière
 */
#[ApiResource(
    shortName: 'TeacherAssignment',
    operations: [
        new GetCollection(
            uriTemplate: '/teacher-assignments',
            provider: TeacherAssignmentsCollectionProvider::class,
            name: 'get_all_teacher_assignments',
        ),
        new GetCollection(
            uriTemplate: '/teachers/{teacherId}/assignments',
            uriVariables: [
                'teacherId' => new Link(
                    fromClass: self::class,
                    identifiers: ['teacherId'],
                ),
            ],
            provider: TeacherAssignmentsByTeacherProvider::class,
            name: 'get_teacher_assignments',
        ),
        new GetCollection(
            uriTemplate: '/classes/{classId}/teachers',
            uriVariables: [
                'classId' => new Link(
                    fromClass: self::class,
                    identifiers: ['classId'],
                ),
            ],
            provider: TeacherAssignmentsByClassProvider::class,
            name: 'get_class_teachers',
        ),
        new Post(
            uriTemplate: '/teacher-assignments',
            processor: CreateTeacherAssignmentProcessor::class,
            validationContext: ['groups' => ['Default', 'create']],
            name: 'create_teacher_assignment',
        ),
        new Delete(
            uriTemplate: '/teacher-assignments/{id}',
            provider: TeacherAssignmentItemProvider::class,
            processor: RemoveTeacherAssignmentProcessor::class,
            name: 'remove_teacher_assignment',
        ),
    ],
)]
final class TeacherAssignmentResource
{
    #[ApiProperty(identifier: true)]
    public ?string $id = null;

    #[Assert\NotBlank(message: 'L\'identifiant de l\'enseignant est requis.', groups: ['create'])]
    public ?string $teacherId = null;

    #[Assert\NotBlank(message: 'L\'identifiant de la classe est requis.', groups: ['create'])]
    public ?string $classId = null;

    #[Assert\NotBlank(message: 'L\'identifiant de la matière est requis.', groups: ['create'])]
    public ?string $subjectId = null;

    #[Assert\NotBlank(message: 'L\'identifiant de l\'année scolaire est requis.', groups: ['create'])]
    public ?string $academicYearId = null;

    public ?string $status = null;

    public ?DateTimeImmutable $startDate = null;

    public ?DateTimeImmutable $endDate = null;

    public ?DateTimeImmutable $createdAt = null;

    public ?string $teacherFirstName = null;

    public ?string $teacherLastName = null;

    public ?string $className = null;

    public ?string $subjectName = null;

    public static function fromDomain(TeacherAssignment $assignment): self
    {
        $resource = new self();
        $resource->id = (string) $assignment->id;
        $resource->teacherId = (string) $assignment->teacherId;
        $resource->classId = (string) $assignment->classId;
        $resource->subjectId = (string) $assignment->subjectId;
        $resource->academicYearId = (string) $assignment->academicYearId;
        $resource->status = $assignment->status->value;
        $resource->startDate = $assignment->startDate;
        $resource->endDate = $assignment->endDate;
        $resource->createdAt = $assignment->createdAt;

        return $resource;
    }

    public static function fromDto(TeacherAssignmentDto $dto): self
    {
        $resource = new self();
        $resource->id = $dto->id;
        $resource->teacherId = $dto->teacherId;
        $resource->classId = $dto->classId;
        $resource->subjectId = $dto->subjectId;
        $resource->academicYearId = $dto->academicYearId;
        $resource->status = $dto->status;
        $resource->startDate = $dto->startDate;
        $resource->endDate = $dto->endDate;
        $resource->createdAt = $dto->createdAt;

        return $resource;
    }
}
