<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Domain\Model\Import;

use App\Administration\Domain\Exception\MappingIncompletException;
use App\Administration\Domain\Model\Import\ColumnMapping;
use App\Administration\Domain\Model\Import\KnownImportFormat;
use App\Administration\Domain\Model\Import\StudentImportField;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class ColumnMappingTest extends TestCase
{
    #[Test]
    public function creerWithAllRequiredFieldsSucceeds(): void
    {
        $mapping = ColumnMapping::creer(
            [
                'Nom' => StudentImportField::LAST_NAME,
                'Prénom' => StudentImportField::FIRST_NAME,
                'Classe' => StudentImportField::CLASS_NAME,
            ],
            KnownImportFormat::CUSTOM,
        );

        self::assertCount(3, $mapping->colonnesSources());
        self::assertSame(KnownImportFormat::CUSTOM, $mapping->format);
    }

    #[Test]
    public function creerWithOptionalFieldsSucceeds(): void
    {
        $mapping = ColumnMapping::creer(
            [
                'Nom' => StudentImportField::LAST_NAME,
                'Prénom' => StudentImportField::FIRST_NAME,
                'Classe' => StudentImportField::CLASS_NAME,
                'Email' => StudentImportField::EMAIL,
                'Naissance' => StudentImportField::BIRTH_DATE,
            ],
            KnownImportFormat::PRONOTE,
        );

        self::assertCount(5, $mapping->colonnesSources());
    }

    #[Test]
    public function creerSansNomLeveException(): void
    {
        $this->expectException(MappingIncompletException::class);

        ColumnMapping::creer(
            [
                'Prénom' => StudentImportField::FIRST_NAME,
                'Classe' => StudentImportField::CLASS_NAME,
            ],
            KnownImportFormat::CUSTOM,
        );
    }

    #[Test]
    public function creerSansPrenomLeveException(): void
    {
        $this->expectException(MappingIncompletException::class);

        ColumnMapping::creer(
            [
                'Nom' => StudentImportField::LAST_NAME,
                'Classe' => StudentImportField::CLASS_NAME,
            ],
            KnownImportFormat::CUSTOM,
        );
    }

    #[Test]
    public function creerSansClasseLeveException(): void
    {
        $this->expectException(MappingIncompletException::class);

        ColumnMapping::creer(
            [
                'Nom' => StudentImportField::LAST_NAME,
                'Prénom' => StudentImportField::FIRST_NAME,
            ],
            KnownImportFormat::CUSTOM,
        );
    }

    #[Test]
    public function champPourReturnsMappedField(): void
    {
        $mapping = ColumnMapping::creer(
            [
                'Nom' => StudentImportField::LAST_NAME,
                'Prénom' => StudentImportField::FIRST_NAME,
                'Classe' => StudentImportField::CLASS_NAME,
            ],
            KnownImportFormat::CUSTOM,
        );

        self::assertSame(StudentImportField::LAST_NAME, $mapping->champPour('Nom'));
        self::assertSame(StudentImportField::FIRST_NAME, $mapping->champPour('Prénom'));
        self::assertNull($mapping->champPour('Inconnu'));
    }

    #[Test]
    public function equalsComparesCorrectly(): void
    {
        $mapping1 = ColumnMapping::creer(
            ['Nom' => StudentImportField::LAST_NAME, 'Prénom' => StudentImportField::FIRST_NAME, 'Classe' => StudentImportField::CLASS_NAME],
            KnownImportFormat::CUSTOM,
        );

        $mapping2 = ColumnMapping::creer(
            ['Nom' => StudentImportField::LAST_NAME, 'Prénom' => StudentImportField::FIRST_NAME, 'Classe' => StudentImportField::CLASS_NAME],
            KnownImportFormat::CUSTOM,
        );

        $mapping3 = ColumnMapping::creer(
            ['Nom' => StudentImportField::LAST_NAME, 'Prénom' => StudentImportField::FIRST_NAME, 'Classe' => StudentImportField::CLASS_NAME],
            KnownImportFormat::PRONOTE,
        );

        self::assertTrue($mapping1->equals($mapping2));
        self::assertFalse($mapping1->equals($mapping3));
    }
}
