<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Tests\MessageHandler;

use Ferienpass\CoreBundle\Message\DispatchDecisionLetters as DispatchDecisionLettersCommand;
use Ferienpass\CoreBundle\MessageHandler\DispatchDecisionLetters;
use Ferienpass\CoreBundle\Repository\AttendanceRepository;
use Ferienpass\CoreBundle\Repository\EditionRepository;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Uid\Uuid;

final class DispatchDecisionLettersTest extends TestCase
{
    public function testDoesNothingWhenEditionNotFound(): void
    {
        $editions = $this->createMock(EditionRepository::class);
        $editions->method('find')->willReturn(null);

        $bus = $this->createMock(MessageBusInterface::class);
        $bus->expects(self::never())->method('dispatch');

        $handler = new DispatchDecisionLetters(
            $this->createMock(AttendanceRepository::class),
            $editions,
            $bus
        );

        $handler(new DispatchDecisionLettersCommand(Uuid::v7()->toRfc4122(), [Uuid::v7()->toRfc4122(), Uuid::v7()->toRfc4122()]), Uuid::v7());
    }

    public function testDispatchesOneEventPerUniqueEmail(): void
    {
        $edition = new \Ferienpass\CoreBundle\Entity\Edition();

        $editions = $this->createMock(EditionRepository::class);
        $editions->method('findOneBy')->with(['uuid' => '1'])->willReturn($edition);

        $offer = new \Ferienpass\CoreBundle\Entity\Offer\Base();

        $participant1 = new \Ferienpass\CoreBundle\Entity\Participant\BaseParticipant();
        $participant1->setEmail('alice@example.com');

        $participant2 = new \Ferienpass\CoreBundle\Entity\Participant\BaseParticipant();
        $participant2->setEmail('alice@example.com'); // same email → grouped

        $a1 = new \Ferienpass\CoreBundle\Entity\Attendance($offer, $participant1);
        $a2 = new \Ferienpass\CoreBundle\Entity\Attendance($offer, $participant2);

        $attendances = $this->createMock(AttendanceRepository::class);
        $attendances->method('findBy')->with(['uuid' => ['1', '2']])->willReturn([$a1, $a2]);

        $dispatched = 0;
        $bus = $this->createMock(MessageBusInterface::class);
        $bus->method('dispatch')->willReturnCallback(static function (mixed $envelope) use (&$dispatched) {
            ++$dispatched;
            if ($envelope instanceof Envelope) {
                return $envelope;
            }

            return new Envelope($envelope);
        });

        $handler = new DispatchDecisionLetters($attendances, $editions, $bus);
        $handler(new DispatchDecisionLettersCommand('1', ['1', '2']), Uuid::v7());

        // Both attendances have the same email → dispatched once
        self::assertSame(1, $dispatched);
    }
}
