<?php

declare(strict_types=1);

use App\Support\RussianRegions;

/**
 * Нормализация регионов реестра Россвязи → subject_code.
 * Кейсы взяты из реальных топ-50 unmapped-форматов прод-реестра (02.06.2026).
 */
it('maps cities of federal significance with the г. prefix', function (): void {
    expect(RussianRegions::resolveSubjectCode('г. Москва'))->toBe(82)
        ->and(RussianRegions::resolveSubjectCode('г. Санкт-Петербург'))->toBe(83)
        ->and(RussianRegions::resolveSubjectCode('г. Севастополь'))->toBe(84);
});

it('still maps a plain canonical federal-city name', function (): void {
    expect(RussianRegions::resolveSubjectCode('Москва'))->toBe(82);
});

it('takes the last pipe segment as the subject region', function (): void {
    // регион = последний сегмент после |
    expect(RussianRegions::resolveSubjectCode('г. Оренбург|Оренбургская обл.'))->toBe(62)
        ->and(RussianRegions::resolveSubjectCode('г. Воскресенск|р-н Воскресенский|Московская обл.'))->toBe(56);
});

it('expands the обл. abbreviation to область', function (): void {
    expect(RussianRegions::resolveSubjectCode('г. Иркутск|Иркутская обл.'))->toBe(45)
        ->and(RussianRegions::resolveSubjectCode('г. Балашиха|Московская обл.'))->toBe(56);
});

it('keeps already-canonical край/республика segments', function (): void {
    expect(RussianRegions::resolveSubjectCode('г. Красноярск|Красноярский край'))->toBe(29)
        ->and(RussianRegions::resolveSubjectCode('г. Уфа|Республика Башкортостан'))->toBe(3);
});

it('reorders the Удмуртская Республика inverted form', function (): void {
    expect(RussianRegions::resolveSubjectCode('г. Ижевск|Республика Удмуртская'))->toBe(21);
});

it('maps the Кузбасс special form to Кемеровская область', function (): void {
    expect(RussianRegions::resolveSubjectCode('г. Кемерово|Кемеровская область - Кузбасс обл.'))->toBe(48);
});

it('returns null for hopeless / ambiguous / city-only strings', function (string $raw): void {
    expect(RussianRegions::resolveSubjectCode($raw))->toBeNull();
})->with([
    '-',
    'Российская Федерация',
    'Москва и Московская область', // неоднозначно — два субъекта
    'г.о. Тольятти',               // нет региона в строке
    'г.о. город Уфа',
    '',
    '   ',
]);

it('exposes the canonical name via canonicalRegionName', function (): void {
    expect(RussianRegions::canonicalRegionName('г. Оренбург|Оренбургская обл.'))->toBe('Оренбургская область')
        ->and(RussianRegions::canonicalRegionName('г. Ижевск|Республика Удмуртская'))->toBe('Удмуртская Республика')
        ->and(RussianRegions::canonicalRegionName('-'))->toBeNull();
});

it('expands the АО abbreviation to автономный округ', function (): void {
    expect(RussianRegions::resolveSubjectCode('Ненецкий АО'))->toBe(86)
        ->and(RussianRegions::resolveSubjectCode('Чукотский АО'))->toBe(88)
        ->and(RussianRegions::resolveSubjectCode('г. Салехард|Ямало-Ненецкий АО'))->toBe(89);
});

it('maps Ханты-Мансийск variants to ХМАО — Югра', function (): void {
    expect(RussianRegions::resolveSubjectCode('г. Сургут|Ханты-Мансийский Автономный округ - Югра АО'))->toBe(87)
        ->and(RussianRegions::resolveSubjectCode('Ханты-Мансийский АО - Югра'))->toBe(87)
        ->and(RussianRegions::resolveSubjectCode('Ханты-Мансийский Автономный округ - Югра.'))->toBe(87);
});

it('reorders inverted Республика X forms', function (): void {
    expect(RussianRegions::resolveSubjectCode('Республика Чеченская'))->toBe(23)
        ->and(RussianRegions::resolveSubjectCode('Республика Кабардино-Балкарская'))->toBe(8)
        ->and(RussianRegions::resolveSubjectCode('Республика Карачаево-Черкесская'))->toBe(10)
        ->and(RussianRegions::resolveSubjectCode('Республика Донецкая Народная'))->toBe(6)
        ->and(RussianRegions::resolveSubjectCode('Республика Луганская Народная'))->toBe(14);
});

it('keeps Республика-first canonical names as-is', function (): void {
    expect(RussianRegions::resolveSubjectCode('Республика Татарстан'))->toBe(19)
        ->and(RussianRegions::resolveSubjectCode('Республика Карелия'))->toBe(11);
});

it('handles irregular subject spellings (Саха, Чувашия, Кузбасс)', function (): void {
    expect(RussianRegions::resolveSubjectCode('у. Мирнинский|Республика Саха /Якутия/'))->toBe(17)
        ->and(RussianRegions::resolveSubjectCode('г. Чебоксары|Чувашская Республика - Чувашия'))->toBe(24)
        ->and(RussianRegions::resolveSubjectCode('Кемеровская область - Кузбасс область'))->toBe(48);
});

it('maps Moscow / SPb spelling variants', function (): void {
    expect(RussianRegions::resolveSubjectCode('Город Москва'))->toBe(82)
        ->and(RussianRegions::resolveSubjectCode('г. Санкт - Петербург'))->toBe(83);
});

it('normalizes spaced hyphen to em-dash (Северная Осетия — Алания)', function (): void {
    expect(RussianRegions::resolveSubjectCode('Республика Северная Осетия - Алания'))->toBe(18)
        ->and(RussianRegions::resolveSubjectCode('г. Владикавказ|Республика Северная Осетия - Алания'))->toBe(18);
});
