<?php

declare(strict_types=1);

namespace App\Scolarite\Application\Query\GetReplacedClassesForTeacher;

use App\Administration\Domain\Model\User\UserId;
use App\Administration\Domain\Repository\ClassRepository;
use App\Administration\Domain\Repository\SubjectRepository;
use App\Scolarite\Domain\Repository\TeacherReplacementRepository;
use App\Shared\Domain\Clock;
use App\Shared\Domain\Tenant\TenantId;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler(bus: 'query.bus')]
final readonly class GetReplacedClassesForTeacherHandler
{
    public function __construct(
        private TeacherReplacementRepository $replacementRepository,
        private ClassRepository $classRepository,
        private SubjectRepository $subjectRepository,
        private Clock $clock,
    ) {
    }

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

        $replacements = $this->replacementRepository->findActiveByReplacementTeacher(
            UserId::fromString($query->replacementTeacherId),
            $tenantId,
            $this->clock->now(),
        );

        if ($replacements === []) {
            return [];
        }

        $classNames = [];
        foreach ($this->classRepository->findAllActiveByTenant($tenantId) as $class) {
            $classNames[(string) $class->id] = (string) $class->name;
        }

        $subjectNames = [];
        foreach ($this->subjectRepository->findAllActiveByTenant($tenantId) as $subject) {
            $subjectNames[(string) $subject->id] = (string) $subject->name;
        }

        $result = [];

        foreach ($replacements as $replacement) {
            foreach ($replacement->classes as $pair) {
                $classId = (string) $pair->classId;
                $subjectId = (string) $pair->subjectId;

                $result[] = new ReplacedClassDto(
                    replacementId: (string) $replacement->id,
                    replacedTeacherId: (string) $replacement->replacedTeacherId,
                    classId: $classId,
                    subjectId: $subjectId,
                    className: $classNames[$classId] ?? $classId,
                    subjectName: $subjectNames[$subjectId] ?? $subjectId,
                    startDate: $replacement->startDate,
                    endDate: $replacement->endDate,
                );
            }
        }

        return $result;
    }
}
