<?php

use App\Filament\Resources\PolicyResource;
use App\Filament\Resources\PolicyResource\Pages\ListPolicies;
use App\Models\ManagedEnvironment;
use App\Models\Policy;
use App\Models\User;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Support\Facades\App;
use Livewire\Livewire;

uses(\Illuminate\Foundation\Testing\RefreshDatabase::class);

test('policies are listed for the active tenant', function () {
    $tenant = ManagedEnvironment::factory()->create();

    Policy::create([
        'managed_environment_id' => $tenant->id,
        'external_id' => 'policy-1',
        'policy_type' => 'deviceConfiguration',
        'display_name' => 'Policy A',
        'platform' => 'windows',
        'last_synced_at' => now(),
    ]);

    $otherTenant = ManagedEnvironment::factory()->create();

    Policy::create([
        'managed_environment_id' => $otherTenant->id,
        'external_id' => 'policy-2',
        'policy_type' => 'deviceConfiguration',
        'display_name' => 'Policy B',
        'platform' => 'windows',
        'last_synced_at' => now(),
    ]);

    $user = User::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, user: $user, role: 'owner');
    $user->tenants()->syncWithoutDetaching([
        $otherTenant->getKey() => ['role' => 'owner'],
    ]);

    $this->actingAs($user)
        ->withSession([
            WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
            WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
                (string) $tenant->workspace_id => (int) $tenant->getKey(),
            ],
        ])
        ->get(PolicyResource::getUrl(panel: 'admin', tenant: $tenant))
        ->assertOk()
        ->assertSee('Policy A')
        ->assertDontSee('Policy B');
});

test('policy list keeps the standard table defaults and persists state in-session', function () {
    App::setLocale('en');

    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $this->actingAs($user);
    setAdminPanelContext($tenant);

    $component = Livewire::actingAs($user)
        ->test(ListPolicies::class)
        ->assertTableEmptyStateActionsExistInOrder(['sync'])
        ->searchTable('Policy')
        ->call('sortTable', 'display_name', 'desc')
        ->set('tableFilters.visibility.value', 'active');

    $table = $component->instance()->getTable();

    expect($table->getPaginationPageOptions())->toBe(\App\Support\Filament\TablePaginationProfiles::resource());
    expect($table->getEmptyStateHeading())->toBe(__('localization.policy.resource.empty_state_heading'));
    expect($table->getColumn('display_name')?->isSearchable())->toBeTrue();
    expect($table->getColumn('display_name')?->isSortable())->toBeTrue();
    expect($table->getColumn('external_id')?->isToggledHiddenByDefault())->toBeTrue();
    expect(count($table->getVisibleColumns()))->toBeLessThanOrEqual(7);
    expect(session()->get($component->instance()->getTableSearchSessionKey()))->toBe('Policy');
    expect(session()->get($component->instance()->getTableSortSessionKey()))->toBe('display_name:desc');

    Livewire::actingAs($user)
        ->test(ListPolicies::class)
        ->assertSet('tableSearch', 'Policy')
        ->assertSet('tableSort', 'display_name:desc')
        ->assertSet('tableFilters.visibility.value', 'active');
});
