<?php

declare(strict_types=1);

namespace App\Scolarite\Infrastructure\Api\Resource;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use App\Scolarite\Domain\Model\Grade\Grade;
use App\Scolarite\Infrastructure\Api\Processor\PublishGradesProcessor;
use App\Scolarite\Infrastructure\Api\Processor\SaveAppreciationProcessor;
use App\Scolarite\Infrastructure\Api\Processor\SaveGradesProcessor;
use App\Scolarite\Infrastructure\Api\Provider\GradeCollectionProvider;
use DateTimeImmutable;

#[ApiResource(
    shortName: 'Grade',
    operations: [
        new GetCollection(
            uriTemplate: '/evaluations/{evaluationId}/grades',
            uriVariables: ['evaluationId'],
            provider: GradeCollectionProvider::class,
            itemUriTemplate: '/grades/{id}',
            name: 'get_evaluation_grades',
        ),
        new Put(
            uriTemplate: '/evaluations/{evaluationId}/grades',
            uriVariables: ['evaluationId'],
            read: false,
            processor: SaveGradesProcessor::class,
            name: 'save_evaluation_grades',
        ),
        new Put(
            uriTemplate: '/grades/{id}/appreciation',
            read: false,
            processor: SaveAppreciationProcessor::class,
            name: 'save_grade_appreciation',
        ),
        new Post(
            uriTemplate: '/evaluations/{evaluationId}/publish',
            uriVariables: ['evaluationId'],
            read: false,
            processor: PublishGradesProcessor::class,
            name: 'publish_evaluation_grades',
        ),
    ],
)]
final class GradeResource
{
    #[ApiProperty(identifier: true)]
    public ?string $id = null;

    public ?string $evaluationId = null;

    public ?string $studentId = null;

    public ?string $studentName = null;

    public ?float $value = null;

    public ?string $status = null;

    public ?string $appreciation = null;

    public ?DateTimeImmutable $createdAt = null;

    public ?DateTimeImmutable $updatedAt = null;

    /** @var array<array{studentId: string, value: ?float, status: string}>|null */
    public ?array $grades = null;

    public ?bool $published = null;

    public ?DateTimeImmutable $gradesPublishedAt = null;

    public static function fromDomain(Grade $grade, ?string $studentName = null): self
    {
        $resource = new self();
        $resource->id = (string) $grade->id;
        $resource->evaluationId = (string) $grade->evaluationId;
        $resource->studentId = (string) $grade->studentId;
        $resource->studentName = $studentName;
        $resource->value = $grade->value?->value;
        $resource->status = $grade->status->value;
        $resource->appreciation = $grade->appreciation;
        $resource->createdAt = $grade->createdAt;
        $resource->updatedAt = $grade->updatedAt;

        return $resource;
    }
}
