<?php

declare(strict_types=1);

namespace App\Tests\Functional\Module\Directory;

use ApiPlatform\Metadata\Post;
use App\Module\Directory\Domain\Entity\Prospect;
use App\Module\Directory\Domain\Enum\ProspectStatus;
use App\Module\Directory\Infrastructure\ApiPlatform\State\ConvertProspectProcessor;
use App\Module\Directory\Infrastructure\Doctrine\DoctrineProspectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @internal
 */
class ProspectConversionTest extends KernelTestCase
{
    private EntityManagerInterface $em;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->em = self::getContainer()->get(EntityManagerInterface::class);
    }

    public function testConvertCreatesClientAndFlagsProspectWon(): void
    {
        $prospect = new Prospect();
        $prospect->setCompany('Lead Company '.uniqid());
        $prospect->setEmail('lead@example.com');
        $prospect->setPhone('06 00 00 00 00');
        $prospect->setStatus(ProspectStatus::Qualified);
        $this->em->persist($prospect);
        $this->em->flush();

        $result = $this->processor()->process($prospect, new Post(), ['id' => $prospect->getId()]);

        self::assertSame(ProspectStatus::Won, $result->getStatus());
        $client = $result->getConvertedClient();
        self::assertNotNull($client);
        self::assertSame($prospect->getCompany(), $client->getName());
    }

    public function testConvertIsIdempotent(): void
    {
        $prospect = new Prospect();
        $prospect->setCompany('Idempotent Lead');
        $prospect->setStatus(ProspectStatus::New);
        $this->em->persist($prospect);
        $this->em->flush();

        $processor = $this->processor();
        $first     = $processor->process($prospect, new Post(), ['id' => $prospect->getId()]);
        $clientId  = $first->getConvertedClient()?->getId();

        $second = $processor->process($prospect, new Post(), ['id' => $prospect->getId()]);

        self::assertNotNull($clientId);
        self::assertSame($clientId, $second->getConvertedClient()?->getId());
    }

    private function processor(): ConvertProspectProcessor
    {
        $c = self::getContainer();

        return new ConvertProspectProcessor(
            $c->get(EntityManagerInterface::class),
            $c->get(DoctrineProspectRepository::class),
        );
    }
}
