<?php

declare(strict_types=1);

use App\Filament\Pages\EnvironmentRequiredPermissions;
use App\Models\ManagedEnvironment;
use App\Models\ManagedEnvironmentPermission;
use App\Models\User;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

function seedEnvironmentRequiredPermissionsFixture(ManagedEnvironment $tenant): void
{
    config()->set('intune_permissions.permissions', [
        [
            'key' => 'DeviceManagementApps.Read.All',
            'type' => 'application',
            'description' => 'Backup application permission',
            'features' => ['backup'],
        ],
        [
            'key' => 'Group.Read.All',
            'type' => 'delegated',
            'description' => 'Backup delegated permission',
            'features' => ['backup'],
        ],
        [
            'key' => 'Reports.Read.All',
            'type' => 'application',
            'description' => 'Reporting permission',
            'features' => ['reporting'],
        ],
    ]);
    config()->set('entra_permissions.permissions', []);

    ManagedEnvironmentPermission::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'permission_key' => 'Group.Read.All',
        'status' => 'missing',
        'details' => ['source' => 'fixture'],
        'last_checked_at' => now(),
    ]);

    ManagedEnvironmentPermission::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'permission_key' => 'Reports.Read.All',
        'status' => 'granted',
        'details' => ['source' => 'fixture'],
        'last_checked_at' => now(),
    ]);
}

function tenantRequiredPermissionsComponent(User $user, ManagedEnvironment $tenant, array $query = [])
{
    test()->actingAs($user);
    setAdminPanelContext();
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    $query = array_merge([
        'tenant' => (string) $tenant->external_id,
    ], $query);

    return Livewire::withQueryParams($query)->test(EnvironmentRequiredPermissions::class);
}

it('uses native table filters and search while keeping summary state aligned with visible rows', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');
    seedEnvironmentRequiredPermissionsFixture($tenant);

    $component = tenantRequiredPermissionsComponent($user, $tenant)
        ->assertTableFilterExists('status')
        ->assertTableFilterExists('type')
        ->assertTableFilterExists('features')
        ->assertCanSeeTableRecords([
            'DeviceManagementApps.Read.All',
            'Group.Read.All',
        ])
        ->assertCanNotSeeTableRecords(['Reports.Read.All'])
        ->assertSee('Missing application permissions')
        ->assertSee('Guidance');

    $component
        ->filterTable('status', 'present')
        ->filterTable('type', 'application')
        ->searchTable('Reports')
        ->assertCountTableRecords(1)
        ->assertCanSeeTableRecords(['Reports.Read.All'])
        ->assertCanNotSeeTableRecords([
            'DeviceManagementApps.Read.All',
            'Group.Read.All',
        ]);

    $viewModel = $component->instance()->viewModel();

    expect($viewModel['overview']['counts'])->toBe([
        'missing_application' => 0,
        'missing_delegated' => 0,
        'present' => 1,
        'error' => 0,
    ])
        ->and(array_column($viewModel['permissions'], 'key'))->toBe(['Reports.Read.All'])
        ->and($viewModel['copy']['application'])->toBe('DeviceManagementApps.Read.All');
});

it('keeps copy payloads feature-scoped and shows the native no-matches state', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');
    seedEnvironmentRequiredPermissionsFixture($tenant);

    $component = tenantRequiredPermissionsComponent($user, $tenant)
        ->set('tableFilters.features.values', ['backup'])
        ->assertSet('tableFilters.features.values', ['backup']);

    $viewModel = $component->instance()->viewModel();

    expect($viewModel['copy']['application'])->toBe('DeviceManagementApps.Read.All')
        ->and($viewModel['copy']['delegated'])->toBe('Group.Read.All');

    $component
        ->searchTable('no-such-permission')
        ->assertCountTableRecords(0)
        ->assertSee('No matches')
        ->assertTableEmptyStateActionsExistInOrder(['clear_filters']);
});
