<?php

declare(strict_types=1);

namespace App\Tests\Module\Transport\Application\Idtf;

use App\Module\Transport\Application\Idtf\IdtfSheetParser;
use PHPUnit\Framework\TestCase;
use RuntimeException;

/**
 * @internal
 */
final class IdtfSheetParserTest extends TestCase
{
    public function testExtractsExportDate(): void
    {
        $parsed = IdtfSheetParser::parse($this->sampleMatrix());
        self::assertSame('2026-06-12', $parsed['exportDate']);
    }

    public function testParsesAndNormalizesFirstRow(): void
    {
        $parsed = IdtfSheetParser::parse($this->sampleMatrix());
        $row    = $parsed['rows'][0];

        self::assertSame(30748, $row['idtf_number']);
        self::assertSame('Argiles avec régime de nettoyage C', $row['name']);
        self::assertSame('C', $row['cleaning_regime']);
        self::assertSame('2026-04-02', $row['mandatory_date']);
        self::assertSame('Al2O3', $row['formula']);
        self::assertSame('01 01 01', $row['eural_code']);
        self::assertSame(['7631-86-9', '1344-28-1'], $row['cas_numbers']);
        self::assertSame('Note 1', $row['footnotes']);
    }

    public function testSkipsEmptyAndNonNumericRows(): void
    {
        $parsed = IdtfSheetParser::parse($this->sampleMatrix());

        // 2 lignes exploitables (30748 et 30744) ; vide + "abc" ignorees.
        self::assertCount(2, $parsed['rows']);
        self::assertSame(30744, $parsed['rows'][1]['idtf_number']);
    }

    public function testEmptyOptionalCellsBecomeNullAndCasEmpty(): void
    {
        $parsed = IdtfSheetParser::parse($this->sampleMatrix());
        $row    = $parsed['rows'][1]; // 30744

        self::assertNull($row['mandatory_date']);
        self::assertNull($row['formula']);
        self::assertNull($row['product_group']);
        self::assertSame([], $row['cas_numbers']);
    }

    public function testColumnOrderIsResolvedByLabel(): void
    {
        // En-tete dans un ordre different : le mapping doit suivre les libelles.
        $matrix = [
            ['Export date: 1-1-2026'],
            ['Numéro CAS', 'Numéro IDTF', 'Nom de la marchandise', 'Régime de nettoyage'],
            ['7440-44-0', '99', 'Carbone', 'B'],
        ];

        $parsed = IdtfSheetParser::parse($matrix);
        $row    = $parsed['rows'][0];

        self::assertSame(99, $row['idtf_number']);
        self::assertSame('Carbone', $row['name']);
        self::assertSame('B', $row['cleaning_regime']);
        self::assertSame(['7440-44-0'], $row['cas_numbers']);
    }

    public function testThrowsWhenHeaderMissing(): void
    {
        $this->expectException(RuntimeException::class);
        IdtfSheetParser::parse([['foo', 'bar'], ['1', '2']]);
    }

    public function testExportDateNullWhenAbsent(): void
    {
        $matrix = [
            ['Numéro IDTF', 'Nom de la marchandise', 'Régime de nettoyage'],
            ['1', 'X', 'A'],
        ];

        self::assertNull(IdtfSheetParser::parse($matrix)['exportDate']);
    }

    /**
     * Matrice representative de l'export reel : preambule (lignes 0-1), ligne
     * vide (2), en-tete (3) puis donnees.
     *
     * @return array<int, array<int, mixed>>
     */
    private function sampleMatrix(): array
    {
        return [
            ['Export date: 12-6-2026'],
            ['Changes in the database after this date...'],
            [],
            ['Numéro IDTF', 'Product Group', 'Nom de la marchandise', 'Régime de nettoyage', 'Exigences importantes', 'Date d’application obligatoire', 'Produits apparentés', 'Formule', 'Code EURAL', 'Numéro CAS', 'Annotations'],
            ['30748', 'Substances inorganiques', 'Argiles avec régime de nettoyage C', 'C', 'Exigence X', '02-04-2026', 'Poudre argile', 'Al2O3', '01 01 01', '7631-86-9 ; 1344-28-1', 'Note 1'],
            ['', '', '', '', '', '', '', '', '', '', ''],
            ['abc', 'ligne non numerique a ignorer', '', '', '', '', '', '', '', '', ''],
            ['30744', '', 'Additifs alimentaires', 'A', '', '', '', '', '', '', ''],
        ];
    }
}
