<?php

declare(strict_types=1);

use App\Filament\Pages\InventoryCoverage;
use App\Filament\Resources\EntraGroupResource\Pages\ListEntraGroups;
use App\Filament\Resources\FindingResource;
use App\Filament\System\Pages\Directory\Workspaces;
use App\Filament\Widgets\Dashboard\RecentDriftFindings;
use App\Filament\Widgets\Dashboard\RecentOperations;
use App\Livewire\EntraGroupCachePickerTable;
use App\Livewire\SettingsCatalogSettingsTable;
use App\Models\EntraGroup;
use App\Models\Finding;
use App\Models\OperationRun;
use App\Models\PlatformUser;
use App\Models\Workspace;
use App\Support\Auth\PlatformCapabilities;
use App\Support\Filament\TablePaginationProfiles;
use App\Support\OperationRunLinks;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use Filament\Facades\Filament;
use Filament\Tables\Table;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Features\SupportTesting\Testable;
use Livewire\Livewire;

uses(RefreshDatabase::class);

function spec125DetailTable(Testable $component): Table
{
    return $component->instance()->getTable();
}

/**
 * @return array{0: \App\Models\User, 1: \App\Models\ManagedEnvironment}
 */
function spec125DetailTenantContext(): array
{
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    test()->actingAs($user);
    $tenant->makeCurrent();
    Filament::setTenant($tenant, true);

    return [$user, $tenant];
}

function spec125DetailPlatformContext(): PlatformUser
{
    $platformUser = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::DIRECTORY_VIEW,
        ],
        'is_active' => true,
    ]);

    test()->actingAs($platformUser, 'platform');

    return $platformUser;
}

it('keeps broad resource tables searchable on primary identifiers while hiding technical IDs by default', function (): void {
    [$user, $tenant] = spec125DetailTenantContext();

    $group = EntraGroup::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_id' => '00000000-0000-0000-0000-1234567890ab',
        'display_name' => 'Alpha Security Group',
        'group_types' => null,
        'security_enabled' => true,
        'mail_enabled' => false,
        'last_seen_at' => now(),
    ]);

    $component = Livewire::actingAs($user)->test(ListEntraGroups::class)
        ->searchTable('Alpha')
        ->assertCanSeeTableRecords([$group]);

    $table = spec125DetailTable($component);

    expect($table->getDefaultSortColumn())->toBe('display_name');
    expect($table->getDefaultSortDirection())->toBe('asc');
    expect($table->getPaginationPageOptions())->toBe(TablePaginationProfiles::resource());
    expect($table->getEmptyStateHeading())->toBe('No groups cached yet');
    expect($table->getColumn('display_name')?->isSearchable())->toBeTrue();
    expect($table->getColumn('display_name')?->isSortable())->toBeTrue();
    expect($table->getColumn('entra_id')?->isToggleable())->toBeTrue();
    expect($table->getColumn('entra_id')?->isToggledHiddenByDefault())->toBeTrue();
    expect(array_keys($table->getVisibleColumns()))->not->toContain('entra_id');
});

it('keeps query-risk system pages explicit about what can and cannot be searched or sorted', function (): void {
    spec125DetailPlatformContext();

    Workspace::factory()->create([
        'name' => 'Alpha Workspace',
    ]);

    $component = Livewire::test(Workspaces::class);
    $table = spec125DetailTable($component);

    expect($table->getDefaultSortColumn())->toBe('name');
    expect($table->getDefaultSortDirection())->toBe('asc');
    expect($table->getPaginationPageOptions())->toBe(TablePaginationProfiles::customPage());
    expect($table->getEmptyStateHeading())->toBe('No workspaces found');
    expect($table->getColumn('name')?->isSearchable())->toBeTrue();
    expect($table->getColumn('health')?->isSearchable())->toBeFalse();
    expect($table->getColumn('health')?->isSortable())->toBeFalse();
    expect($table->getColumn('failed_runs_24h')?->isSearchable())->toBeFalse();
    expect($table->getColumn('failed_runs_24h')?->isSortable())->toBeFalse();
});

it('keeps custom page tables explicit about pagination profiles and revealable detail', function (): void {
    [$user] = spec125DetailTenantContext();

    $component = Livewire::actingAs($user)->test(InventoryCoverage::class)
        ->assertTableEmptyStateActionsExistInOrder(['clear_filters'])
        ->searchTable('Scope Tag');

    $table = spec125DetailTable($component);

    expect($table->getDefaultSortColumn())->toBe('follow_up_priority');
    expect($table->getDefaultSortDirection())->toBe('asc');
    expect($table->getPaginationPageOptions())->toBe(TablePaginationProfiles::customPage());
    expect($table->getColumn('type')?->isSortable())->toBeTrue();
    expect($table->getColumn('label')?->isSortable())->toBeTrue();
    expect($table->getColumn('category')?->isToggleable())->toBeTrue();
    expect($table->getColumn('segment')?->isToggleable())->toBeTrue();
    expect($table->getColumn('dependencies')?->isToggleable())->toBeTrue();
});

it('keeps dashboard widgets as glance surfaces instead of searchable investigative tables', function (): void {
    [$user, $tenant] = spec125DetailTenantContext();

    $operation = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::InventorySync->value,
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
    ]);

    $component = Livewire::actingAs($user)->test(RecentOperations::class);
    $table = spec125DetailTable($component);

    expect($table->getDefaultSortColumn())->toBe('created_at');
    expect($table->getDefaultSortDirection())->toBe('desc');
    expect($table->getPaginationPageOptions())->toBe(TablePaginationProfiles::widget());
    expect($table->getEmptyStateHeading())->toBe('No operations yet');
    expect($table->isSearchable())->toBeFalse();
    expect($table->getColumn('type')?->isSortable())->toBeTrue();
    expect($table->getColumn('status')?->isSortable())->toBeTrue();
    expect($table->getColumn('outcome')?->isSortable())->toBeTrue();
    expect($table->getColumn('created_at')?->isSortable())->toBeTrue();
    expect($table->getColumn('status')?->isToggleable())->toBeTrue();
    expect($table->getColumn('status')?->isToggledHiddenByDefault())->toBeTrue();
    expect($table->getRecordUrl($operation))->toBe(OperationRunLinks::view($operation, $tenant));
    expect(array_keys($table->getVisibleColumns()))->toBe([
        'short_id',
        'type',
        'outcome',
        'created_at',
    ]);
});

it('keeps recent drift findings row clicks on the canonical finding detail view', function (): void {
    [$user, $tenant] = spec125DetailTenantContext();

    $finding = Finding::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'finding_type' => Finding::FINDING_TYPE_DRIFT,
    ]);

    $component = Livewire::actingAs($user)->test(RecentDriftFindings::class);
    $table = spec125DetailTable($component);

    expect($table->getRecordUrl($finding))->toBe(
        FindingResource::getUrl('view', ['record' => $finding], tenant: $tenant)
    );
});

it('keeps picker tables workflow-local while preserving readable hidden troubleshooting detail', function (): void {
    [$user, $tenant] = spec125DetailTenantContext();

    $group = EntraGroup::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_id' => '00000000-0000-0000-0000-1234567890ab',
        'display_name' => 'Bravo Group',
        'group_types' => null,
        'security_enabled' => true,
        'mail_enabled' => false,
        'last_seen_at' => now(),
    ]);

    Livewire::actingAs($user)
        ->test(EntraGroupCachePickerTable::class, [
            'sourceGroupId' => 'source-group',
        ])
        ->assertCanSeeTableRecords([$group])
        ->assertTableColumnFormattedStateSet('entra_id', '…567890ab', $group);

    $settingsComponent = Livewire::actingAs($user)->test(SettingsCatalogSettingsTable::class, [
        'settingsRows' => [[
            '__id' => 'setting-1',
            'definition' => 'Device Lock',
            'category' => 'Security',
            'data_type' => 'Boolean',
            'value' => 'Enabled',
            'description' => 'Require a lock screen on managed devices.',
            'path' => './deviceLock',
        ]],
        'context' => 'policy',
    ]);

    $settingsTable = spec125DetailTable($settingsComponent);

    expect($settingsTable->getDefaultSortColumn())->toBe('definition');
    expect($settingsTable->getDefaultSortDirection())->toBe('asc');
    expect($settingsTable->getPaginationPageOptions())->toBe(TablePaginationProfiles::picker());
    expect($settingsTable->getColumn('definition')?->isSearchable())->toBeTrue();
    expect($settingsTable->getColumn('definition')?->isSortable())->toBeTrue();
    expect($settingsTable->getColumn('description')?->isToggleable())->toBeTrue();
    expect($settingsTable->getColumn('description')?->isToggledHiddenByDefault())->toBeTrue();
    expect($settingsTable->getColumn('path')?->isToggleable())->toBeTrue();
    expect($settingsTable->getColumn('path')?->isToggledHiddenByDefault())->toBeTrue();
});
