<?php

namespace App\Tests\Controller;

use App\Controller\OrderPaymentController;
use App\Entity\Advert;
use App\Entity\Customer;
use App\Entity\OrderNumber;
use App\Entity\Revendeur;
use App\Entity\User;
use App\Service\MailerService;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\RouterInterface;
use Twig\Environment;

class OrderPaymentControllerTest extends TestCase
{
    // ---------------------------------------------------------------
    // Helpers
    // ---------------------------------------------------------------

    private function createAdvert(?Customer $customer = null, string $state = Advert::STATE_SEND): Advert
    {
        $orderNumber = new OrderNumber('04/2026-TEST01');
        $advert = new Advert($orderNumber, 'secret');
        $advert->setState($state);
        if (null !== $customer) {
            $advert->setCustomer($customer);
        }

        return $advert;
    }

    private function createCustomerWithEmail(string $email = 'client@test.com'): Customer
    {
        $user = new User();
        $user->setEmail($email);
        $user->setFirstName('Jean');
        $user->setLastName('Test');
        $user->setPassword('h');
        $customer = new Customer($user);
        $customer->setEmail($email);

        return $customer;
    }

    private function createCustomerWithoutEmail(): Customer
    {
        $user = new User();
        $user->setEmail('user@test.com');
        $user->setFirstName('Jean');
        $user->setLastName('Test');
        $user->setPassword('h');

        return new Customer($user);
    }

    /**
     * Builds a QueryBuilder stub that returns $advert from getOneOrNullResult().
     */
    private function createEmWithAdvert(?Advert $advert): EntityManagerInterface
    {
        $stubEm = $this->createStub(EntityManagerInterface::class);

        $query = $this->getMockBuilder(Query::class)
            ->setConstructorArgs([$stubEm])
            ->onlyMethods(['getOneOrNullResult', '_doExecute', 'getSQL'])
            ->getMock();
        $query->method('getOneOrNullResult')->willReturn($advert);

        $qb = $this->createStub(QueryBuilder::class);
        $qb->method('select')->willReturnSelf();
        $qb->method('from')->willReturnSelf();
        $qb->method('join')->willReturnSelf();
        $qb->method('where')->willReturnSelf();
        $qb->method('andWhere')->willReturnSelf();
        $qb->method('setParameter')->willReturnSelf();
        $qb->method('orderBy')->willReturnSelf();
        $qb->method('setMaxResults')->willReturnSelf();
        $qb->method('getQuery')->willReturn($query);

        $em = $this->createStub(EntityManagerInterface::class);
        $em->method('createQueryBuilder')->willReturn($qb);
        $em->method('persist');
        $em->method('flush');

        return $em;
    }

    /**
     * Builds a QueryBuilder stub + optional Revendeur repo stub for findRevendeur().
     */
    private function createEmWithAdvertAndRevendeur(?Advert $advert, ?Revendeur $revendeur = null): EntityManagerInterface
    {
        $stubEm = $this->createStub(EntityManagerInterface::class);

        $query = $this->getMockBuilder(Query::class)
            ->setConstructorArgs([$stubEm])
            ->onlyMethods(['getOneOrNullResult', '_doExecute', 'getSQL'])
            ->getMock();
        $query->method('getOneOrNullResult')->willReturn($advert);

        $qb = $this->createStub(QueryBuilder::class);
        $qb->method('select')->willReturnSelf();
        $qb->method('from')->willReturnSelf();
        $qb->method('join')->willReturnSelf();
        $qb->method('where')->willReturnSelf();
        $qb->method('andWhere')->willReturnSelf();
        $qb->method('setParameter')->willReturnSelf();
        $qb->method('orderBy')->willReturnSelf();
        $qb->method('setMaxResults')->willReturnSelf();
        $qb->method('getQuery')->willReturn($query);

        $revendeurRepo = $this->createStub(EntityRepository::class);
        $revendeurRepo->method('findOneBy')->willReturn($revendeur);

        $em = $this->createStub(EntityManagerInterface::class);
        $em->method('createQueryBuilder')->willReturn($qb);
        $em->method('getRepository')->willReturn($revendeurRepo);
        $em->method('persist');
        $em->method('flush');

        return $em;
    }

    private function createContainer(?Session $session = null): ContainerInterface
    {
        $session ??= new Session(new MockArraySessionStorage());
        $stack = $this->createStub(RequestStack::class);
        $stack->method('getSession')->willReturn($session);

        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $router = $this->createStub(RouterInterface::class);
        $router->method('generate')->willReturn('/some/path');

        $container = $this->createStub(ContainerInterface::class);
        $container->method('has')->willReturnMap([
            ['twig', true],
            ['router', true],
            ['request_stack', true],
            ['serializer', false],
        ]);
        $container->method('get')->willReturnMap([
            ['twig', $twig],
            ['router', $router],
            ['request_stack', $stack],
        ]);

        return $container;
    }

    private function buildController(
        EntityManagerInterface $em,
        ?MailerService $mailer = null,
        ?Environment $twig = null,
        ?Session $session = null,
    ): OrderPaymentController {
        $mailer ??= $this->createStub(MailerService::class);
        $twig ??= $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $controller = new OrderPaymentController($em, $mailer, $twig);
        $controller->setContainer($this->createContainer($session));

        return $controller;
    }

    // ---------------------------------------------------------------
    // findAdvert – not found throws 404
    // ---------------------------------------------------------------

    public function testFindAdvertNotFoundThrows404(): void
    {
        $em = $this->createEmWithAdvert(null);
        $controller = $this->buildController($em);

        $this->expectException(NotFoundHttpException::class);
        $controller->index('INVALID', new Request());
    }

    // ---------------------------------------------------------------
    // index – not verified → redirect to verify
    // ---------------------------------------------------------------

    public function testIndexNotVerifiedRedirectsToVerify(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail());
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        // Do not set order_verified_* key → session returns false
        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->index('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // index – verified → render payment page
    // ---------------------------------------------------------------

    public function testIndexVerifiedRendersPaymentPage(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail());
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $session->set('order_verified_'.$advert->getId(), true);

        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->index('04/2026-TEST01', $request);

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // verify – already verified → redirect
    // ---------------------------------------------------------------

    public function testVerifyAlreadyVerifiedRedirects(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail());
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $session->set('order_verified_'.$advert->getId(), true);

        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // verify – no customer → auto-verify and redirect
    // ---------------------------------------------------------------

    public function testVerifyNoCustomerAutoVerifiesAndRedirects(): void
    {
        $advert = $this->createAdvert(null); // no customer
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
        // Session flag should be set
        $this->assertTrue($session->get('order_verified_'.$advert->getId(), false));
    }

    // ---------------------------------------------------------------
    // verify – customer without email → auto-verify and redirect
    // ---------------------------------------------------------------

    public function testVerifyCustomerWithoutEmailAutoVerifiesAndRedirects(): void
    {
        $customer = $this->createCustomerWithoutEmail(); // email is null
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
        $this->assertTrue($session->get('order_verified_'.$advert->getId(), false));
    }

    // ---------------------------------------------------------------
    // verify – GET with customer+email → sends code, renders verify
    // ---------------------------------------------------------------

    public function testVerifyGetRendersVerifyFormAndSendsCode(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects($this->once())->method('sendEmail');

        $twig = $this->createMock(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $session = new Session(new MockArraySessionStorage());
        $controller = $this->buildController($em, $mailer, $twig, $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        $this->assertSame(200, $response->getStatusCode());
        // Code should have been stored in session
        $this->assertNotNull($session->get('order_code_'.$advert->getId()));
    }

    // ---------------------------------------------------------------
    // verify – GET with existing valid code → does NOT resend
    // ---------------------------------------------------------------

    public function testVerifyGetDoesNotResendWhenCodeStillValid(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects($this->never())->method('sendEmail');

        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $session = new Session(new MockArraySessionStorage());
        // Pre-seed a valid code with future expiry
        $session->set('order_code_'.$advert->getId(), '123456');
        $session->set('order_code_expires_'.$advert->getId(), time() + 900);

        $controller = $this->buildController($em, $mailer, $twig, $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // verify POST – expired code → error message
    // ---------------------------------------------------------------

    public function testVerifyPostExpiredCodeReturnsError(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        // Code expired (expiresAt in the past)
        $session->set('order_code_'.$advert->getId(), '123456');
        $session->set('order_code_expires_'.$advert->getId(), time() - 1);

        $mailer = $this->createMock(MailerService::class);
        // After expired code, sendVerifyCodeIfNeeded sends a new code
        $mailer->expects($this->once())->method('sendEmail');

        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $controller = $this->buildController($em, $mailer, $twig, $session);

        $request = new Request([], ['code' => '123456']);
        $request->setMethod('POST');
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        // Should render verify page (not redirect) with error
        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // verify POST – correct code → sets session + redirect
    // ---------------------------------------------------------------

    public function testVerifyPostCorrectCodeRedirects(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $session->set('order_code_'.$advert->getId(), '654321');
        $session->set('order_code_expires_'.$advert->getId(), time() + 900);

        $controller = $this->buildController($em, session: $session);

        $request = new Request([], ['code' => '654321']);
        $request->setMethod('POST');
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
        $this->assertTrue($session->get('order_verified_'.$advert->getId(), false));
    }

    // ---------------------------------------------------------------
    // verify POST – wrong code → error
    // ---------------------------------------------------------------

    public function testVerifyPostWrongCodeRendersError(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $session->set('order_code_'.$advert->getId(), '000000');
        $session->set('order_code_expires_'.$advert->getId(), time() + 900);

        $mailer = $this->createStub(MailerService::class);
        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $controller = $this->buildController($em, $mailer, $twig, $session);

        $request = new Request([], ['code' => '999999']);
        $request->setMethod('POST');
        $request->setSession($session);

        $response = $controller->verify('04/2026-TEST01', $request);

        // Should render verify page (not redirect) with wrong-code error
        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // verifyResend – no customer (skips email)
    // ---------------------------------------------------------------

    public function testVerifyResendNoCustomerSkipsEmail(): void
    {
        $advert = $this->createAdvert(null);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects($this->never())->method('sendEmail');

        $session = new Session(new MockArraySessionStorage());
        $controller = $this->buildController($em, $mailer, session: $session);

        $request = new Request();
        $request->setMethod('POST');
        $request->setSession($session);

        $response = $controller->verifyResend('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // verifyResend – customer with email → sends code + redirects
    // ---------------------------------------------------------------

    public function testVerifyResendWithEmailSendsCodeAndRedirects(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects($this->once())->method('sendEmail');

        $twig = $this->createMock(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $session = new Session(new MockArraySessionStorage());
        $controller = $this->buildController($em, $mailer, $twig, $session);

        $request = new Request();
        $request->setMethod('POST');
        $request->setSession($session);

        $response = $controller->verifyResend('04/2026-TEST01', $request);

        $this->assertSame(302, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // chooseVirement – delegates to handleOfflinePayment
    // ---------------------------------------------------------------

    public function testChooseVirementDelegatesToHandleOfflinePayment(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        // 2 emails: one to customer, one to admin
        $mailer->expects($this->exactly(2))->method('sendEmail');

        $twig = $this->createMock(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $controller = $this->buildController($em, $mailer, $twig);

        $response = $controller->chooseVirement('04/2026-TEST01');

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // chooseCheque – delegates to handleOfflinePayment
    // ---------------------------------------------------------------

    public function testChooseCheque(): void
    {
        $customer = $this->createCustomerWithEmail();
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        $mailer->expects($this->exactly(2))->method('sendEmail');

        $twig = $this->createMock(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $controller = $this->buildController($em, $mailer, $twig);

        $response = $controller->chooseCheque('04/2026-TEST01');

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // handleOfflinePayment – customer without email (only admin mail)
    // ---------------------------------------------------------------

    public function testHandleOfflinePaymentNoCustomerEmail(): void
    {
        $customer = $this->createCustomerWithoutEmail(); // no email
        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvert($advert);

        $mailer = $this->createMock(MailerService::class);
        // Only admin notification (customer has no email)
        $mailer->expects($this->once())->method('sendEmail');

        $twig = $this->createMock(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $controller = $this->buildController($em, $mailer, $twig);

        $response = $controller->chooseVirement('04/2026-TEST01');

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // createStripeIntent – empty stripeSk returns 500
    // ---------------------------------------------------------------

    public function testCreateStripeIntentEmptySkReturns500(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail());
        $em = $this->createEmWithAdvert($advert);
        $controller = $this->buildController($em);

        $request = new Request();
        // stripeSk = '' by default → guard triggers
        $response = $controller->createStripeIntent('04/2026-TEST01', $request, '');

        $this->assertSame(500, $response->getStatusCode());
        $data = json_decode($response->getContent(), true);
        $this->assertArrayHasKey('error', $data);
    }

    // ---------------------------------------------------------------
    // createStripeIntent – amount <= 0 returns 400
    // ---------------------------------------------------------------

    public function testCreateStripeIntentZeroAmountReturns400(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail());
        // totalTtc = '0.00' by default → amount = 0
        $em = $this->createEmWithAdvert($advert);
        $controller = $this->buildController($em);

        $request = new Request();
        $response = $controller->createStripeIntent('04/2026-TEST01', $request, 'sk_test_fake');

        $this->assertSame(400, $response->getStatusCode());
        $data = json_decode($response->getContent(), true);
        $this->assertArrayHasKey('error', $data);
    }

    // ---------------------------------------------------------------
    // stripeSuccess – advert already accepted → render confirmed
    // ---------------------------------------------------------------

    public function testStripeSuccessAlreadyAcceptedRendersConfirmed(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail(), Advert::STATE_ACCEPTED);
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $session->set('order_verified_'.$advert->getId(), true);

        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        $response = $controller->stripeSuccess('04/2026-TEST01', $request, 'sk_test_fake');

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // stripeSuccess – no piId + empty sk → render processing loader
    // ---------------------------------------------------------------

    public function testStripeSuccessNoPiIdRendersLoader(): void
    {
        $advert = $this->createAdvert($this->createCustomerWithEmail(), Advert::STATE_SEND);
        // stripePaymentId is null by default
        $em = $this->createEmWithAdvert($advert);

        $session = new Session(new MockArraySessionStorage());
        $controller = $this->buildController($em, session: $session);

        $request = new Request();
        $request->setSession($session);

        // No pi_id and empty sk → skip Stripe block, fall through to loader
        $response = $controller->stripeSuccess('04/2026-TEST01', $request, '');

        $this->assertSame(200, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // stripeCheck – returns JSON status
    // ---------------------------------------------------------------

    public function testStripeCheckReturnsJsonStatus(): void
    {
        $advert = $this->createAdvert(null, Advert::STATE_SEND);
        $em = $this->createEmWithAdvert($advert);
        $controller = $this->buildController($em);

        $response = $controller->stripeCheck('04/2026-TEST01');

        $this->assertSame(200, $response->getStatusCode());
        $data = json_decode($response->getContent(), true);
        $this->assertArrayHasKey('status', $data);
        $this->assertArrayHasKey('accepted', $data);
        $this->assertSame(Advert::STATE_SEND, $data['status']);
        $this->assertFalse($data['accepted']);
    }

    public function testStripeCheckAcceptedState(): void
    {
        $advert = $this->createAdvert(null, Advert::STATE_ACCEPTED);
        $em = $this->createEmWithAdvert($advert);
        $controller = $this->buildController($em);

        $response = $controller->stripeCheck('04/2026-TEST01');

        $data = json_decode($response->getContent(), true);
        $this->assertTrue($data['accepted']);
    }

    // ---------------------------------------------------------------
    // findRevendeur – null customer → returns null (guard via createStripeIntent)
    // ---------------------------------------------------------------

    public function testFindRevendeurNullCustomerReturnsNullGuard(): void
    {
        // We test findRevendeur indirectly via createStripeIntent guard path (amount=0)
        $advert = $this->createAdvert(null); // no customer
        $em = $this->createEmWithAdvert($advert);
        $controller = $this->buildController($em);

        // amount = 0 (totalTtc = 0.00) → guard fires before findRevendeur
        $request = new Request();
        $response = $controller->createStripeIntent('04/2026-TEST01', $request, 'sk_test_fake');

        $this->assertSame(400, $response->getStatusCode());
    }

    // ---------------------------------------------------------------
    // findRevendeur – customer with no revendeurCode → returns null
    // We test this by exercising the private method via Reflection
    // ---------------------------------------------------------------

    public function testFindRevendeurNoCodeReturnsNull(): void
    {
        $customer = $this->createCustomerWithEmail();
        // revendeurCode is null by default

        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvertAndRevendeur($advert, null);
        $controller = $this->buildController($em);

        $method = new \ReflectionMethod(OrderPaymentController::class, 'findRevendeur');
        $method->setAccessible(true);

        $result = $method->invoke($controller, $customer);

        $this->assertNull($result);
    }

    // ---------------------------------------------------------------
    // findRevendeur – revendeur not found in DB → returns null
    // ---------------------------------------------------------------

    public function testFindRevendeurNotFoundInDbReturnsNull(): void
    {
        $customer = $this->createCustomerWithEmail();
        $customer->setRevendeurCode('REV001');

        $advert = $this->createAdvert($customer);
        // Repo returns null for findOneBy
        $em = $this->createEmWithAdvertAndRevendeur($advert, null);
        $controller = $this->buildController($em);

        $method = new \ReflectionMethod(OrderPaymentController::class, 'findRevendeur');
        $method->setAccessible(true);

        $result = $method->invoke($controller, $customer);

        $this->assertNull($result);
    }

    // ---------------------------------------------------------------
    // findRevendeur – revendeur found but isUseStripe=false → returns null
    // ---------------------------------------------------------------

    public function testFindRevendeurNotUsingStripeReturnsNull(): void
    {
        $customer = $this->createCustomerWithEmail();
        $customer->setRevendeurCode('REV002');

        $revendeurUser = new User();
        $revendeurUser->setEmail('rev@test.com');
        $revendeurUser->setPassword('h');
        $revendeur = new Revendeur($revendeurUser, 'REV002');
        // isUseStripe defaults to false

        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvertAndRevendeur($advert, $revendeur);
        $controller = $this->buildController($em);

        $method = new \ReflectionMethod(OrderPaymentController::class, 'findRevendeur');
        $method->setAccessible(true);

        $result = $method->invoke($controller, $customer);

        $this->assertNull($result);
    }

    // ---------------------------------------------------------------
    // findRevendeur – revendeur isUseStripe=true but no stripeConnectId → null
    // ---------------------------------------------------------------

    public function testFindRevendeurNoStripeConnectIdReturnsNull(): void
    {
        $customer = $this->createCustomerWithEmail();
        $customer->setRevendeurCode('REV003');

        $revendeurUser = new User();
        $revendeurUser->setEmail('rev3@test.com');
        $revendeurUser->setPassword('h');
        $revendeur = new Revendeur($revendeurUser, 'REV003');
        $revendeur->setIsUseStripe(true);
        // stripeConnectId is null by default

        $advert = $this->createAdvert($customer);
        $em = $this->createEmWithAdvertAndRevendeur($advert, $revendeur);
        $controller = $this->buildController($em);

        $method = new \ReflectionMethod(OrderPaymentController::class, 'findRevendeur');
        $method->setAccessible(true);

        $result = $method->invoke($controller, $customer);

        $this->assertNull($result);
    }

    // ---------------------------------------------------------------
    // findAdvert – not found → throws NotFoundHttpException
    // ---------------------------------------------------------------

    public function testFindAdvertThrows404WhenNotFound(): void
    {
        $em = $this->createEmWithAdvert(null);
        $controller = $this->buildController($em);

        $method = new \ReflectionMethod(OrderPaymentController::class, 'findAdvert');
        $method->setAccessible(true);

        $this->expectException(NotFoundHttpException::class);
        $method->invoke($controller, 'NONEXISTENT');
    }
}
