<?php

namespace App\Tests\Entity;

use App\Entity\Customer;
use App\Entity\User;
use PHPUnit\Framework\TestCase;

class CustomerTest extends TestCase
{
    private function createCustomer(): Customer
    {
        $user = new User();
        $user->setEmail('c@test.com');
        $user->setFirstName('John');
        $user->setLastName('Doe');
        $user->setPassword('h');

        return new Customer($user);
    }

    public function testConstructor(): void
    {
        $c = $this->createCustomer();
        $this->assertNull($c->getId());
        $this->assertSame('John', $c->getUser()->getFirstName());
        $this->assertSame(Customer::STATE_ACTIVE, $c->getState());
        $this->assertTrue($c->isActive());
        $this->assertInstanceOf(\DateTimeImmutable::class, $c->getCreatedAt());
        $this->assertNull($c->getUpdatedAt());
    }

    public function testCodeComptable(): void
    {
        $c = $this->createCustomer();
        $this->assertNull($c->getCodeComptable());
        $c->setCodeComptable('C-001');
        $this->assertSame('C-001', $c->getCodeComptable());
    }

    public function testGenerateCodeComptable(): void
    {
        $c = $this->createCustomer();
        $code = $c->generateCodeComptable();
        $this->assertNotEmpty($code);
        $this->assertStringStartsWith('EC-', $code);
    }

    public function testGenerateCodeComptableWithRaisonSociale(): void
    {
        $c = $this->createCustomer();
        $c->setRaisonSociale('SITECONSEIL SAS');
        $code = $c->generateCodeComptable();
        $this->assertStringContainsString('SITEC', $code);
    }

    public function testGenerateCodeComptableWithLastName(): void
    {
        $c = $this->createCustomer();
        $c->setRaisonSociale(null);
        $c->setLastName('Dupont');
        $code = $c->generateCodeComptable();
        $this->assertStringContainsString('DUPON', $code);
    }

    public function testGenerateCodeComptableNoName(): void
    {
        $c = $this->createCustomer();
        $c->setRaisonSociale(null);
        $c->setLastName(null);
        $code = $c->generateCodeComptable();
        $this->assertStringContainsString('XXXXX', $code);
    }

    public function testNames(): void
    {
        $c = $this->createCustomer();
        $c->setFirstName('Jane');
        $c->setLastName('Smith');
        $this->assertSame('Jane', $c->getFirstName());
        $this->assertSame('Smith', $c->getLastName());
        $this->assertSame('Jane Smith', $c->getFullName());
    }

    public function testRaisonSociale(): void
    {
        $c = $this->createCustomer();
        $c->setRaisonSociale('SARL Test');
        $this->assertSame('SARL Test', $c->getRaisonSociale());
    }

    public function testContact(): void
    {
        $c = $this->createCustomer();
        $c->setEmail('new@test.com');
        $c->setPhone('0612345678');
        $this->assertSame('new@test.com', $c->getEmail());
        $this->assertSame('0612345678', $c->getPhone());
    }

    public function testAddress(): void
    {
        $c = $this->createCustomer();
        $c->setAddress('1 rue Test');
        $c->setAddress2('Bat A');
        $c->setZipCode('02100');
        $c->setCity('Saint-Quentin');
        $this->assertSame('1 rue Test', $c->getAddress());
        $this->assertSame('Bat A', $c->getAddress2());
        $this->assertSame('02100', $c->getZipCode());
        $this->assertSame('Saint-Quentin', $c->getCity());
    }

    public function testGeoCoordinates(): void
    {
        $c = $this->createCustomer();
        $this->assertNull($c->getGeoLat());
        $this->assertNull($c->getGeoLong());

        $c->setGeoLat('49.8486');
        $c->setGeoLong('3.2876');
        $this->assertSame('49.8486', $c->getGeoLat());
        $this->assertSame('3.2876', $c->getGeoLong());
    }

    public function testLegal(): void
    {
        $c = $this->createCustomer();
        $c->setSiret('12345678901234');
        $c->setRcs('RCS Paris');
        $c->setNumTva('FR12345678901');
        $c->setApe('62.01Z');
        $c->setRna('W502004724');
        $this->assertSame('12345678901234', $c->getSiret());
        $this->assertSame('RCS Paris', $c->getRcs());
        $this->assertSame('FR12345678901', $c->getNumTva());
        $this->assertSame('62.01Z', $c->getApe());
        $this->assertSame('W502004724', $c->getRna());
    }

    public function testStripe(): void
    {
        $c = $this->createCustomer();
        $this->assertNull($c->getStripeCustomerId());
        $c->setStripeCustomerId('cus_xxx');
        $this->assertSame('cus_xxx', $c->getStripeCustomerId());
    }

    public function testTypeCompany(): void
    {
        $c = $this->createCustomer();
        $c->setTypeCompany(Customer::TYPE_SARL);
        $this->assertSame('sarl', $c->getTypeCompany());
    }

    public function testState(): void
    {
        $c = $this->createCustomer();
        $c->setState(Customer::STATE_SUSPENDED);
        $this->assertSame(Customer::STATE_SUSPENDED, $c->getState());
        $this->assertFalse($c->isActive());
        $this->assertInstanceOf(\DateTimeImmutable::class, $c->getUpdatedAt());
    }

    public function testIsPendingDelete(): void
    {
        $c = $this->createCustomer();
        $this->assertFalse($c->isPendingDelete());

        $c->setState(Customer::STATE_PENDING_DELETE);
        $this->assertTrue($c->isPendingDelete());

        $c->setState(Customer::STATE_ACTIVE);
        $this->assertFalse($c->isPendingDelete());
    }

    public function testRevendeurCode(): void
    {
        $c = $this->createCustomer();
        $this->assertNull($c->getRevendeurCode());

        $c->setRevendeurCode('REV01');
        $this->assertSame('REV01', $c->getRevendeurCode());

        $c->setRevendeurCode(null);
        $this->assertNull($c->getRevendeurCode());
    }

    public function testSetUpdatedAt(): void
    {
        $c = $this->createCustomer();
        $this->assertNull($c->getUpdatedAt());

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

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