<?php

declare(strict_types=1);

namespace App\Scolarite\Infrastructure\EventHandler;

use App\Scolarite\Application\Port\PeriodFinder;
use App\Scolarite\Application\Service\RecalculerMoyennesService;
use App\Scolarite\Domain\Event\EvaluationSupprimee;
use App\Scolarite\Domain\Repository\EvaluationRepository;
use App\Scolarite\Domain\Repository\EvaluationStatisticsRepository;
use App\Scolarite\Domain\Repository\GradeRepository;
use App\Shared\Infrastructure\Tenant\TenantContext;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

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

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

        // Charger l'évaluation (encore accessible même en DELETED)
        $evaluation = $this->evaluationRepository->findById($evaluationId, $tenantId);

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

        // Supprimer les stats de l'évaluation
        $this->evaluationStatisticsRepository->delete($evaluationId);

        // Si les notes étaient publiées, recalculer les moyennes des élèves affectés
        if ($evaluation->gradesPublishedAt === null) {
            return;
        }

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

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

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

        foreach ($grades as $g) {
            $studentIds[(string) $g->studentId] = $g->studentId;
        }

        // Recalculer : l'évaluation DELETED sera exclue par findWithPublishedGrades...
        foreach ($studentIds as $studentId) {
            $this->service->recalculerMoyenneEleve(
                $studentId,
                $evaluation->subjectId,
                $evaluation->classId,
                $period,
                $tenantId,
            );
        }
    }
}
