<?php

declare(strict_types=1);

use App\Filament\Pages\Settings\WorkspaceSettings;
use App\Models\AuditLog;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Models\WorkspaceSetting;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Testing\TestAction;
use Livewire\Livewire;

it('allows view-only members to view workspace settings but forbids save and per-setting reset mutations', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'readonly',
    ]);

    WorkspaceSetting::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'domain' => 'backup',
        'key' => 'retention_keep_last_default',
        'value' => 27,
        'updated_by_user_id' => null,
    ]);

    WorkspaceSetting::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'domain' => 'ai',
        'key' => 'policy_mode',
        'value' => 'private_only',
        'updated_by_user_id' => null,
    ]);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());

    $this->actingAs($user)
        ->get(WorkspaceSettings::getUrl(panel: 'admin'))
        ->assertSuccessful();

    Livewire::actingAs($user)
        ->test(WorkspaceSettings::class)
        ->assertSet('data.ai_policy_mode', 'private_only')
        ->assertSet('data.backup_retention_keep_last_default', 27)
        ->assertSet('data.backup_retention_min_floor', null)
        ->assertSet('data.drift_severity_mapping', [])
        ->assertSet('data.baseline_severity_missing_policy', null)
        ->assertSet('data.baseline_severity_different_version', null)
        ->assertSet('data.baseline_severity_unexpected_policy', null)
        ->assertSet('data.baseline_alert_min_severity', null)
        ->assertSet('data.baseline_auto_close_enabled', null)
        ->assertSet('data.findings_sla_critical', null)
        ->assertSet('data.findings_sla_high', null)
        ->assertSet('data.findings_sla_medium', null)
        ->assertSet('data.findings_sla_low', null)
        ->assertSet('data.operations_operation_run_retention_days', null)
        ->assertSet('data.operations_stuck_run_threshold_minutes', null)
        ->assertActionVisible('save')
        ->assertActionDisabled('save')
        ->assertFormComponentActionVisible('backup_retention_keep_last_default', 'reset_backup_retention_keep_last_default', [], 'content')
        ->assertFormComponentActionDisabled('backup_retention_keep_last_default', 'reset_backup_retention_keep_last_default', [], 'content')
        ->assertFormComponentActionVisible('ai_policy_mode', 'reset_ai_policy_mode', [], 'content')
        ->assertFormComponentActionDisabled('ai_policy_mode', 'reset_ai_policy_mode', [], 'content')
        ->assertFormComponentActionVisible('backup_retention_min_floor', 'reset_backup_retention_min_floor', [], 'content')
        ->assertFormComponentActionDisabled('backup_retention_min_floor', 'reset_backup_retention_min_floor', [], 'content')
        ->assertFormComponentActionVisible('drift_severity_mapping', 'reset_drift_severity_mapping', [], 'content')
        ->assertFormComponentActionDisabled('drift_severity_mapping', 'reset_drift_severity_mapping', [], 'content')
        ->assertActionVisible(TestAction::make('reset_baseline_severity_mapping')->schemaComponent('baseline_section'))
        ->assertActionDisabled(TestAction::make('reset_baseline_severity_mapping')->schemaComponent('baseline_section'))
        ->assertActionVisible(TestAction::make('reset_baseline_alert_min_severity')->schemaComponent('baseline_section'))
        ->assertActionDisabled(TestAction::make('reset_baseline_alert_min_severity')->schemaComponent('baseline_section'))
        ->assertActionVisible(TestAction::make('reset_baseline_auto_close_enabled')->schemaComponent('baseline_section'))
        ->assertActionDisabled(TestAction::make('reset_baseline_auto_close_enabled')->schemaComponent('baseline_section'))
        ->assertActionVisible(TestAction::make('reset_findings_sla_days')->schemaComponent('findings_section'))
        ->assertActionDisabled(TestAction::make('reset_findings_sla_days')->schemaComponent('findings_section'))
        ->assertFormComponentActionVisible('operations_operation_run_retention_days', 'reset_operations_operation_run_retention_days', [], 'content')
        ->assertFormComponentActionDisabled('operations_operation_run_retention_days', 'reset_operations_operation_run_retention_days', [], 'content')
        ->assertFormComponentActionVisible('operations_stuck_run_threshold_minutes', 'reset_operations_stuck_run_threshold_minutes', [], 'content')
        ->assertFormComponentActionDisabled('operations_stuck_run_threshold_minutes', 'reset_operations_stuck_run_threshold_minutes', [], 'content')
        ->call('save')
        ->assertStatus(403);

    Livewire::actingAs($user)
        ->test(WorkspaceSettings::class)
        ->call('resetSetting', 'ai_policy_mode')
        ->assertStatus(403);

    Livewire::actingAs($user)
        ->test(WorkspaceSettings::class)
        ->call('resetSetting', 'backup_retention_keep_last_default')
        ->assertStatus(403);

    expect(AuditLog::query()->count())->toBe(0);

    $setting = WorkspaceSetting::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('domain', 'backup')
        ->where('key', 'retention_keep_last_default')
        ->first();

    $aiSetting = WorkspaceSetting::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('domain', 'ai')
        ->where('key', 'policy_mode')
        ->first();

    expect($setting)->not->toBeNull()
        ->and($aiSetting)->not->toBeNull();
});
