<?php

namespace App\Tests\Entity;

use App\Entity\Billet;
use App\Entity\Category;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\File\File;

class BilletTest extends TestCase
{
    public function testNewBilletDefaults(): void
    {
        $billet = new Billet();

        self::assertNull($billet->getId());
        self::assertNull($billet->getName());
        self::assertNull($billet->getCategory());
        self::assertNull($billet->getDescription());
        self::assertNull($billet->getPictureName());
        self::assertNull($billet->getPictureFile());
        self::assertNull($billet->getUpdatedAt());
        self::assertSame(0, $billet->getPosition());
        self::assertSame(0, $billet->getPriceHT());
        self::assertNull($billet->getQuantity());
        self::assertTrue($billet->isUnlimited());
        self::assertTrue($billet->isGeneratedBillet());
        self::assertFalse($billet->hasDefinedExit());
        self::assertFalse($billet->isNotBuyable());
        self::assertSame('billet', $billet->getType());
        self::assertNull($billet->getStripeProductId());
        self::assertInstanceOf(\DateTimeImmutable::class, $billet->getCreatedAt());
    }

    public function testSetAndGetCategory(): void
    {
        $billet = new Billet();
        $category = new Category();
        $result = $billet->setCategory($category);

        self::assertSame($category, $billet->getCategory());
        self::assertSame($billet, $result);
    }

    public function testSetAndGetName(): void
    {
        $billet = new Billet();
        $result = $billet->setName('Entree VIP');

        self::assertSame('Entree VIP', $billet->getName());
        self::assertSame($billet, $result);
    }

    public function testSetAndGetPriceHT(): void
    {
        $billet = new Billet();
        $result = $billet->setPriceHT(1500);

        self::assertSame(1500, $billet->getPriceHT());
        self::assertSame($billet, $result);
    }

    public function testGetPriceHTDecimal(): void
    {
        $billet = new Billet();
        $billet->setPriceHT(1500);

        self::assertSame(15.0, $billet->getPriceHTDecimal());
    }

    public function testGetPriceHTDecimalZero(): void
    {
        $billet = new Billet();

        self::assertSame(0.0, $billet->getPriceHTDecimal());
    }

    public function testSetAndGetIsGeneratedBillet(): void
    {
        $billet = new Billet();
        $result = $billet->setIsGeneratedBillet(false);

        self::assertFalse($billet->isGeneratedBillet());
        self::assertSame($billet, $result);

        $billet->setIsGeneratedBillet(true);
        self::assertTrue($billet->isGeneratedBillet());
    }

    public function testSetAndGetHasDefinedExit(): void
    {
        $billet = new Billet();
        $result = $billet->setHasDefinedExit(true);

        self::assertTrue($billet->hasDefinedExit());
        self::assertSame($billet, $result);

        $billet->setHasDefinedExit(false);
        self::assertFalse($billet->hasDefinedExit());
    }

    public function testSetAndGetDescription(): void
    {
        $billet = new Billet();
        $result = $billet->setDescription('Acces backstage inclus');

        self::assertSame('Acces backstage inclus', $billet->getDescription());
        self::assertSame($billet, $result);
    }

    public function testSetDescriptionNull(): void
    {
        $billet = new Billet();
        $billet->setDescription('Test');
        $billet->setDescription(null);

        self::assertNull($billet->getDescription());
    }

    public function testSetAndGetPictureName(): void
    {
        $billet = new Billet();
        $result = $billet->setPictureName('billet-vip.jpg');

        self::assertSame('billet-vip.jpg', $billet->getPictureName());
        self::assertSame($billet, $result);
    }

    public function testSetPictureFileUpdatesTimestamp(): void
    {
        $billet = new Billet();
        self::assertNull($billet->getUpdatedAt());

        $file = $this->createMock(File::class);
        $result = $billet->setPictureFile($file);

        self::assertSame($file, $billet->getPictureFile());
        self::assertInstanceOf(\DateTimeImmutable::class, $billet->getUpdatedAt());
        self::assertSame($billet, $result);
    }

    public function testSetAndGetPosition(): void
    {
        $billet = new Billet();
        $result = $billet->setPosition(3);

        self::assertSame(3, $billet->getPosition());
        self::assertSame($billet, $result);
    }

    public function testSetAndGetQuantity(): void
    {
        $billet = new Billet();
        $result = $billet->setQuantity(100);

        self::assertSame(100, $billet->getQuantity());
        self::assertFalse($billet->isUnlimited());
        self::assertSame($billet, $result);

        $billet->setQuantity(null);
        self::assertNull($billet->getQuantity());
        self::assertTrue($billet->isUnlimited());
    }

    public function testSetAndGetNotBuyable(): void
    {
        $billet = new Billet();
        $result = $billet->setNotBuyable(true);

        self::assertTrue($billet->isNotBuyable());
        self::assertSame($billet, $result);

        $billet->setNotBuyable(false);
        self::assertFalse($billet->isNotBuyable());
    }

    public function testSetAndGetType(): void
    {
        $billet = new Billet();
        $result = $billet->setType('reservation_brocante');

        self::assertSame('reservation_brocante', $billet->getType());
        self::assertSame($billet, $result);

        $billet->setType('vote');
        self::assertSame('vote', $billet->getType());
    }

    public function testSetAndGetStripeProductId(): void
    {
        $billet = new Billet();
        $result = $billet->setStripeProductId('prod_abc123');

        self::assertSame('prod_abc123', $billet->getStripeProductId());
        self::assertSame($billet, $result);

        $billet->setStripeProductId(null);
        self::assertNull($billet->getStripeProductId());
    }

    public function testSetPictureFileNullDoesNotUpdateTimestamp(): void
    {
        $billet = new Billet();
        $billet->setPictureFile(null);

        self::assertNull($billet->getUpdatedAt());
        self::assertNull($billet->getPictureFile());
    }

    public function testSetCategoryNull(): void
    {
        $billet = new Billet();
        $billet->setCategory(null);

        self::assertNull($billet->getCategory());
    }

    public function testGetCreatedAt(): void
    {
        $before = new \DateTimeImmutable();
        $billet = new Billet();
        $after = new \DateTimeImmutable();

        self::assertGreaterThanOrEqual($before, $billet->getCreatedAt());
        self::assertLessThanOrEqual($after, $billet->getCreatedAt());
    }
}
