<?php

use App\Filament\Resources\BackupSetResource;
use App\Filament\Resources\BackupSetResource\Pages\CreateBackupSet;
use App\Filament\Resources\BackupSetResource\Pages\ListBackupSets;
use App\Filament\Resources\PolicyResource\Pages\ListPolicies;
use App\Filament\Resources\RestoreRunResource\Pages\CreateRestoreRun;
use App\Filament\Resources\RestoreRunResource\Pages\ListRestoreRuns;
use App\Models\BackupSet;
use App\Models\OperationRun;
use App\Models\Policy;
use App\Models\RestoreRun;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

test('readonly users cannot archive backup sets', function () {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');

    setAdminPanelContext($tenant);

    $set = BackupSet::create([
        'managed_environment_id' => $tenant->id,
        'name' => 'Backup 1',
        'status' => 'completed',
        'item_count' => 0,
    ]);

    Livewire::actingAs($user)
        ->test(ListBackupSets::class)
        ->assertTableActionDisabled('archive', $set)
        ->callTableAction('archive', $set);

    expect(BackupSet::withTrashed()->find($set->id)?->trashed())->toBeFalse();
});

test('readonly users cannot create backup sets', function () {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');

    setAdminPanelContext($tenant);

    $this->actingAs($user)
        ->get(BackupSetResource::getUrl('create', tenant: $tenant))
        ->assertForbidden();

    Livewire::actingAs($user)
        ->test(CreateBackupSet::class)
        ->assertStatus(403);
});

test('readonly users cannot export policies to backup', function () {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');

    setAdminPanelContext($tenant);

    $policy = Policy::factory()->create([
        'managed_environment_id' => $tenant->id,
        'ignored_at' => null,
    ]);

    Livewire::actingAs($user)
        ->test(ListPolicies::class)
        ->assertTableActionDisabled('export', $policy)
        ->callTableAction('export', $policy, data: [
            'backup_name' => 'Readonly Export',
        ]);

    expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->where('type', 'policy.export')->exists())->toBeFalse();
});

test('operator users cannot access the restore run wizard (create)', function () {
    [$user, $tenant] = createUserWithTenant(role: 'operator');

    setAdminPanelContext($tenant);

    Livewire::actingAs($user)
        ->test(CreateRestoreRun::class)
        ->assertStatus(403);
});

test('readonly users cannot force delete restore runs', function () {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');

    setAdminPanelContext($tenant);

    $set = BackupSet::create([
        'managed_environment_id' => $tenant->id,
        'name' => 'Backup for Restore Run',
        'status' => 'completed',
        'item_count' => 0,
    ]);

    $run = RestoreRun::create([
        'managed_environment_id' => $tenant->id,
        'backup_set_id' => $set->id,
        'status' => 'completed',
        'is_dry_run' => true,
        'requested_by' => 'tester@example.com',
    ]);

    $run->delete();

    Livewire::actingAs($user)
        ->test(ListRestoreRuns::class)
        ->assertTableActionDisabled('forceDelete', $run)
        ->callTableAction('forceDelete', $run);

    expect(RestoreRun::withTrashed()->find($run->id))->not->toBeNull();
});
