<?php

declare(strict_types=1);

namespace App\Tests\Module\Commercial\Api;

/**
 * Tests de structure / migration M2 (§ 8.1). Vérifie au niveau du schéma Postgres :
 *  - l'unique index partiel fonctionnel uq_supplier_company_name_active existe
 *    (LOWER(company_name), partiel sur actifs non archivés / non supprimés —
 *    RG-2.11), seule unicité de nom conservée ; pas d'index unique siren/email ;
 *  - le type de catégorie FOURNISSEUR est présent (seedé migration + fixture).
 *
 * @internal
 */
final class SupplierMigrationTest extends AbstractSupplierApiTestCase
{
    public function testCompanyNameActivePartialIndexExistsExactlyOnce(): void
    {
        $rows = $this->supplierIndexes();

        $companyNameIndexes = array_filter(
            $rows,
            static fn (array $r): bool => 'uq_supplier_company_name_active' === $r['indexname'],
        );

        self::assertCount(1, $companyNameIndexes, 'Il doit exister exactement UN index uq_supplier_company_name_active.');

        $def = strtolower((string) array_values($companyNameIndexes)[0]['indexdef']);
        self::assertStringContainsString('unique', $def);
        self::assertStringContainsString('lower', $def);
        self::assertStringContainsString('company_name', $def);
        self::assertStringContainsString('where', $def, 'L\'index doit etre partiel (clause WHERE sur les actifs).');
    }

    public function testNoSirenOrEmailUniqueIndexOnSupplier(): void
    {
        $names = array_map(static fn (array $r): string => $r['indexname'], $this->supplierIndexes());

        // § 2.6 : SIREN et email NON uniques sur le fournisseur.
        self::assertNotContains('uq_supplier_siren_active', $names);
        self::assertNotContains('uq_supplier_email_active', $names);
    }

    public function testFournisseurCategoryTypeExists(): void
    {
        self::bootKernel();

        $count = (int) $this->getEm()->getConnection()->fetchOne(
            "SELECT COUNT(*) FROM category_type WHERE code = 'FOURNISSEUR'",
        );

        self::assertSame(1, $count, 'Le type de categorie FOURNISSEUR doit etre present (migration + fixture).');
    }

    /**
     * @return list<array{indexname: string, indexdef: string}>
     */
    private function supplierIndexes(): array
    {
        self::bootKernel();

        /** @var list<array{indexname: string, indexdef: string}> $rows */
        return $this->getEm()->getConnection()->fetchAllAssociative(
            "SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'supplier'",
        );
    }
}
