<?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\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Administration\Domain\Model\SchoolClass\SchoolLevels;
use App\Administration\Infrastructure\Api\Processor\CreateClassProcessor;
use App\Administration\Infrastructure\Api\Processor\DeleteClassProcessor;
use App\Administration\Infrastructure\Api\Processor\UpdateClassProcessor;
use App\Administration\Infrastructure\Api\Provider\ClassCollectionProvider;
use App\Administration\Infrastructure\Api\Provider\ClassItemProvider;
use DateTimeImmutable;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * API Resource pour la gestion des classes scolaires.
 *
 * @see Story 2.1 - Création et Gestion des Classes
 * @see FR73 - Organiser les élèves par groupes pédagogiques
 */
#[ApiResource(
    shortName: 'Class',
    operations: [
        new GetCollection(
            uriTemplate: '/classes',
            provider: ClassCollectionProvider::class,
            name: 'get_classes',
        ),
        new Get(
            uriTemplate: '/classes/{id}',
            provider: ClassItemProvider::class,
            name: 'get_class',
        ),
        new Post(
            uriTemplate: '/classes',
            processor: CreateClassProcessor::class,
            validationContext: ['groups' => ['Default', 'create']],
            name: 'create_class',
        ),
        new Patch(
            uriTemplate: '/classes/{id}',
            provider: ClassItemProvider::class,
            processor: UpdateClassProcessor::class,
            validationContext: ['groups' => ['Default', 'update']],
            name: 'update_class',
        ),
        new Delete(
            uriTemplate: '/classes/{id}',
            provider: ClassItemProvider::class,
            processor: DeleteClassProcessor::class,
            name: 'delete_class',
        ),
    ],
)]
final class ClassResource
{
    #[ApiProperty(identifier: true)]
    public ?string $id = null;

    #[Assert\NotBlank(message: 'Le nom de la classe est requis.', groups: ['create'])]
    #[Assert\Length(
        min: 2,
        max: 50,
        minMessage: 'Le nom de la classe doit contenir au moins {{ limit }} caractères.',
        maxMessage: 'Le nom de la classe ne peut pas dépasser {{ limit }} caractères.',
    )]
    public ?string $name = null;

    #[Assert\Choice(
        choices: SchoolLevels::ALL,
        message: 'Le niveau scolaire doit être un niveau valide.',
    )]
    public ?string $level = null;

    #[Assert\PositiveOrZero(message: 'La capacité doit être un nombre positif.')]
    public ?int $capacity = null;

    public ?string $description = null;

    public ?string $status = null;

    public ?DateTimeImmutable $createdAt = null;

    public ?DateTimeImmutable $updatedAt = null;

    /**
     * Permet de supprimer explicitement le niveau lors d'un PATCH.
     * Si true, le niveau sera mis à null même si level n'est pas fourni.
     */
    #[ApiProperty(readable: false)]
    public ?bool $clearLevel = null;

    /**
     * Permet de supprimer explicitement la capacité lors d'un PATCH.
     * Si true, la capacité sera mise à null même si capacity n'est pas fourni.
     */
    #[ApiProperty(readable: false)]
    public ?bool $clearCapacity = null;

    /**
     * Permet de supprimer explicitement la description lors d'un PATCH.
     * Si true, la description sera mise à null même si description n'est pas fourni.
     */
    #[ApiProperty(readable: false)]
    public ?bool $clearDescription = null;
}
