<?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\Export\Offer;

use Doctrine\Common\Collections\ArrayCollection;
use Ferienpass\CoreBundle\ConsentManager\ConsentManager;
use Ferienpass\CoreBundle\Entity\Attendance;
use Ferienpass\CoreBundle\Entity\Offer\OfferInterface;
use Ferienpass\CoreBundle\Entity\Participant\ParticipantInterface;
use Ferienpass\CoreBundle\Entity\User;
use Ferienpass\CoreBundle\Export\Offer\ConsentsOverviewExport;
use Ferienpass\CoreBundle\Repository\ConsentFormRepository;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Filesystem;
use Twig\Environment as TwigEnvironment;

final class ConsentsOverviewExportTest extends TestCase
{
    public function testSortsByParticipantLastName(): void
    {
        $offer = $this->createStub(OfferInterface::class);
        $filesystem = $this->createStub(Filesystem::class);
        $twig = $this->createMock(TwigEnvironment::class);
        $consentFormRepository = $this->createStub(ConsentFormRepository::class);
        $consentManager = $this->createStub(ConsentManager::class);
        $cacheDir = sys_get_temp_dir();

        $user1 = $this->createStub(User::class);
        $participant1 = $this->createStub(ParticipantInterface::class);
        $participant1->method('getLastname')->willReturn('Zzz');
        $participant1->method('getFirstname')->willReturn('Alice');
        $participant1->method('getUser')->willReturn($user1);

        $user2 = $this->createStub(User::class);
        $participant2 = $this->createStub(ParticipantInterface::class);
        $participant2->method('getLastname')->willReturn('Aaa');
        $participant2->method('getFirstname')->willReturn('Bob');
        $participant2->method('getUser')->willReturn($user2);

        $attendance1 = $this->createStub(Attendance::class);
        $attendance1->method('getParticipant')->willReturn($participant1);

        $attendance2 = $this->createStub(Attendance::class);
        $attendance2->method('getParticipant')->willReturn($participant2);

        $offer->method('getAttendancesConfirmedOrWaitlisted')
            ->willReturn(new ArrayCollection([$attendance1, $attendance2]));

        $consentFormRepository->method('findForOffer')->willReturn([]);

        $twig->expects($this->once())
            ->method('render')
            ->with($this->anything(), $this->callback(static function (array $args) use ($participant1, $participant2) {
                return $args['rows'][0]['participant'] === $participant2 && $args['rows'][1]['participant'] === $participant1;
            }))
            ->willReturn('html');

        $export = new ConsentsOverviewExport($filesystem, $twig, $consentFormRepository, $consentManager, $cacheDir);
        $export->generate($offer);
    }

    public function testSortsByFirstNameIfLastNameIsSame(): void
    {
        $offer = $this->createStub(OfferInterface::class);
        $filesystem = $this->createStub(Filesystem::class);
        $twig = $this->createMock(TwigEnvironment::class);
        $consentFormRepository = $this->createStub(ConsentFormRepository::class);
        $consentManager = $this->createStub(ConsentManager::class);
        $cacheDir = sys_get_temp_dir();

        $user1 = $this->createStub(User::class);
        $participant1 = $this->createStub(ParticipantInterface::class);
        $participant1->method('getLastname')->willReturn('Aaa');
        $participant1->method('getFirstname')->willReturn('Zzz');
        $participant1->method('getUser')->willReturn($user1);

        $user2 = $this->createStub(User::class);
        $participant2 = $this->createStub(ParticipantInterface::class);
        $participant2->method('getLastname')->willReturn('Aaa');
        $participant2->method('getFirstname')->willReturn('Alice');
        $participant2->method('getUser')->willReturn($user2);

        $attendance1 = $this->createStub(Attendance::class);
        $attendance1->method('getParticipant')->willReturn($participant1);

        $attendance2 = $this->createStub(Attendance::class);
        $attendance2->method('getParticipant')->willReturn($participant2);

        $offer->method('getAttendancesConfirmedOrWaitlisted')
            ->willReturn(new ArrayCollection([$attendance1, $attendance2]));

        $consentFormRepository->method('findForOffer')->willReturn([]);

        $twig->expects($this->once())
            ->method('render')
            ->with($this->anything(), $this->callback(static function (array $args) use ($participant1, $participant2) {
                return $args['rows'][0]['participant'] === $participant2 && $args['rows'][1]['participant'] === $participant1;
            }))
            ->willReturn('html');

        $export = new ConsentsOverviewExport($filesystem, $twig, $consentFormRepository, $consentManager, $cacheDir);
        $export->generate($offer);
    }
}
