<?php

namespace App\Tests\Service;

use App\Entity\BilletBuyer;
use App\Entity\Event;
use App\Entity\User;
use App\Service\InvoiceService;
use PHPUnit\Framework\TestCase;
use Twig\Environment;

class InvoiceServiceTest extends TestCase
{
    private function createMockOrder(): BilletBuyer
    {
        $user = $this->createMock(User::class);
        $user->method('getLogoName')->willReturn(null);

        $event = $this->createMock(Event::class);
        $event->method('getAccount')->willReturn($user);

        $order = $this->createMock(BilletBuyer::class);
        $order->method('getEvent')->willReturn($event);
        $order->method('getOrderNumber')->willReturn('2026-03-15-1');

        return $order;
    }

    public function testGeneratePdfReturnsPdfContent(): void
    {
        $twig = $this->createMock(Environment::class);
        $twig->method('render')->with('pdf/invoice.html.twig', $this->anything())
            ->willReturn('<html><body><h1>Facture</h1></body></html>');

        $service = new InvoiceService($twig, '/tmp/test-project');

        $order = $this->createMockOrder();
        $pdf = $service->generatePdf($order);

        self::assertNotEmpty($pdf);
        self::assertStringStartsWith('%PDF', $pdf);
    }

    public function testGeneratePdfPassesCorrectData(): void
    {
        $twig = $this->createMock(Environment::class);
        $order = $this->createMockOrder();

        $twig->expects($this->once())->method('render')->with(
            'pdf/invoice.html.twig',
            $this->callback(function (array $params) use ($order) {
                return $params['order'] === $order
                    && $params['organizer'] === $order->getEvent()->getAccount()
                    && '' === $params['logoBase64'];
            })
        )->willReturn('<html><body>test</body></html>');

        $service = new InvoiceService($twig, '/tmp/nonexistent-project');
        $service->generatePdf($order);
    }

    public function testGenerateToFileCreatesFile(): void
    {
        $twig = $this->createMock(Environment::class);
        $twig->method('render')->willReturn('<html><body>invoice</body></html>');

        $tmpDir = sys_get_temp_dir().'/invoice-test-'.uniqid();
        mkdir($tmpDir);

        $service = new InvoiceService($twig, $tmpDir);
        $order = $this->createMockOrder();

        $path = $service->generateToFile($order);

        self::assertFileExists($path);
        self::assertStringStartsWith('%PDF', (string) file_get_contents($path));
        self::assertStringContainsString('facture_2026-03-15-1.pdf', $path);

        // Cleanup
        unlink($path);
        rmdir($tmpDir.'/var/invoices');
        rmdir($tmpDir.'/var');
        rmdir($tmpDir);
    }

    public function testGeneratePdfWithLogo(): void
    {
        $twig = $this->createMock(Environment::class);

        $tmpDir = sys_get_temp_dir().'/invoice-logo-test-'.uniqid();
        mkdir($tmpDir);
        mkdir($tmpDir.'/public', 0o755, true);
        file_put_contents($tmpDir.'/public/logo.png', 'fake-png-data');

        $twig->expects($this->once())->method('render')->with(
            'pdf/invoice.html.twig',
            $this->callback(fn (array $params) => '' !== $params['logoBase64'] && str_starts_with($params['logoBase64'], 'data:'))
        )->willReturn('<html><body>test</body></html>');

        $service = new InvoiceService($twig, $tmpDir);
        $order = $this->createMockOrder();
        $service->generatePdf($order);

        // Cleanup
        unlink($tmpDir.'/public/logo.png');
        rmdir($tmpDir.'/public');
        rmdir($tmpDir);
    }
}
