<?php

namespace App\Tests\Entity;

use App\Entity\Advert;
use App\Entity\Devis;
use App\Entity\OrderNumber;
use PHPUnit\Framework\TestCase;

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

    public function testConstructor(): void
    {
        $order = new OrderNumber('04/2026-00001');
        $advert = new Advert($order, self::HMAC_SECRET);

        $this->assertNull($advert->getId());
        $this->assertSame($order, $advert->getOrderNumber());
        $this->assertNull($advert->getDevis());
        $this->assertNotEmpty($advert->getHmac());
        $this->assertInstanceOf(\DateTimeImmutable::class, $advert->getCreatedAt());
        $this->assertCount(0, $advert->getFactures());
    }

    public function testSetDevis(): void
    {
        $order = new OrderNumber('04/2026-00002');
        $advert = new Advert($order, self::HMAC_SECRET);

        $devis = $this->createStub(Devis::class);
        $advert->setDevis($devis);
        $this->assertSame($devis, $advert->getDevis());

        $advert->setDevis(null);
        $this->assertNull($advert->getDevis());
    }

    public function testVerifyHmacValid(): void
    {
        $order = new OrderNumber('04/2026-00003');
        $advert = new Advert($order, self::HMAC_SECRET);

        $this->assertTrue($advert->verifyHmac(self::HMAC_SECRET));
    }

    public function testVerifyHmacInvalid(): void
    {
        $order = new OrderNumber('04/2026-00004');
        $advert = new Advert($order, self::HMAC_SECRET);

        $this->assertFalse($advert->verifyHmac('wrong-secret'));
    }

    public function testStateConstants(): void
    {
        $this->assertSame('created', Advert::STATE_CREATED);
        $this->assertSame('send', Advert::STATE_SEND);
        $this->assertSame('accepted', Advert::STATE_ACCEPTED);
        $this->assertSame('refused', Advert::STATE_REFUSED);
        $this->assertSame('cancel', Advert::STATE_CANCEL);
    }

    public function testStateGetterSetter(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00010'), self::HMAC_SECRET);

        $this->assertSame(Advert::STATE_CREATED, $advert->getState());

        $advert->setState(Advert::STATE_SEND);
        $this->assertSame(Advert::STATE_SEND, $advert->getState());

        $advert->setState(Advert::STATE_ACCEPTED);
        $this->assertSame(Advert::STATE_ACCEPTED, $advert->getState());

        $advert->setState(Advert::STATE_REFUSED);
        $this->assertSame(Advert::STATE_REFUSED, $advert->getState());

        $advert->setState(Advert::STATE_CANCEL);
        $this->assertSame(Advert::STATE_CANCEL, $advert->getState());
    }

    public function testSetCustomer(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00011'), self::HMAC_SECRET);

        $this->assertNull($advert->getCustomer());

        $customer = $this->createStub(\App\Entity\Customer::class);
        $advert->setCustomer($customer);
        $this->assertSame($customer, $advert->getCustomer());

        $advert->setCustomer(null);
        $this->assertNull($advert->getCustomer());
    }

    public function testRaisonMessage(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00012'), self::HMAC_SECRET);

        $this->assertNull($advert->getRaisonMessage());

        $advert->setRaisonMessage('Motif de refus');
        $this->assertSame('Motif de refus', $advert->getRaisonMessage());

        $advert->setRaisonMessage(null);
        $this->assertNull($advert->getRaisonMessage());
    }

    public function testTotals(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00013'), self::HMAC_SECRET);

        $this->assertSame('0.00', $advert->getTotalHt());
        $this->assertSame('0.00', $advert->getTotalTva());
        $this->assertSame('0.00', $advert->getTotalTtc());

        $advert->setTotalHt('500.00');
        $advert->setTotalTva('100.00');
        $advert->setTotalTtc('600.00');

        $this->assertSame('500.00', $advert->getTotalHt());
        $this->assertSame('100.00', $advert->getTotalTva());
        $this->assertSame('600.00', $advert->getTotalTtc());
    }

    public function testSubmissionId(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00014'), self::HMAC_SECRET);

        $this->assertNull($advert->getSubmissionId());

        $advert->setSubmissionId('sub_abc123');
        $this->assertSame('sub_abc123', $advert->getSubmissionId());

        $advert->setSubmissionId(null);
        $this->assertNull($advert->getSubmissionId());
    }

    public function testStripePaymentId(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00015'), self::HMAC_SECRET);

        $this->assertNull($advert->getStripePaymentId());

        $advert->setStripePaymentId('pi_xxx123');
        $this->assertSame('pi_xxx123', $advert->getStripePaymentId());

        $advert->setStripePaymentId(null);
        $this->assertNull($advert->getStripePaymentId());
    }

    public function testAdvertFile(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00016'), self::HMAC_SECRET);

        $this->assertNull($advert->getAdvertFile());

        $advert->setAdvertFile('advert-001.pdf');
        $this->assertSame('advert-001.pdf', $advert->getAdvertFile());

        $advert->setAdvertFile(null);
        $this->assertNull($advert->getAdvertFile());
    }

    public function testAdvertFileUploadSetsUpdatedAt(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00017'), self::HMAC_SECRET);

        $this->assertNull($advert->getAdvertFileUpload());
        $this->assertNull($advert->getUpdatedAt());

        $tmpFile = tempnam(sys_get_temp_dir(), 'advert_');
        file_put_contents($tmpFile, 'pdf');
        $file = new \Symfony\Component\HttpFoundation\File\File($tmpFile);

        $advert->setAdvertFileUpload($file);
        $this->assertSame($file, $advert->getAdvertFileUpload());
        $this->assertInstanceOf(\DateTimeImmutable::class, $advert->getUpdatedAt());

        $advert->setAdvertFileUpload(null);
        $this->assertNull($advert->getAdvertFileUpload());

        @unlink($tmpFile);
    }

    public function testSetUpdatedAt(): void
    {
        $advert = new Advert(new OrderNumber('04/2026-00018'), self::HMAC_SECRET);

        $this->assertNull($advert->getUpdatedAt());

        $now = new \DateTimeImmutable();
        $result = $advert->setUpdatedAt($now);

        $this->assertSame($now, $advert->getUpdatedAt());
        $this->assertSame($advert, $result);

        $advert->setUpdatedAt(null);
        $this->assertNull($advert->getUpdatedAt());
    }

    public function testLinesCollection(): void
    {
        $order = new OrderNumber('04/2026-00019');
        $advert = new Advert($order, self::HMAC_SECRET);

        $this->assertCount(0, $advert->getLines());

        $line = new \App\Entity\AdvertLine($advert, 'Prestation', '100.00', 1);
        $result = $advert->addLine($line);

        $this->assertSame($advert, $result);
        $this->assertCount(1, $advert->getLines());
        $this->assertTrue($advert->getLines()->contains($line));

        // Adding same line again should not duplicate
        $advert->addLine($line);
        $this->assertCount(1, $advert->getLines());

        $advert->removeLine($line);
        $this->assertCount(0, $advert->getLines());
    }

    public function testPaymentsCollection(): void
    {
        $order = new OrderNumber('04/2026-00020');
        $advert = new Advert($order, self::HMAC_SECRET);

        $this->assertCount(0, $advert->getPayments());
    }
}
