<?php

namespace App\Tests\Command;

use App\Command\PurgeTxtCommand;
use App\Entity\Formules;
use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

#[AllowMockObjectsWithoutExpectations]
class PurgeTxtCommandTest extends TestCase
{
    private MockObject&EntityManagerInterface $entityManager;
    private MockObject&EntityRepository $productRepository;
    private MockObject&EntityRepository $formulesRepository;

    protected function setUp(): void
    {
        $this->entityManager = $this->createMock(EntityManagerInterface::class);
        $this->productRepository = $this->createMock(EntityRepository::class);
        $this->formulesRepository = $this->createMock(EntityRepository::class);

        $this->entityManager->method('getRepository')->willReturnMap([
            [Product::class, $this->productRepository],
            [Formules::class, $this->formulesRepository],
        ]);
    }

    public function testExecute()
    {
        // 1. Setup Product Data
        $product = new Product();
        $product->setDescription('<p>Description <b>HTML</b> &eacute; purger.</p>');
        
        $this->productRepository->method('findAll')->willReturn([$product]);

        // 2. Setup Formules Data
        $formule = new Formules();
        $formule->setDescription('<div>Une autre <br> description.</div>');
        
        $this->formulesRepository->method('findAll')->willReturn([$formule]);

        // 3. Expect Flush
        $this->entityManager->expects($this->once())->method('flush');

        // 4. Execute
        $command = new PurgeTxtCommand($this->entityManager);
        $application = new Application();
        $application->addCommand($command);
        $commandTester = new CommandTester($application->find('app:txt:purge'));

        $commandTester->execute([]);

        // 5. Assertions
        $this->assertEquals('Description HTML é purger.', $product->getDescription());
        $this->assertEquals('Une autre description.', $formule->getDescription());
        
        $this->assertStringContainsString('Purge terminée', $commandTester->getDisplay());
    }
}
