<?php

$_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'] ?? '/';

app_require('routes/birdVoiceWebhooksRoute.php');

final class BirdVoiceWebhookRouteTestDouble extends \routes\birdVoiceWebhooksRoute
{
    public array $departmentNames = [];
    public array $rawState = [];
    public array $ttls = [];

    public function mapDepartments(array $ids): array
    {
        return $this->buildDepartmentOptionMap($ids);
    }

    public function departmentPrompt(array $map): string
    {
        return $this->buildDepartmentPromptText($map);
    }

    public function gatePrompt(string $name): string
    {
        return $this->buildGateTypePromptText($name);
    }

    public function selectDepartment(array $map, string $digit): ?int
    {
        return $this->resolveDepartmentIdByDigit($map, $digit);
    }

    public function selectGateType(string $digit): ?string
    {
        return $this->resolveGateTypeByDigit($digit);
    }

    public function storeState(string $callId, array $state): void
    {
        $this->saveIvrState($callId, $state);
    }

    public function loadState(string $callId): ?array
    {
        return $this->readIvrState($callId);
    }

    public function removeState(string $callId): void
    {
        $this->clearIvrState($callId);
    }

    public function stateForCaller(array $state, int $countryCode, int $phone): bool
    {
        return $this->isStateForCaller($state, $countryCode, $phone);
    }

    public function stateKey(string $callId): string
    {
        return $this->ivrStateKey($callId);
    }

    protected function getDepartmentNameById(int $departmentId): string
    {
        return $this->departmentNames[$departmentId] ?? ('Afdeling ' . $departmentId);
    }

    protected function writeIvrStateRaw(string $key, string $value, int $ttlSeconds): void
    {
        $this->rawState[$key] = $value;
        $this->ttls[$key] = $ttlSeconds;
    }

    protected function readIvrStateRaw(string $key): ?string
    {
        return $this->rawState[$key] ?? null;
    }

    protected function deleteIvrStateRaw(string $key): void
    {
        unset($this->rawState[$key], $this->ttls[$key]);
    }
}

it('builds deterministic department digit map and caps to 9 options', function (): void {
    $route = new BirdVoiceWebhookRouteTestDouble();
    $route->departmentNames = [11 => 'Nord', 22 => 'Syd', 33 => 'Vest'];

    $map = $route->mapDepartments([11, 22, 0, -5, 33, 44, 55, 66, 77, 88, 99]);

    expect($map)->toHaveCount(9);
    expect(array_keys($map))->toBe(['1', '2', '3', '4', '5', '6', '7', '8', '9']);
    expect($map['1']['department_id'])->toBe(11);
    expect($map['2']['department_id'])->toBe(22);
    expect($map['3']['department_id'])->toBe(33);
    expect($map['1']['department_name'])->toBe('Nord');
    expect($map['2']['department_name'])->toBe('Syd');
    expect($map['3']['department_name'])->toBe('Vest');
});

it('resolves department ids by selected digit', function (): void {
    $route = new BirdVoiceWebhookRouteTestDouble();
    $map = [
        '1' => ['department_id' => 101, 'department_name' => 'A'],
        '2' => ['department_id' => 202, 'department_name' => 'B'],
    ];

    expect($route->selectDepartment($map, '1'))->toBe(101);
    expect($route->selectDepartment($map, '2'))->toBe(202);
    expect($route->selectDepartment($map, '9'))->toBeNull();
    expect($route->selectDepartment($map, ''))->toBeNull();
});

it('resolves gate type digit to entrance or exit', function (): void {
    $route = new BirdVoiceWebhookRouteTestDouble();

    expect($route->selectGateType('1'))->toBe('entrance');
    expect($route->selectGateType('2'))->toBe('exit');
    expect($route->selectGateType('0'))->toBeNull();
    expect($route->selectGateType('x'))->toBeNull();
});

it('stores, loads and clears ivr state with ttl', function (): void {
    $route = new BirdVoiceWebhookRouteTestDouble();
    $callId = 'abc-123';
    $state = [
        'stage' => 'department_select',
        'department_options' => ['1' => ['department_id' => 5, 'department_name' => 'North']],
        'country_code' => 45,
        'phone' => 12345678,
    ];

    $route->storeState($callId, $state);

    $key = $route->stateKey($callId);
    expect($route->loadState($callId))->toBe($state);
    expect($route->ttls[$key] ?? null)->toBe(600);

    $route->removeState($callId);
    expect($route->loadState($callId))->toBeNull();
});

it('validates state caller fingerprint matching', function (): void {
    $route = new BirdVoiceWebhookRouteTestDouble();
    $state = ['country_code' => 45, 'phone' => 12345678];

    expect($route->stateForCaller($state, 45, 12345678))->toBeTrue();
    expect($route->stateForCaller($state, 46, 12345678))->toBeFalse();
    expect($route->stateForCaller($state, 45, 87654321))->toBeFalse();
});

it('builds department and gate prompts', function (): void {
    $route = new BirdVoiceWebhookRouteTestDouble();

    $prompt = $route->departmentPrompt([
        '1' => ['department_id' => 1, 'department_name' => 'Nord'],
        '2' => ['department_id' => 2, 'department_name' => 'Syd'],
    ]);

    expect($prompt)->toContain('Tast 1 for Nord');
    expect($prompt)->toContain('Tast 2 for Syd');

    $gatePrompt = $route->gatePrompt('Nord');
    expect($gatePrompt)->toContain('Du valgte Nord.');
    expect($gatePrompt)->toContain('Tast 1 for indgang. Tast 2 for udgang.');
});
