<?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\Link;
use ApiPlatform\Metadata\Post;
use App\Administration\Application\Query\GetParentsForStudent\GuardianForStudentDto;
use App\Administration\Domain\Model\StudentGuardian\StudentGuardian;
use App\Administration\Infrastructure\Api\Processor\LinkParentToStudentProcessor;
use App\Administration\Infrastructure\Api\Processor\UnlinkParentFromStudentProcessor;
use App\Administration\Infrastructure\Api\Provider\GuardianItemProvider;
use App\Administration\Infrastructure\Api\Provider\GuardiansForStudentProvider;
use DateTimeImmutable;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * API Resource pour la gestion des liaisons parent-élève.
 *
 * @see Story 2.7 - Liaison Parents-Enfants
 */
#[ApiResource(
    shortName: 'StudentGuardian',
    operations: [
        new GetCollection(
            uriTemplate: '/students/{studentId}/guardians',
            uriVariables: [
                'studentId' => new Link(
                    fromClass: self::class,
                    identifiers: ['studentId'],
                ),
            ],
            provider: GuardiansForStudentProvider::class,
            name: 'get_student_guardians',
        ),
        new Get(
            uriTemplate: '/students/{studentId}/guardians/{guardianId}',
            uriVariables: [
                'studentId' => new Link(
                    fromClass: self::class,
                    identifiers: ['studentId'],
                ),
                'guardianId' => new Link(
                    fromClass: self::class,
                    identifiers: ['guardianId'],
                ),
            ],
            provider: GuardianItemProvider::class,
            name: 'get_student_guardian',
        ),
        new Post(
            uriTemplate: '/students/{studentId}/guardians',
            uriVariables: [
                'studentId' => new Link(
                    fromClass: self::class,
                    identifiers: ['studentId'],
                ),
            ],
            processor: LinkParentToStudentProcessor::class,
            validationContext: ['groups' => ['Default', 'create']],
            name: 'link_parent_to_student',
        ),
        new Delete(
            uriTemplate: '/students/{studentId}/guardians/{guardianId}',
            uriVariables: [
                'studentId' => new Link(
                    fromClass: self::class,
                    identifiers: ['studentId'],
                ),
                'guardianId' => new Link(
                    fromClass: self::class,
                    identifiers: ['guardianId'],
                ),
            ],
            provider: GuardianItemProvider::class,
            processor: UnlinkParentFromStudentProcessor::class,
            name: 'unlink_parent_from_student',
        ),
    ],
)]
final class StudentGuardianResource
{
    #[ApiProperty(identifier: false)]
    public ?string $id = null;

    #[ApiProperty(identifier: true)]
    public ?string $studentId = null;

    #[ApiProperty(identifier: true)]
    #[Assert\NotBlank(message: 'L\'identifiant du parent est requis.', groups: ['create'])]
    #[Assert\Uuid(message: 'L\'identifiant du parent n\'est pas un UUID valide.', groups: ['create'])]
    public ?string $guardianId = null;

    #[Assert\NotBlank(message: 'Le type de relation est requis.', groups: ['create'])]
    #[Assert\Choice(
        choices: ['père', 'mère', 'tuteur', 'tutrice', 'grand-père', 'grand-mère', 'autre'],
        message: 'Le type de relation n\'est pas valide.',
        groups: ['create'],
    )]
    public ?string $relationshipType = null;

    public ?string $relationshipLabel = null;

    public ?DateTimeImmutable $linkedAt = null;

    public ?string $firstName = null;

    public ?string $lastName = null;

    public ?string $email = null;

    public static function fromDomain(StudentGuardian $link): self
    {
        $resource = new self();
        $resource->id = (string) $link->id;
        $resource->studentId = (string) $link->studentId;
        $resource->guardianId = (string) $link->guardianId;
        $resource->relationshipType = $link->relationshipType->value;
        $resource->relationshipLabel = $link->relationshipType->label();
        $resource->linkedAt = $link->createdAt;

        return $resource;
    }

    public static function fromDto(GuardianForStudentDto $dto): self
    {
        $resource = new self();
        $resource->id = $dto->linkId;
        $resource->guardianId = $dto->guardianId;
        $resource->relationshipType = $dto->relationshipType;
        $resource->relationshipLabel = $dto->relationshipLabel;
        $resource->linkedAt = $dto->linkedAt;
        $resource->firstName = $dto->firstName;
        $resource->lastName = $dto->lastName;
        $resource->email = $dto->email;

        return $resource;
    }
}
