<?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\Template;

use Ferienpass\CoreBundle\Entity\Attendance;
use Ferienpass\CoreBundle\Entity\Offer\OfferInterface;
use Ferienpass\CoreBundle\Entity\Participant\ParticipantInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Twig\Extension\SecurityExtension;
use Symfony\Bundle\SecurityBundle\Security;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

final class ParticipantListPdfTemplateTest extends TestCase
{
    private Environment $twig;
    private Security $security;

    private array $grantedRoles = [];

    protected function setUp(): void
    {
        $loader = new FilesystemLoader([
            __DIR__.'/../../templates',
        ]);
        $loader->addPath(__DIR__.'/../../templates', 'FerienpassCore');
        $this->twig = new Environment($loader);

        $this->security = $this->createMock(Security::class);
        $this->security->method('isGranted')->willReturnCallback(fn ($role) => $this->grantedRoles[$role] ?? false);
        $this->twig->addExtension(new SecurityExtension($this->security));
    }

    public function testDateOfBirthVisibilityInTemplate(): void
    {
        $offer = $this->createMock(OfferInterface::class);
        $offer->method('isCollectDateOfBirth')->willReturnCallback(fn () => $this->collectDateOfBirth);

        $participant = $this->createStub(ParticipantInterface::class);
        $participant->method('getDateOfBirth')->willReturn(new \DateTimeImmutable('2010-01-01'));
        $participant->method('getFirstname')->willReturn('First');
        $participant->method('getLastname')->willReturn('Last');
        $participant->method('getAge')->willReturn(15);

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

        $offer->method('getAttendancesConfirmed')->willReturn(new \Doctrine\Common\Collections\ArrayCollection([$attendance]));
        $offer->method('getAttendancesWaitlisted')->willReturn(new \Doctrine\Common\Collections\ArrayCollection([]));

        // 1. Role granted, setting false -> Should show
        $this->grantedRoles['ROLE_PARTICIPANTS_ADMIN'] = true;
        $this->collectDateOfBirth = false;
        $html = $this->twig->render('participant_list/pdf/page.html.twig', [
            'offer' => $offer,
            'sort' => 'lastname',
            'expanded' => true,
            'consentForms' => [],
        ]);
        self::assertStringContainsString('01.01.2010', $html);

        // 2. Role not granted, setting true -> Should show
        $this->grantedRoles['ROLE_PARTICIPANTS_ADMIN'] = false;
        $this->collectDateOfBirth = true;
        $html = $this->twig->render('participant_list/pdf/page.html.twig', [
            'offer' => $offer,
            'sort' => 'lastname',
            'expanded' => true,
            'consentForms' => [],
        ]);
        self::assertStringContainsString('01.01.2010', $html);

        // 3. Role not granted, setting false -> Should NOT show
        $this->grantedRoles['ROLE_PARTICIPANTS_ADMIN'] = false;
        $this->collectDateOfBirth = false;
        $html = $this->twig->render('participant_list/pdf/page.html.twig', [
            'offer' => $offer,
            'sort' => 'lastname',
            'expanded' => true,
            'consentForms' => [],
        ]);
        self::assertStringNotContainsString('01.01.2010', $html);
    }
}
