<?php

declare(strict_types=1);

namespace App\Administration\Application\Command\CreateClass;

use App\Administration\Domain\Exception\ClasseDejaExistanteException;
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Administration\Domain\Model\SchoolClass\ClassName;
use App\Administration\Domain\Model\SchoolClass\SchoolClass;
use App\Administration\Domain\Model\SchoolClass\SchoolId;
use App\Administration\Domain\Model\SchoolClass\SchoolLevel;
use App\Administration\Domain\Repository\ClassRepository;
use App\Shared\Domain\Clock;
use App\Shared\Domain\Tenant\TenantId;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

/**
 * Handler pour créer une nouvelle classe scolaire.
 */
#[AsMessageHandler(bus: 'command.bus')]
final readonly class CreateClassHandler
{
    public function __construct(
        private ClassRepository $classRepository,
        private Clock $clock,
    ) {
    }

    public function __invoke(CreateClassCommand $command): SchoolClass
    {
        $tenantId = TenantId::fromString($command->tenantId);
        $academicYearId = AcademicYearId::fromString($command->academicYearId);
        $name = new ClassName($command->name);

        // Vérifier l'unicité du nom dans le tenant et l'année scolaire
        $existingClass = $this->classRepository->findByName($name, $tenantId, $academicYearId);
        if ($existingClass !== null) {
            throw ClasseDejaExistanteException::avecNom($name);
        }

        $class = SchoolClass::creer(
            tenantId: $tenantId,
            schoolId: SchoolId::fromString($command->schoolId),
            academicYearId: $academicYearId,
            name: $name,
            level: $command->level !== null ? SchoolLevel::from($command->level) : null,
            capacity: $command->capacity,
            createdAt: $this->clock->now(),
        );

        $this->classRepository->save($class);

        return $class;
    }
}
