<?php

namespace App\Tests\Entity;

use App\Entity\FacturePrestataire;
use App\Entity\Prestataire;
use PHPUnit\Framework\TestCase;

class PrestataireTest extends TestCase
{
    public function testConstructor(): void
    {
        $p = new Prestataire('Dupont SARL');

        $this->assertNull($p->getId());
        $this->assertSame('Dupont SARL', $p->getRaisonSociale());
        $this->assertSame(Prestataire::STATE_ACTIVE, $p->getState());
        $this->assertNull($p->getSiret());
        $this->assertNull($p->getEmail());
        $this->assertNull($p->getPhone());
        $this->assertNull($p->getAddress());
        $this->assertNull($p->getZipCode());
        $this->assertNull($p->getCity());
        $this->assertNull($p->getUpdatedAt());
        $this->assertInstanceOf(\DateTimeImmutable::class, $p->getCreatedAt());
        $this->assertCount(0, $p->getFactures());
    }

    public function testRaisonSociale(): void
    {
        $p = new Prestataire('Initial');
        $p->setRaisonSociale('Nouveau Nom SAS');
        $this->assertSame('Nouveau Nom SAS', $p->getRaisonSociale());
    }

    public function testSiret(): void
    {
        $p = new Prestataire('Test');
        $this->assertNull($p->getSiret());
        $p->setSiret('12345678901234');
        $this->assertSame('12345678901234', $p->getSiret());
        $p->setSiret(null);
        $this->assertNull($p->getSiret());
    }

    public function testEmail(): void
    {
        $p = new Prestataire('Test');
        $this->assertNull($p->getEmail());
        $p->setEmail('contact@prestataire.fr');
        $this->assertSame('contact@prestataire.fr', $p->getEmail());
        $p->setEmail(null);
        $this->assertNull($p->getEmail());
    }

    public function testPhone(): void
    {
        $p = new Prestataire('Test');
        $this->assertNull($p->getPhone());
        $p->setPhone('0612345678');
        $this->assertSame('0612345678', $p->getPhone());
        $p->setPhone(null);
        $this->assertNull($p->getPhone());
    }

    public function testAddress(): void
    {
        $p = new Prestataire('Test');
        $this->assertNull($p->getAddress());
        $this->assertNull($p->getZipCode());
        $this->assertNull($p->getCity());

        $p->setAddress('10 rue de la Paix');
        $p->setZipCode('75001');
        $p->setCity('Paris');

        $this->assertSame('10 rue de la Paix', $p->getAddress());
        $this->assertSame('75001', $p->getZipCode());
        $this->assertSame('Paris', $p->getCity());
    }

    public function testGetFullAddress(): void
    {
        $p = new Prestataire('Test');
        $this->assertSame('', $p->getFullAddress());

        $p->setAddress('10 rue de la Paix');
        $p->setZipCode('75001');
        $p->setCity('Paris');

        $this->assertSame('10 rue de la Paix 75001 Paris', $p->getFullAddress());
    }

    public function testGetFullAddressPartial(): void
    {
        $p = new Prestataire('Test');
        $p->setCity('Lyon');
        $this->assertSame('Lyon', $p->getFullAddress());
    }

    public function testState(): void
    {
        $p = new Prestataire('Test');
        $this->assertSame(Prestataire::STATE_ACTIVE, $p->getState());
        $this->assertNull($p->getUpdatedAt());

        $p->setState(Prestataire::STATE_INACTIVE);
        $this->assertSame(Prestataire::STATE_INACTIVE, $p->getState());
        $this->assertInstanceOf(\DateTimeImmutable::class, $p->getUpdatedAt());
    }

    public function testAddFacture(): void
    {
        $p = new Prestataire('Test');
        $this->assertCount(0, $p->getFactures());

        $f = new FacturePrestataire($p, 'FACT-001', 2026, 4);
        $p->addFacture($f);
        $this->assertCount(1, $p->getFactures());

        // Adding same instance twice must not duplicate
        $p->addFacture($f);
        $this->assertCount(1, $p->getFactures());
    }

    public function testGetTotalPaidHtNoFactures(): void
    {
        $p = new Prestataire('Test');
        $this->assertSame(0.0, $p->getTotalPaidHt());
    }

    public function testGetTotalPaidHtOnlyPaid(): void
    {
        $p = new Prestataire('Test');

        $f1 = new FacturePrestataire($p, 'FACT-001', 2026, 1);
        $f1->setMontantHt('1000.00');
        $f1->setIsPaid(true);
        $p->addFacture($f1);

        $f2 = new FacturePrestataire($p, 'FACT-002', 2026, 2);
        $f2->setMontantHt('500.00');
        $f2->setIsPaid(false);
        $p->addFacture($f2);

        $this->assertSame(1000.0, $p->getTotalPaidHt());
    }

    public function testGetTotalPaidHtMultiplePaid(): void
    {
        $p = new Prestataire('Test');

        $f1 = new FacturePrestataire($p, 'FACT-001', 2026, 1);
        $f1->setMontantHt('250.50');
        $f1->setIsPaid(true);
        $p->addFacture($f1);

        $f2 = new FacturePrestataire($p, 'FACT-002', 2026, 2);
        $f2->setMontantHt('749.50');
        $f2->setIsPaid(true);
        $p->addFacture($f2);

        $this->assertEqualsWithDelta(1000.0, $p->getTotalPaidHt(), 0.001);
    }

    public function testStateConstants(): void
    {
        $this->assertSame('active', Prestataire::STATE_ACTIVE);
        $this->assertSame('inactive', Prestataire::STATE_INACTIVE);
    }
}
