<?php

declare(strict_types=1);

use App\Services\Dto\RossvyazRecord;
use App\Services\RossvyazPrefixLookup;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;

uses(DatabaseTransactions::class);
uses(SharesSupplierPdo::class);

/**
 * Вставляет строку-журнал импорта и возвращает её id (import_id для phone_ranges).
 */
function seedRossvyazImport(): int
{
    return (int) DB::table('phone_ranges_imports')->insertGetId([
        'source_url' => 'https://rossvyaz.gov.ru/test',
        'checksum_sha256' => str_repeat('a', 64),
        'status' => 'completed',
        'imported_at' => now(),
    ]);
}

/**
 * @param  array<string, mixed>  $overrides
 */
function seedPhoneRange(array $overrides = []): void
{
    DB::table('phone_ranges')->insert(array_merge([
        'def_code' => 921,
        'from_num' => 5550000,
        'to_num' => 5559999,
        'operator' => 'МегаФон',
        'region' => 'Санкт-Петербург',
        'subject_code' => 83,
        'imported_at' => now(),
        'import_id' => seedRossvyazImport(),
    ], $overrides));
}

it('mobile prefix returns correct region and operator', function (): void {
    seedPhoneRange();

    $rec = app(RossvyazPrefixLookup::class)->find('79215555123');

    expect($rec)->toBeInstanceOf(RossvyazRecord::class)
        ->and($rec->subjectCode)->toBe(83)
        ->and($rec->region)->toBe('Санкт-Петербург')
        ->and($rec->operator)->toBe('МегаФон');
});

it('prefers narrower range when two ranges overlap', function (): void {
    $importId = seedRossvyazImport();
    // Широкий диапазон (вся 495-зона) — Московская область (56).
    seedPhoneRange([
        'def_code' => 495, 'from_num' => 1000000, 'to_num' => 9999999,
        'operator' => 'Ростелеком', 'region' => 'Московская область',
        'subject_code' => 56, 'import_id' => $importId,
    ]);
    // Узкий диапазон внутри — Москва (82). Должен выиграть (ORDER BY width ASC).
    seedPhoneRange([
        'def_code' => 495, 'from_num' => 2000000, 'to_num' => 2009999,
        'operator' => 'МГТС', 'region' => 'Москва',
        'subject_code' => 82, 'import_id' => $importId,
    ]);

    $rec = app(RossvyazPrefixLookup::class)->find('74952005000');

    expect($rec)->not->toBeNull()
        ->and($rec->subjectCode)->toBe(82)
        ->and($rec->region)->toBe('Москва');
});

it('returns null for unknown prefix', function (): void {
    seedPhoneRange(); // только def_code=921

    expect(app(RossvyazPrefixLookup::class)->find('79991234567'))->toBeNull();
});

it('returns null when subscriber number is outside any range', function (): void {
    seedPhoneRange(['def_code' => 921, 'from_num' => 5550000, 'to_num' => 5559999]);

    // def_code совпадает (921), но subscriber 4440000 вне [5550000, 5559999]
    expect(app(RossvyazPrefixLookup::class)->find('79214440000'))->toBeNull();
});

it('returns null for malformed phone', function (): void {
    seedPhoneRange();

    expect(app(RossvyazPrefixLookup::class)->find('123'))->toBeNull();
});
