<?php

declare(strict_types=1);

namespace App\Scolarite\Infrastructure\EventHandler;

use App\Administration\Domain\Model\User\UserId;
use App\Scolarite\Application\Port\PeriodFinder;
use App\Scolarite\Application\Service\RecalculerMoyennesService;
use App\Scolarite\Domain\Event\NotesPubliees;
use App\Scolarite\Domain\Model\Grade\GradeStatus;
use App\Scolarite\Domain\Repository\EvaluationRepository;
use App\Scolarite\Domain\Repository\GradeRepository;
use App\Shared\Infrastructure\Tenant\TenantContext;

use function array_filter;
use function array_map;
use function array_unique;

use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler(bus: 'event.bus')]
final readonly class RecalculerMoyennesOnNotesPublieesHandler
{
    public function __construct(
        private TenantContext $tenantContext,
        private EvaluationRepository $evaluationRepository,
        private GradeRepository $gradeRepository,
        private PeriodFinder $periodFinder,
        private RecalculerMoyennesService $service,
    ) {
    }

    public function __invoke(NotesPubliees $event): void
    {
        $tenantId = $this->tenantContext->getCurrentTenantId();
        $evaluationId = $event->evaluationId;

        $evaluation = $this->evaluationRepository->findById($evaluationId, $tenantId);

        if ($evaluation === null) {
            return;
        }

        $this->service->recalculerStatistiquesEvaluation($evaluationId, $tenantId);

        $period = $this->periodFinder->findForDate($evaluation->evaluationDate, $tenantId);

        if ($period === null) {
            return;
        }

        $grades = $this->gradeRepository->findByEvaluation($evaluationId, $tenantId);

        $studentIds = array_unique(array_map(
            static fn ($g) => (string) $g->studentId,
            array_filter($grades, static fn ($g) => $g->status === GradeStatus::GRADED),
        ));

        foreach ($studentIds as $studentIdStr) {
            $this->service->recalculerMoyenneEleve(
                UserId::fromString($studentIdStr),
                $evaluation->subjectId,
                $evaluation->classId,
                $period,
                $tenantId,
            );
        }
    }
}
