<?php

namespace App\Tests\Controller;

use App\Controller\AttestationController;
use App\Controller\EspaceClientController;
use App\Controller\EspacePrestataireController;
use App\Controller\WebhookDocuSealController;
use App\Entity\Attestation;
use App\Repository\AttestationRepository;
use App\Repository\DevisRepository;
use App\Service\DocuSealService;
use App\Service\MailerService;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;

class EspacesControllersTest extends TestCase
{
    private function createContainer(array $services = []): ContainerInterface
    {
        $container = $this->createStub(ContainerInterface::class);
        $container->method('has')->willReturnCallback(fn($id) => isset($services[$id]) || $id === 'twig' || $id === 'router' || $id === 'parameter_bag');
        $container->method('get')->willReturnCallback(fn($id) => $services[$id] ?? null);
        return $container;
    }

    // --- EspaceClientController ---

    public function testEspaceClientIndex(): void
    {
        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');
        $container = $this->createContainer(['twig' => $twig]);

        $controller = new EspaceClientController();
        $controller->setContainer($container);

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

    // --- EspacePrestataireController ---

    public function testEspacePrestataireIndex(): void
    {
        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');
        $container = $this->createContainer(['twig' => $twig]);

        $controller = new EspacePrestataireController();
        $controller->setContainer($container);

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

    // --- AttestationController ---

    public function testAttestationVerifyNotFound(): void
    {
        $repo = $this->createStub(AttestationRepository::class);
        $repo->method('findOneBy')->willReturn(null);

        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html>not found</html>');
        $container = $this->createContainer(['twig' => $twig]);

        $controller = new AttestationController();
        $controller->setContainer($container);

        $response = $controller->verify('REF-123', $repo, 'secret');
        $this->assertSame('<html>not found</html>', $response->getContent());
    }

    // --- WebhookDocuSealController ---

    public function testWebhookDocuSealInvalidSecret(): void
    {
        $request = new Request();
        $request->setMethod('POST');
        $request->headers->set('X-DocuSeal-Secret', 'wrong');

        $repo = $this->createStub(AttestationRepository::class);
        $mailer = $this->createStub(MailerService::class);
        $em = $this->createStub(EntityManagerInterface::class);
        $twig = $this->createStub(Environment::class);

        $devisRepo = $this->createStub(DevisRepository::class);
        $docuSealService = $this->createStub(DocuSealService::class);

        $controller = new WebhookDocuSealController();
        $response = $controller($request, $repo, $devisRepo, $docuSealService, $mailer, $em, $twig, 'X-DocuSeal-Secret', 'secret', '/tmp');

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

    public function testWebhookDocuSealSuccessIgnoredEvent(): void
    {
        $payload = json_encode([
            'event_type' => 'other',
            'data' => [
                'id' => 123,
                'metadata' => ['doc_type' => 'other']
            ]
        ]);
        $request = new Request([], [], [], [], [], [], $payload);
        $request->setMethod('POST');
        $request->headers->set('X-Secret', 'secret');

        $repo = $this->createStub(AttestationRepository::class);
        $repo->method('findOneBy')->willReturn(null);
        $mailer = $this->createStub(MailerService::class);
        $em = $this->createStub(EntityManagerInterface::class);
        $twig = $this->createStub(Environment::class);

        $devisRepo = $this->createStub(DevisRepository::class);
        $docuSealService = $this->createStub(DocuSealService::class);

        $controller = new WebhookDocuSealController();
        $response = $controller($request, $repo, $devisRepo, $docuSealService, $mailer, $em, $twig, 'X-Secret', 'secret', '/tmp');

        $this->assertSame(200, $response->getStatusCode());
        $this->assertStringContainsString('ignored', $response->getContent());
    }
}
