<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Api\Resource;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Administration\Application\Query\GetStudentsWithClass\StudentWithClassDto;
use App\Administration\Infrastructure\Api\Processor\ChangeStudentClassProcessor;
use App\Administration\Infrastructure\Api\Processor\CreateStudentProcessor;
use App\Administration\Infrastructure\Api\Provider\StudentCollectionProvider;
use App\Administration\Infrastructure\Api\Provider\StudentItemProvider;
use Symfony\Component\Validator\Constraints as Assert;

#[ApiResource(
    shortName: 'Student',
    operations: [
        new GetCollection(
            uriTemplate: '/students',
            provider: StudentCollectionProvider::class,
            name: 'get_students',
        ),
        new Get(
            uriTemplate: '/students/{id}',
            provider: StudentItemProvider::class,
            name: 'get_student',
        ),
        new Post(
            uriTemplate: '/students',
            processor: CreateStudentProcessor::class,
            validationContext: ['groups' => ['Default', 'create']],
            name: 'create_student',
        ),
        new Patch(
            uriTemplate: '/students/{id}/class',
            provider: StudentItemProvider::class,
            processor: ChangeStudentClassProcessor::class,
            validationContext: ['groups' => ['Default', 'change_class']],
            name: 'change_student_class',
        ),
    ],
)]
final class StudentResource
{
    #[ApiProperty(identifier: true)]
    public ?string $id = null;

    #[Assert\NotBlank(message: 'Le prénom est requis.', groups: ['create'])]
    #[Assert\Length(max: 100, maxMessage: 'Le prénom ne doit pas dépasser {{ limit }} caractères.')]
    public ?string $firstName = null;

    #[Assert\NotBlank(message: 'Le nom est requis.', groups: ['create'])]
    #[Assert\Length(max: 100, maxMessage: 'Le nom ne doit pas dépasser {{ limit }} caractères.')]
    public ?string $lastName = null;

    #[Assert\Email(message: 'L\'email n\'est pas valide.')]
    public ?string $email = null;

    #[Assert\NotBlank(message: 'La classe est requise.', groups: ['create', 'change_class'])]
    public ?string $classId = null;

    public ?string $className = null;
    public ?string $classLevel = null;
    public ?string $statut = null;
    public ?string $dateNaissance = null;

    #[Assert\Regex(pattern: '/^[A-Za-z0-9]{11}$/', message: 'L\'INE doit contenir exactement 11 caractères alphanumériques.')]
    public ?string $studentNumber = null;

    public bool $parentalConsent = false;

    public static function fromDto(StudentWithClassDto $dto): self
    {
        $resource = new self();
        $resource->id = $dto->id;
        $resource->firstName = $dto->firstName;
        $resource->lastName = $dto->lastName;
        $resource->email = $dto->email;
        $resource->statut = $dto->statut;
        $resource->studentNumber = $dto->studentNumber;
        $resource->dateNaissance = $dto->dateNaissance;
        $resource->classId = $dto->classId;
        $resource->className = $dto->className;
        $resource->classLevel = $dto->classLevel;

        return $resource;
    }
}
