<?php

namespace App\Tests\Service;

use App\Entity\Advert;
use App\Entity\Devis;
use App\Entity\OrderNumber;
use App\Service\AdvertService;
use App\Service\OrderNumberService;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;

class AdvertServiceTest extends TestCase
{
    private const HMAC_SECRET = 'test-hmac-secret';

    public function testCreateWithoutDevis(): void
    {
        $orderNumber = new OrderNumber('04/2026-00001');
        $orderNumber->markAsUsed();

        $orderService = $this->createStub(OrderNumberService::class);
        $orderService->method('generateAndUse')->willReturn($orderNumber);

        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET);
        $advert = $service->create();

        $this->assertInstanceOf(Advert::class, $advert);
        $this->assertSame($orderNumber, $advert->getOrderNumber());
        $this->assertNull($advert->getDevis());
    }

    public function testCreateWithDevis(): void
    {
        $orderNumber = new OrderNumber('04/2026-00002');

        $devis = $this->createStub(Devis::class);
        $devis->method('getOrderNumber')->willReturn($orderNumber);

        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET);
        $advert = $service->create($devis);

        $this->assertInstanceOf(Advert::class, $advert);
        $this->assertSame($orderNumber, $advert->getOrderNumber());
    }

    public function testCreateFromDevis(): void
    {
        $orderNumber = new OrderNumber('04/2026-00003');

        $devis = $this->createStub(Devis::class);
        $devis->method('getOrderNumber')->willReturn($orderNumber);

        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET);
        $advert = $service->createFromDevis($devis);

        $this->assertInstanceOf(Advert::class, $advert);
        $this->assertSame($orderNumber, $advert->getOrderNumber());
    }

    // --- isTvaEnabled ---

    public function testIsTvaEnabledReturnsTrueForTrueString(): void
    {
        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET, 'true');
        $this->assertTrue($service->isTvaEnabled());
    }

    public function testIsTvaEnabledReturnsTrueForOne(): void
    {
        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET, '1');
        $this->assertTrue($service->isTvaEnabled());
    }

    public function testIsTvaEnabledReturnsFalseForFalseString(): void
    {
        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET, 'false');
        $this->assertFalse($service->isTvaEnabled());
    }

    // --- getTvaRate ---

    public function testGetTvaRateReturnsFloat(): void
    {
        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET, 'false', '0.20');
        $this->assertSame(0.20, $service->getTvaRate());
    }

    // --- computeTotals ---

    public function testComputeTotalsTvaDisabled(): void
    {
        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET, 'false', '0.20');
        $result = $service->computeTotals('100.00');

        $this->assertSame('100.00', $result['totalHt']);
        $this->assertSame('0.00', $result['totalTva']);
        $this->assertSame('100.00', $result['totalTtc']);
    }

    public function testComputeTotalsTvaEnabled(): void
    {
        $orderService = $this->createStub(OrderNumberService::class);
        $em = $this->createStub(EntityManagerInterface::class);

        $service = new AdvertService($orderService, $em, self::HMAC_SECRET, 'true', '0.20');
        $result = $service->computeTotals('100.00');

        $this->assertSame('100.00', $result['totalHt']);
        $this->assertSame('20.00', $result['totalTva']);
        $this->assertSame('120.00', $result['totalTtc']);
    }
}
