<?php

declare(strict_types=1);

namespace App\Tests\Module\Catalog\Api;

use App\Module\Catalog\Application\Service\CategoryCodeGenerator;
use App\Shared\Infrastructure\Database\CategoryCodeSql;
use Doctrine\DBAL\Connection;
use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * Garde-fou ERP-78 : l'expression SQL de slug (CategoryCodeSql, utilisee par le
 * backfill de la migration Version20260602100000) doit produire EXACTEMENT le
 * meme code que le generateur applicatif (CategoryCodeGenerator::slugify), sur
 * tout le domaine de noms francais / Latin-1.
 *
 * Verrouille la cause racine du bug initial : deux implementations d'un meme
 * slug qui derivent silencieusement (« Independant » -> IND_PENDANT cote SQL
 * faute de translitteration des accents, vs INDEPENDANT cote PHP). On ne couvre
 * volontairement PAS les ligatures (`Œ`, `ß`) : `translate()` est 1->1 et ne
 * peut produire `OE`/`SS` ; elles sont hors du domaine des categories CLIENT.
 *
 * @internal
 */
final class CategoryCodeSqlSlugTest extends KernelTestCase
{
    /**
     * Noms representatifs du domaine reel : accents, cedille, apostrophe,
     * separateurs varies, parentheses, majuscules accentuees.
     *
     * @return iterable<string, array{string}>
     */
    public static function nameProvider(): iterable
    {
        yield 'sans accent'         => ['Distributeur'];
        yield 'tiret'               => ['Agro-alimentaire'];
        yield 'slash'               => ['Transport/Logistique'];
        yield 'accent aigu'         => ['Indépendant'];
        yield 'apostrophe + accent' => ["L'Oréal"];
        yield 'esperluette'         => ['Forêt & Bûcheron'];
        yield 'cedille majuscule'   => ['Ça va'];
        yield 'accents multiples'   => ['Naïve façade'];
        yield 'circonflexe'         => ["Côte d'Azur"];
        yield 'parentheses'         => ['Zone (Sud)'];
    }

    #[DataProvider('nameProvider')]
    public function testSqlSlugMatchesPhpSlug(string $name): void
    {
        self::bootKernel();
        $container = self::getContainer();

        /** @var Connection $conn */
        $conn = $container->get('doctrine')->getConnection();
        /** @var CategoryCodeGenerator $generator */
        $generator = $container->get(CategoryCodeGenerator::class);

        // Evaluation pure de l'expression (aucune table requise) : le nom est
        // passe en parametre lie a la place de la colonne.
        $sqlSlug = $conn->fetchOne(
            'SELECT '.CategoryCodeSql::slugExpression(':name'),
            ['name' => $name],
        );

        self::assertSame(
            $generator->slugify($name),
            $sqlSlug,
            sprintf('SQL et PHP doivent produire le meme slug pour "%s".', $name),
        );
    }
}
