<?php

declare(strict_types=1);

namespace App\Scolarite\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\Scolarite\Domain\Model\Homework\Homework;
use App\Scolarite\Domain\Model\Homework\HomeworkRuleException;
use App\Scolarite\Infrastructure\Api\Processor\CreateHomeworkProcessor;
use App\Scolarite\Infrastructure\Api\Processor\DeleteHomeworkProcessor;
use App\Scolarite\Infrastructure\Api\Processor\UpdateHomeworkProcessor;
use App\Scolarite\Infrastructure\Api\Provider\HomeworkCollectionProvider;
use App\Scolarite\Infrastructure\Api\Provider\HomeworkItemProvider;
use DateTimeImmutable;
use Symfony\Component\Validator\Constraints as Assert;

#[ApiResource(
    shortName: 'Homework',
    operations: [
        new GetCollection(
            uriTemplate: '/homework',
            provider: HomeworkCollectionProvider::class,
            name: 'get_homework_list',
        ),
        new Get(
            uriTemplate: '/homework/{id}',
            provider: HomeworkItemProvider::class,
            name: 'get_homework',
        ),
        new Post(
            uriTemplate: '/homework',
            processor: CreateHomeworkProcessor::class,
            validationContext: ['groups' => ['Default', 'create']],
            name: 'create_homework',
        ),
        new Patch(
            uriTemplate: '/homework/{id}',
            provider: HomeworkItemProvider::class,
            processor: UpdateHomeworkProcessor::class,
            validationContext: ['groups' => ['Default', 'update']],
            name: 'update_homework',
        ),
        new Delete(
            uriTemplate: '/homework/{id}',
            provider: HomeworkItemProvider::class,
            processor: DeleteHomeworkProcessor::class,
            name: 'delete_homework',
        ),
    ],
)]
final class HomeworkResource
{
    #[ApiProperty(identifier: true)]
    public ?string $id = null;

    #[Assert\NotBlank(message: 'La classe est requise.', groups: ['create'])]
    #[Assert\Uuid(message: 'L\'identifiant de la classe doit être un UUID valide.', groups: ['create'])]
    public ?string $classId = null;

    #[Assert\NotBlank(message: 'La matière est requise.', groups: ['create'])]
    #[Assert\Uuid(message: 'L\'identifiant de la matière doit être un UUID valide.', groups: ['create'])]
    public ?string $subjectId = null;

    public ?string $teacherId = null;

    #[Assert\NotBlank(message: 'Le titre est requis.', groups: ['create', 'update'])]
    #[Assert\Length(max: 255, maxMessage: 'Le titre ne peut pas dépasser 255 caractères.')]
    public ?string $title = null;

    public ?string $description = null;

    #[Assert\NotBlank(message: 'La date d\'échéance est requise.', groups: ['create', 'update'])]
    public ?string $dueDate = null;

    public ?string $status = null;

    public ?bool $acknowledgeWarning = null;

    public ?string $className = null;

    public ?string $subjectName = null;

    public ?DateTimeImmutable $createdAt = null;

    public ?DateTimeImmutable $updatedAt = null;

    public ?bool $hasRuleOverride = null;

    public ?bool $hasRuleException = null;

    public ?string $ruleExceptionJustification = null;

    public ?string $ruleExceptionRuleType = null;

    public static function fromDomain(
        Homework $homework,
        ?string $className = null,
        ?string $subjectName = null,
        ?HomeworkRuleException $ruleException = null,
    ): self {
        $resource = new self();
        $resource->id = (string) $homework->id;
        $resource->classId = (string) $homework->classId;
        $resource->subjectId = (string) $homework->subjectId;
        $resource->teacherId = (string) $homework->teacherId;
        $resource->title = $homework->title;
        $resource->description = $homework->description;
        $resource->dueDate = $homework->dueDate->format('Y-m-d');
        $resource->status = $homework->status->value;
        $resource->className = $className;
        $resource->subjectName = $subjectName;
        $resource->createdAt = $homework->createdAt;
        $resource->updatedAt = $homework->updatedAt;
        $resource->hasRuleOverride = $homework->ruleOverride !== null;
        $resource->hasRuleException = $ruleException !== null;
        $resource->ruleExceptionJustification = $ruleException?->justification;
        $resource->ruleExceptionRuleType = $ruleException?->ruleType;

        return $resource;
    }
}
