<?php

use App\Filament\Pages\TablesExplorer;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use Livewire\Livewire;

beforeEach(function () {
    config([
        'logistics.base_url' => 'http://test-server.local',
        'logistics.api_key' => 'test-api-key',
        'logistics.folder' => 'testfolder',
        'logistics.timeout' => 30,
        'logistics.connect_timeout' => 10,
        'logistics.retry.times' => 1,
        'logistics.retry.sleep_ms' => 0,
    ]);

    $this->actingAs(User::factory()->create());
});

it('loads the tables list on mount', function () {
    Http::fake([
        '*/tables_list' => Http::response([
            'data' => [
                ['name' => 'art', 'columnCount' => 160],
                ['name' => 'cust', 'columnCount' => 216],
            ],
            'metadata' => ['tableCount' => 2, 'folderType' => 'DBF', 'endpoint' => 'test'],
            'error' => null,
        ]),
    ]);

    Livewire::test(TablesExplorer::class)
        ->assertSet('tables', [
            ['name' => 'art', 'columnCount' => 160],
            ['name' => 'cust', 'columnCount' => 216],
        ])
        ->assertSee('art')
        ->assertSee('cust')
        ->assertSee('160')
        ->assertSee('216');
});

it('loads columns when a table is selected', function () {
    Http::fake([
        '*/tables_list' => Http::response([
            'data' => [['name' => 'stk', 'columnCount' => 10]],
            'metadata' => ['tableCount' => 1],
            'error' => null,
        ]),
        '*/column_list/stk' => Http::response([
            'data' => [
                ['name' => 'ARTID', 'dataType' => 'C', 'length' => 20, 'precision' => 0],
                ['name' => 'ARTID', 'dataType' => 'C', 'length' => 20, 'precision' => 0],
                ['name' => 'STOCK', 'dataType' => 'N', 'length' => 10, 'precision' => 2],
                ['name' => 'STOCK', 'dataType' => 'N', 'length' => 10, 'precision' => 2],
            ],
            'metadata' => ['columnCount' => 4, 'tableName' => 'stk'],
            'error' => null,
        ]),
    ]);

    Livewire::test(TablesExplorer::class)
        ->call('selectTable', 'stk')
        ->assertSet('selectedTable', 'stk')
        ->assertSee('ARTID')
        ->assertSee('STOCK')
        ->assertSee('Caractère')
        ->assertSee('Numérique');
});

it('deduplicates columns from the API response', function () {
    Http::fake([
        '*/tables_list' => Http::response([
            'data' => [['name' => 'stk', 'columnCount' => 4]],
            'metadata' => ['tableCount' => 1],
            'error' => null,
        ]),
        '*/column_list/stk' => Http::response([
            'data' => [
                ['name' => 'ARTID', 'dataType' => 'C', 'length' => 20, 'precision' => 0],
                ['name' => 'ARTID', 'dataType' => 'C', 'length' => 20, 'precision' => 0],
                ['name' => 'STOCK', 'dataType' => 'N', 'length' => 10, 'precision' => 2],
                ['name' => 'STOCK', 'dataType' => 'N', 'length' => 10, 'precision' => 2],
            ],
            'metadata' => ['columnCount' => 4],
            'error' => null,
        ]),
    ]);

    Livewire::test(TablesExplorer::class)
        ->call('selectTable', 'stk')
        ->assertSet('columns', [
            ['name' => 'ARTID', 'dataType' => 'C', 'length' => 20, 'precision' => 0],
            ['name' => 'STOCK', 'dataType' => 'N', 'length' => 10, 'precision' => 2],
        ]);
});

it('filters tables by name', function () {
    Http::fake([
        '*/tables_list' => Http::response([
            'data' => [
                ['name' => 'art', 'columnCount' => 160],
                ['name' => 'attach', 'columnCount' => 13],
                ['name' => 'cust', 'columnCount' => 216],
                ['name' => 'dochead', 'columnCount' => 212],
                ['name' => 'docdet', 'columnCount' => 82],
                ['name' => 'docpay', 'columnCount' => 22],
                ['name' => 'stk', 'columnCount' => 20],
            ],
            'metadata' => ['tableCount' => 7],
            'error' => null,
        ]),
    ]);

    $component = Livewire::test(TablesExplorer::class)
        ->set('tableFilter', 'doc');

    $filteredTables = $component->get('filteredTables');

    expect($filteredTables)->toHaveCount(3)
        ->and(array_column($filteredTables, 'name'))->toBe(['dochead', 'docdet', 'docpay']);
});

it('displays an error message when the API fails', function () {
    Http::fake([
        '*/tables_list' => Http::response([
            'data' => [],
            'metadata' => [],
            'error' => 'Invalid API key',
        ]),
    ]);

    Livewire::test(TablesExplorer::class)
        ->assertSee('Invalid API key');
});

it('shows data type labels correctly', function () {
    expect(TablesExplorer::getDataTypeLabel('C'))->toBe('Caractère')
        ->and(TablesExplorer::getDataTypeLabel('N'))->toBe('Numérique')
        ->and(TablesExplorer::getDataTypeLabel('T'))->toBe('Date/Heure')
        ->and(TablesExplorer::getDataTypeLabel('D'))->toBe('Date')
        ->and(TablesExplorer::getDataTypeLabel('L'))->toBe('Logique')
        ->and(TablesExplorer::getDataTypeLabel('M'))->toBe('Mémo')
        ->and(TablesExplorer::getDataTypeLabel('X'))->toBe('X');
});
