<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Messaging;

use App\Administration\Domain\Event\JourneePedagogiqueAjoutee;
use App\Administration\Domain\Model\User\Role;
use App\Administration\Domain\Repository\UserRepository;

use function array_filter;
use function count;

use Psr\Log\LoggerInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Mime\Email;
use Throwable;
use Twig\Environment;

/**
 * Notifie les enseignants par email lors de l'ajout d'une journée pédagogique.
 */
#[AsMessageHandler(bus: 'event.bus')]
final readonly class NotifyTeachersPedagogicalDayHandler
{
    public function __construct(
        private MailerInterface $mailer,
        private Environment $twig,
        private UserRepository $userRepository,
        private LoggerInterface $logger,
        private string $fromEmail = 'noreply@classeo.fr',
    ) {
    }

    public function __invoke(JourneePedagogiqueAjoutee $event): void
    {
        $allUsers = $this->userRepository->findAllByTenant($event->tenantId);

        $teachers = array_filter(
            $allUsers,
            static fn ($user) => $user->aLeRole(Role::PROF),
        );

        if (count($teachers) === 0) {
            $this->logger->info('Journée pédagogique ajoutée — aucun enseignant à notifier', [
                'tenant_id' => (string) $event->tenantId,
                'date' => $event->date->format('Y-m-d'),
                'label' => $event->label,
            ]);

            return;
        }

        $html = $this->twig->render('emails/pedagogical_day_notification.html.twig', [
            'date' => $event->date->format('d/m/Y'),
            'label' => $event->label,
        ]);

        $sent = 0;

        foreach ($teachers as $teacher) {
            try {
                $email = (new Email())
                    ->from($this->fromEmail)
                    ->to((string) $teacher->email)
                    ->subject('Journée pédagogique — ' . $event->label)
                    ->html($html);

                $this->mailer->send($email);
                ++$sent;
            } catch (Throwable $e) {
                $this->logger->warning('Échec envoi notification journée pédagogique', [
                    'teacher_email' => (string) $teacher->email,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $this->logger->info('Notifications journée pédagogique envoyées', [
            'tenant_id' => (string) $event->tenantId,
            'date' => $event->date->format('Y-m-d'),
            'label' => $event->label,
            'emails_sent' => $sent,
            'teachers_total' => count($teachers),
        ]);
    }
}
