<?php

namespace App\Tests\Controller;

use App\Entity\Event;
use App\Entity\User;
use App\Service\EventIndexService;
use App\Service\MailerService;
use App\Service\MeilisearchService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class AdminControllerTest extends WebTestCase
{
    public function testDashboardRedirectsWhenNotAuthenticated(): void
    {
        $client = static::createClient();
        $client->request('GET', '/admin');

        self::assertResponseRedirects();
    }

    public function testDashboardDeniedForNonRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser();

        $client->loginUser($user);
        $client->request('GET', '/admin');

        self::assertResponseStatusCodeSame(403);
    }

    public function testDashboardReturnsSuccessForRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($user);
        $client->request('GET', '/admin');

        self::assertResponseIsSuccessful();
    }

    public function testUsersPageReturnsSuccessForRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($user);
        $client->request('GET', '/admin/utilisateurs');

        self::assertResponseIsSuccessful();
    }

    public function testUsersPageDeniedForNonRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser();

        $client->loginUser($user);
        $client->request('GET', '/admin/utilisateurs');

        self::assertResponseStatusCodeSame(403);
    }

    public function testBuyersPageReturnsSuccessForRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($user);
        $client->request('GET', '/admin/acheteurs');

        self::assertResponseIsSuccessful();
    }

    public function testBuyersSearchWithQuery(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->expects(self::once())->method('search')->willReturn([
            'hits' => [],
            'estimatedTotalHits' => 0,
        ]);
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('GET', '/admin/acheteurs?q=test');

        self::assertResponseIsSuccessful();
    }

    public function testSyncMeilisearchWithBuyers(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-sync-'.uniqid().'@example.com');
        $buyer->setFirstName('Sync');
        $buyer->setLastName('Test');
        $buyer->setPassword('$2y$13$hashed');
        $buyer->setIsVerified(true);
        $em->persist($buyer);
        $em->flush();

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->expects(self::exactly(2))->method('createIndexIfNotExists');
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('POST', '/admin/sync-meilisearch');

        self::assertResponseRedirects('/admin');
    }

    public function testSyncMeilisearchWithOrganizers(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);

        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $em->flush();

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->expects(self::exactly(2))->method('createIndexIfNotExists');
        $meilisearch->expects(self::exactly(2))->method('addDocuments');
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('POST', '/admin/sync-meilisearch');

        self::assertResponseRedirects('/admin');
    }

    public function testBuyersSearchWithMeilisearchError(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->method('search')->willThrowException(new \RuntimeException('Meilisearch down'));
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('GET', '/admin/acheteurs?q=test');

        self::assertResponseIsSuccessful();
    }

    public function testBuyersSearchWithResults(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-search-hit-'.uniqid().'@example.com');
        $buyer->setFirstName('Found');
        $buyer->setLastName('User');
        $buyer->setPassword('$2y$13$hashed');
        $buyer->setIsVerified(true);
        $em->persist($buyer);
        $em->flush();

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->method('search')->willReturn([
            'hits' => [['id' => $buyer->getId()]],
            'estimatedTotalHits' => 1,
        ]);
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('GET', '/admin/acheteurs?q=Found');

        self::assertResponseIsSuccessful();
    }

    public function testCreateBuyerWithValidData(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteurs/creer', [
            'first_name' => 'Nouveau',
            'last_name' => 'Acheteur',
            'email' => 'new-buyer-'.uniqid().'@example.com',
        ]);

        self::assertResponseRedirects('/admin/acheteurs');
    }

    public function testCreateBuyerWithDuplicateEmail(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteurs/creer', [
            'first_name' => 'Dup',
            'last_name' => 'Test',
            'email' => $admin->getEmail(),
        ]);

        self::assertResponseRedirects('/admin/acheteurs');
    }

    public function testResendVerificationEmail(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-buyer-'.uniqid().'@example.com');
        $buyer->setFirstName('Buyer');
        $buyer->setLastName('Test');
        $buyer->setPassword('$2y$13$hashed');
        $em->persist($buyer);
        $em->flush();

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteur/'.$buyer->getId().'/renvoyer-verification');

        self::assertResponseRedirects('/admin/acheteurs');

        $em->refresh($buyer);
        self::assertNotNull($buyer->getEmailVerificationToken());
    }

    public function testResetPasswordSendsEmail(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-reset-admin-'.uniqid().'@example.com');
        $buyer->setFirstName('Reset');
        $buyer->setLastName('Test');
        $buyer->setPassword('$2y$13$hashed');
        $buyer->setIsVerified(true);
        $em->persist($buyer);
        $em->flush();

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteur/'.$buyer->getId().'/reset-password');

        self::assertResponseRedirects('/admin/acheteurs');
    }

    public function testDeleteBuyer(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-delete-'.uniqid().'@example.com');
        $buyer->setFirstName('Delete');
        $buyer->setLastName('Test');
        $buyer->setPassword('$2y$13$hashed');
        $em->persist($buyer);
        $em->flush();
        $buyerId = $buyer->getId();

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->expects(self::once())->method('deleteDocument')->with('buyers', $buyerId);
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteur/'.$buyerId.'/supprimer');

        self::assertResponseRedirects('/admin/acheteurs');

        $deleted = $em->getRepository(User::class)->find($buyerId);
        self::assertNull($deleted);
    }

    public function testDeleteBuyerMeilisearchFailureDoesNotBlock(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-delete-fail-'.uniqid().'@example.com');
        $buyer->setFirstName('DeleteFail');
        $buyer->setLastName('Test');
        $buyer->setPassword('$2y$13$hashed');
        $em->persist($buyer);
        $em->flush();
        $buyerId = $buyer->getId();

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->method('deleteDocument')->willThrowException(new \RuntimeException('Meilisearch down'));
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteur/'.$buyerId.'/supprimer');

        self::assertResponseRedirects('/admin/acheteurs');
    }

    public function testForceVerification(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);

        $buyer = new User();
        $buyer->setEmail('test-force-'.uniqid().'@example.com');
        $buyer->setFirstName('Force');
        $buyer->setLastName('Test');
        $buyer->setPassword('$2y$13$hashed');
        $em->persist($buyer);
        $em->flush();

        $client->loginUser($admin);
        $client->request('POST', '/admin/acheteur/'.$buyer->getId().'/forcer-verification');

        self::assertResponseRedirects('/admin/acheteurs');

        $em->refresh($buyer);
        self::assertTrue($buyer->isVerified());
        self::assertNotNull($buyer->getEmailVerifiedAt());
        self::assertNull($buyer->getEmailVerificationToken());
    }

    public function testOrganizersSearchWithQuery(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->expects(self::once())->method('search')->with('organizers')->willReturn([
            'hits' => [],
            'estimatedTotalHits' => 0,
        ]);
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateurs?q=test');

        self::assertResponseIsSuccessful();
    }

    public function testOrganizersSearchWithError(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->method('search')->willThrowException(new \RuntimeException('Meilisearch down'));
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateurs?q=test');

        self::assertResponseIsSuccessful();
    }

    public function testOrganizersPagePendingTab(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateurs');

        self::assertResponseIsSuccessful();
    }

    public function testOrganizersPageApprovedTab(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateurs?tab=approved');

        self::assertResponseIsSuccessful();
    }

    public function testSiretCheckPage(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateur/'.$orga->getId().'/siret');

        self::assertResponseIsSuccessful();
    }

    public function testSiretCheckRedirectsIfApproved(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $em->flush();

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateur/'.$orga->getId().'/siret');

        self::assertResponseRedirects('/admin/organisateurs');
    }

    public function testSiretCheckWithoutSiret(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);

        $orga = new User();
        $orga->setEmail('test-no-siret-'.uniqid().'@example.com');
        $orga->setFirstName('No');
        $orga->setLastName('Siret');
        $orga->setPassword('$2y$13$hashed');
        $orga->setRoles(['ROLE_ORGANIZER']);
        $em->persist($orga);
        $em->flush();

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateur/'.$orga->getId().'/siret');

        self::assertResponseRedirects('/admin/organisateurs');
    }

    public function testSiretRefresh(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orga->getId().'/siret/refresh');

        self::assertResponseRedirects('/admin/organisateur/'.$orga->getId().'/siret');
    }

    public function testEditOrganizerPage(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $orga->setOffer('free');
        $orga->setCommissionRate(3.0);
        $em->flush();

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateur/'.$orga->getId().'/modifier');

        self::assertResponseIsSuccessful();
    }

    public function testEditOrganizerSubmit(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $orga->setOffer('free');
        $orga->setCommissionRate(3.0);
        $em->flush();

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orga->getId().'/modifier', [
            'offer' => 'custom',
            'commission_rate' => '0.5',
        ]);

        self::assertResponseRedirects('/admin/organisateurs?tab=approved');

        $em->refresh($orga);
        self::assertSame('custom', $orga->getOffer());
        self::assertSame(0.5, $orga->getCommissionRate());
    }

    public function testEditOrganizerWithLogo(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $orga->setOffer('basic');
        $orga->setCommissionRate(3.0);
        $em->flush();

        $logo = new \Symfony\Component\HttpFoundation\File\UploadedFile(
            __DIR__.'/../fixtures/logo.png',
            'logo.png',
            'image/png',
            null,
            true,
        );

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orga->getId().'/modifier', [
            'first_name' => $orga->getFirstName(),
            'last_name' => $orga->getLastName(),
            'email' => $orga->getEmail(),
            'company_name' => $orga->getCompanyName(),
            'siret' => $orga->getSiret(),
            'offer' => 'basic',
            'commission_rate' => '3',
        ], ['logo' => $logo]);

        self::assertResponseRedirects('/admin/organisateurs?tab=approved');

        $em->refresh($orga);
        self::assertNotNull($orga->getLogoName());
    }

    public function testEditOrganizerRedirectsIfNotApproved(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateur/'.$orga->getId().'/modifier');

        self::assertResponseRedirects('/admin/organisateurs');
    }

    public function testApproveOrganizer(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $meilisearch = $this->createMock(MeilisearchService::class);
        $meilisearch->expects(self::once())->method('createIndexIfNotExists')->with('organizers');
        $meilisearch->expects(self::once())->method('addDocuments');
        static::getContainer()->set(MeilisearchService::class, $meilisearch);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orga->getId().'/approuver', [
            'offer' => 'basic',
            'commission_rate' => '1.5',
        ]);

        self::assertResponseRedirects('/admin/organisateurs');

        $em->refresh($orga);
        self::assertTrue($orga->isApproved());
        self::assertSame('basic', $orga->getOffer());
        self::assertSame(1.5, $orga->getCommissionRate());
    }

    public function testRejectOrganizer(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orgaId = $orga->getId();

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orgaId.'/refuser', [
            'reason' => 'SIRET invalide, activite non conforme.',
        ]);

        self::assertResponseRedirects('/admin/organisateurs');

        $deleted = $em->getRepository(User::class)->find($orgaId);
        self::assertNull($deleted);
    }

    /**
     * @param list<string> $roles
     */
    private function createUser(array $roles = []): User
    {
        $em = static::getContainer()->get(EntityManagerInterface::class);

        $user = new User();
        $user->setEmail('test-admin-'.uniqid().'@example.com');
        $user->setFirstName('Admin');
        $user->setLastName('User');
        $user->setPassword('$2y$13$hashed');
        $user->setRoles($roles);

        $em->persist($user);
        $em->flush();

        return $user;
    }

    public function testEventsPageReturnsSuccess(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/evenements');

        self::assertResponseIsSuccessful();
    }

    public function testEventsPageWithSearch(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/evenements?q=brocante');

        self::assertResponseIsSuccessful();
    }

    public function testEventsPageDeniedForNonRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser();

        $client->loginUser($user);
        $client->request('GET', '/admin/evenements');

        self::assertResponseStatusCodeSame(403);
    }

    private function createOrganizer(EntityManagerInterface $em): User
    {
        $orga = new User();
        $orga->setEmail('test-orga-'.uniqid().'@example.com');
        $orga->setFirstName('Orga');
        $orga->setLastName('Test');
        $orga->setPassword('$2y$13$hashed');
        $orga->setRoles(['ROLE_ORGANIZER']);
        $orga->setIsVerified(true);
        $orga->setCompanyName('Mon Asso');
        $orga->setSiret('12345678901234');

        $em->persist($orga);
        $em->flush();

        return $orga;
    }

    public function testSuspendOrganizer(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $em->flush();

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orga->getId().'/suspendre');

        self::assertResponseRedirects('/admin/organisateurs?tab=approved');

        $em->refresh($orga);
        self::assertTrue($orga->isSuspended());
    }

    public function testReactivateOrganizer(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $orga->setIsApproved(true);
        $orga->setIsSuspended(true);
        $em->flush();

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateur/'.$orga->getId().'/suspendre');

        self::assertResponseRedirects('/admin/organisateurs?tab=approved');

        $em->refresh($orga);
        self::assertNull($orga->isSuspended());
    }

    public function testOrdersPage(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/commandes');

        self::assertResponseIsSuccessful();
    }

    public function testOrdersPageWithFilters(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/commandes?status=paid&q=test');

        self::assertResponseIsSuccessful();
    }

    public function testLogsPage(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/logs');

        self::assertResponseIsSuccessful();
    }

    public function testInfraPage(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/infra');

        self::assertResponseIsSuccessful();
    }

    public function testInfraPageDeniedForNonRoot(): void
    {
        $client = static::createClient();
        $user = $this->createUser();

        $client->loginUser($user);
        $client->request('GET', '/admin/infra');

        self::assertResponseStatusCodeSame(403);
    }

    public function testInviteOrganizerPage(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $mailer = $this->createMock(MailerService::class);
        static::getContainer()->set(MailerService::class, $mailer);

        $client->loginUser($admin);
        $client->request('GET', '/admin/organisateurs/inviter');

        self::assertResponseIsSuccessful();
    }

    public function testInviteOrganizerSubmit(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateurs/inviter', [
            'company_name' => 'New Asso',
            'first_name' => 'Jean',
            'last_name' => 'Invite',
            'email' => 'invite-admin-'.uniqid().'@example.com',
            'offer' => 'basic',
            'commission_rate' => '2.5',
        ]);

        self::assertResponseRedirects('/admin/organisateurs/inviter');
    }

    public function testInviteOrganizerEmptyFields(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateurs/inviter', [
            'company_name' => '',
            'first_name' => '',
            'last_name' => '',
            'email' => '',
        ]);

        self::assertResponseRedirects('/admin/organisateurs/inviter');
    }

    public function testDeleteInvitation(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);

        $invitation = new \App\Entity\OrganizerInvitation();
        $invitation->setCompanyName('Del Asso');
        $invitation->setFirstName('Del');
        $invitation->setLastName('Test');
        $invitation->setEmail('del-'.uniqid().'@example.com');
        $em->persist($invitation);
        $em->flush();

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateurs/invitation/'.$invitation->getId().'/supprimer');

        self::assertResponseRedirects('/admin/organisateurs/inviter');
    }

    public function testResendInvitation(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects(self::once())->method('sendEmail');
        static::getContainer()->set(MailerService::class, $mailer);

        $invitation = new \App\Entity\OrganizerInvitation();
        $invitation->setCompanyName('Resend Asso');
        $invitation->setFirstName('Resend');
        $invitation->setLastName('Test');
        $invitation->setEmail('resend-'.uniqid().'@example.com');
        $invitation->setStatus(\App\Entity\OrganizerInvitation::STATUS_ACCEPTED);
        $em->persist($invitation);
        $em->flush();

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateurs/invitation/'.$invitation->getId().'/renvoyer');

        self::assertResponseRedirects('/admin/organisateurs/inviter');

        $freshEm = static::getContainer()->get(EntityManagerInterface::class);
        $updated = $freshEm->getRepository(\App\Entity\OrganizerInvitation::class)->find($invitation->getId());
        self::assertSame(\App\Entity\OrganizerInvitation::STATUS_SENT, $updated->getStatus());
    }

    public function testDeleteInvitationNotFound(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateurs/invitation/999999/supprimer');

        self::assertResponseStatusCodeSame(404);
    }

    public function testResendInvitationNotFound(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('POST', '/admin/organisateurs/invitation/999999/renvoyer');

        self::assertResponseStatusCodeSame(404);
    }

    public function testExportCsv(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/export/2026/3');

        self::assertResponseIsSuccessful();
        self::assertStringContainsString('text/csv', $client->getResponse()->headers->get('Content-Type'));
    }

    public function testExportPdf(): void
    {
        $client = static::createClient();
        $admin = $this->createUser(['ROLE_ROOT']);

        $client->loginUser($admin);
        $client->request('GET', '/admin/export/2026/3/pdf');

        self::assertResponseIsSuccessful();
        self::assertStringContainsString('application/pdf', $client->getResponse()->headers->get('Content-Type'));
    }

    private function createEvent(EntityManagerInterface $em, User $organizer): Event
    {
        $event = new Event();
        $event->setAccount($organizer);
        $event->setTitle('Test Event '.uniqid());
        $event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
        $event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
        $event->setAddress('1 rue de la Paix');
        $event->setZipcode('75001');
        $event->setCity('Paris');

        $em->persist($event);
        $em->flush();

        return $event;
    }

    public function testToggleEventOnline(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $event = $this->createEvent($em, $orga);

        $eventIndex = $this->createMock(EventIndexService::class);
        $eventIndex->expects(self::once())->method('indexEvent');
        static::getContainer()->set(EventIndexService::class, $eventIndex);

        self::assertFalse($event->isOnline());

        $client->loginUser($admin);
        $client->request('POST', '/admin/evenement/'.$event->getId().'/en-ligne');

        self::assertResponseRedirects('/admin/evenements');

        $em->refresh($event);
        self::assertTrue($event->isOnline());
    }

    public function testToggleEventOffline(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $event = $this->createEvent($em, $orga);
        $event->setIsOnline(true);
        $em->flush();

        $eventIndex = $this->createMock(EventIndexService::class);
        $eventIndex->expects(self::once())->method('indexEvent');
        static::getContainer()->set(EventIndexService::class, $eventIndex);

        $client->loginUser($admin);
        $client->request('POST', '/admin/evenement/'.$event->getId().'/en-ligne');

        self::assertResponseRedirects('/admin/evenements');

        $em->refresh($event);
        self::assertFalse($event->isOnline());
    }

    public function testDeleteEvent(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $admin = $this->createUser(['ROLE_ROOT']);
        $orga = $this->createOrganizer($em);
        $event = $this->createEvent($em, $orga);
        $eventId = $event->getId();

        $eventIndex = $this->createMock(EventIndexService::class);
        $eventIndex->expects(self::once())->method('removeEvent');
        static::getContainer()->set(EventIndexService::class, $eventIndex);

        $client->loginUser($admin);
        $client->request('POST', '/admin/evenement/'.$eventId.'/supprimer');

        self::assertResponseRedirects('/admin/evenements');

        $deleted = $em->getRepository(Event::class)->find($eventId);
        self::assertNull($deleted);
    }

    public function testToggleEventOnlineDeniedForNonRoot(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $user = $this->createUser();
        $orga = $this->createOrganizer($em);
        $event = $this->createEvent($em, $orga);

        $client->loginUser($user);
        $client->request('POST', '/admin/evenement/'.$event->getId().'/en-ligne');

        self::assertResponseStatusCodeSame(403);
    }

    public function testDeleteEventDeniedForNonRoot(): void
    {
        $client = static::createClient();
        $em = static::getContainer()->get(EntityManagerInterface::class);
        $user = $this->createUser();
        $orga = $this->createOrganizer($em);
        $event = $this->createEvent($em, $orga);

        $client->loginUser($user);
        $client->request('POST', '/admin/evenement/'.$event->getId().'/supprimer');

        self::assertResponseStatusCodeSame(403);
    }
}
