<?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\KnownImportFormat;
use App\Administration\Domain\Model\Import\TeacherColumnMapping;
use App\Administration\Domain\Model\Import\TeacherImportField;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class TeacherColumnMappingTest extends TestCase
{
    #[Test]
    public function creerWithAllRequiredFieldsSucceeds(): void
    {
        $mapping = TeacherColumnMapping::creer(
            [
                'Nom' => TeacherImportField::LAST_NAME,
                'Prénom' => TeacherImportField::FIRST_NAME,
                'Email' => TeacherImportField::EMAIL,
            ],
            KnownImportFormat::CUSTOM,
        );

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

    #[Test]
    public function creerWithOptionalFieldsSucceeds(): void
    {
        $mapping = TeacherColumnMapping::creer(
            [
                'Nom' => TeacherImportField::LAST_NAME,
                'Prénom' => TeacherImportField::FIRST_NAME,
                'Email' => TeacherImportField::EMAIL,
                'Matières' => TeacherImportField::SUBJECTS,
                'Classes' => TeacherImportField::CLASSES,
            ],
            KnownImportFormat::CUSTOM,
        );

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

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

        TeacherColumnMapping::creer(
            [
                'Prénom' => TeacherImportField::FIRST_NAME,
                'Email' => TeacherImportField::EMAIL,
            ],
            KnownImportFormat::CUSTOM,
        );
    }

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

        TeacherColumnMapping::creer(
            [
                'Nom' => TeacherImportField::LAST_NAME,
                'Email' => TeacherImportField::EMAIL,
            ],
            KnownImportFormat::CUSTOM,
        );
    }

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

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

    #[Test]
    public function champPourReturnsMappedField(): void
    {
        $mapping = TeacherColumnMapping::creer(
            [
                'Nom' => TeacherImportField::LAST_NAME,
                'Prénom' => TeacherImportField::FIRST_NAME,
                'Email' => TeacherImportField::EMAIL,
            ],
            KnownImportFormat::CUSTOM,
        );

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

    #[Test]
    public function equalsComparesCorrectly(): void
    {
        $mapping1 = TeacherColumnMapping::creer(
            ['Nom' => TeacherImportField::LAST_NAME, 'Prénom' => TeacherImportField::FIRST_NAME, 'Email' => TeacherImportField::EMAIL],
            KnownImportFormat::CUSTOM,
        );

        $mapping2 = TeacherColumnMapping::creer(
            ['Nom' => TeacherImportField::LAST_NAME, 'Prénom' => TeacherImportField::FIRST_NAME, 'Email' => TeacherImportField::EMAIL],
            KnownImportFormat::CUSTOM,
        );

        $mapping3 = TeacherColumnMapping::creer(
            ['Nom' => TeacherImportField::LAST_NAME, 'Prénom' => TeacherImportField::FIRST_NAME, 'Email' => TeacherImportField::EMAIL],
            KnownImportFormat::PRONOTE,
        );

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