<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Messaging;

use App\Administration\Domain\Event\InvitationParentEnvoyee;
use App\Administration\Domain\Model\Invitation\ParentInvitationId;
use App\Administration\Domain\Model\User\UserId;
use App\Administration\Domain\Repository\ParentInvitationRepository;
use App\Administration\Domain\Repository\UserRepository;
use App\Shared\Infrastructure\Tenant\TenantUrlBuilder;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Mime\Email;
use Twig\Environment;

/**
 * Sends a parent invitation email when a parent invitation is created/sent.
 *
 * Listens for InvitationParentEnvoyee events and sends an email
 * with the activation link to the parent.
 */
#[AsMessageHandler(bus: 'event.bus')]
final readonly class SendParentInvitationEmailHandler
{
    public function __construct(
        private MailerInterface $mailer,
        private Environment $twig,
        private ParentInvitationRepository $invitationRepository,
        private UserRepository $userRepository,
        private TenantUrlBuilder $tenantUrlBuilder,
        private string $fromEmail = 'noreply@classeo.fr',
    ) {
    }

    public function __invoke(InvitationParentEnvoyee $event): void
    {
        $invitation = $this->invitationRepository->findById(
            ParentInvitationId::fromString((string) $event->invitationId),
            $event->tenantId,
        );

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

        $student = $this->userRepository->get(UserId::fromString((string) $event->studentId));
        $studentName = $student->firstName . ' ' . $student->lastName;

        $activationUrl = $this->tenantUrlBuilder->build(
            $event->tenantId,
            '/parent-activate/' . (string) $invitation->code,
        );

        $html = $this->twig->render('emails/parent_invitation.html.twig', [
            'studentName' => $studentName,
            'activationUrl' => $activationUrl,
        ]);

        $email = (new Email())
            ->from($this->fromEmail)
            ->to((string) $event->parentEmail)
            ->subject('Invitation à rejoindre Classeo')
            ->html($html);

        $this->mailer->send($email);
    }
}
