<?php

declare(strict_types=1);

namespace App\Scolarite\Application\Query\GetScheduleSlots;

use App\Administration\Domain\Model\SchoolClass\ClassId;
use App\Administration\Domain\Model\User\UserId;
use App\Scolarite\Domain\Model\Schedule\ScheduleSlot;
use App\Scolarite\Domain\Repository\ScheduleSlotRepository;
use App\Shared\Domain\Tenant\TenantId;

use function array_filter;
use function array_map;
use function array_values;

use Ramsey\Uuid\Exception\InvalidUuidStringException;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler(bus: 'query.bus')]
final readonly class GetScheduleSlotsHandler
{
    public function __construct(
        private ScheduleSlotRepository $repository,
    ) {
    }

    /** @return array<ScheduleSlotDto> */
    public function __invoke(GetScheduleSlotsQuery $query): array
    {
        try {
            $tenantId = TenantId::fromString($query->tenantId);

            if ($query->classId !== null) {
                $slots = $this->repository->findByClass(ClassId::fromString($query->classId), $tenantId);

                if ($query->teacherId !== null) {
                    $teacherId = UserId::fromString($query->teacherId);
                    $slots = array_values(array_filter(
                        $slots,
                        static fn (ScheduleSlot $slot) => $slot->teacherId->equals($teacherId),
                    ));
                }
            } elseif ($query->teacherId !== null) {
                $slots = $this->repository->findByTeacher(UserId::fromString($query->teacherId), $tenantId);
            } else {
                $slots = [];
            }
        } catch (InvalidUuidStringException) {
            return [];
        }

        return array_map(ScheduleSlotDto::fromDomain(...), $slots);
    }
}
