<?php

declare(strict_types=1);

use App\Filament\Resources\PolicyVersionResource;
use App\Filament\Resources\PolicyVersionResource\Pages\ListPolicyVersions;
use App\Models\BaselineProfile;
use App\Models\Policy;
use App\Models\PolicyVersion;
use App\Services\Auth\CapabilityResolver;
use App\Support\Auth\Capabilities;
use App\Support\Baselines\PolicyVersionCapturePurpose;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

it('hides baseline-purpose policy versions for tenant.view-only actors', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'readonly');

    $resolver = \Mockery::mock(CapabilityResolver::class);
    $resolver->shouldReceive('isMember')->andReturnTrue();
    $resolver->shouldReceive('primeMemberships')->andReturnNull();
    $resolver->shouldReceive('can')
        ->andReturnUsing(static fn ($user, $tenant, string $capability): bool => $capability === Capabilities::TENANT_VIEW);

    app()->instance(CapabilityResolver::class, $resolver);

    Filament::setTenant($tenant, true);

    $policy = Policy::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
    ]);

    $baselineProfile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    $backupVersion = PolicyVersion::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'policy_id' => (int) $policy->getKey(),
        'version_number' => 1,
        'capture_purpose' => PolicyVersionCapturePurpose::Backup->value,
    ]);

    $baselinePurposeVersion = PolicyVersion::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'policy_id' => (int) $policy->getKey(),
        'version_number' => 2,
        'capture_purpose' => PolicyVersionCapturePurpose::BaselineCompare->value,
        'baseline_profile_id' => (int) $baselineProfile->getKey(),
    ]);

    Livewire::actingAs($user)
        ->test(ListPolicyVersions::class)
        ->assertCanSeeTableRecords([$backupVersion])
        ->assertCanNotSeeTableRecords([$baselinePurposeVersion]);

    $this->actingAs($user)
        ->get(PolicyVersionResource::getUrl('view', ['record' => $baselinePurposeVersion], tenant: $tenant))
        ->assertNotFound();
});

it('shows baseline-purpose policy versions for actors with tenant.sync', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    app()->forgetInstance(CapabilityResolver::class);

    Filament::setTenant($tenant, true);

    $policy = Policy::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
    ]);

    $baselineProfile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    $backupVersion = PolicyVersion::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'policy_id' => (int) $policy->getKey(),
        'version_number' => 1,
        'capture_purpose' => PolicyVersionCapturePurpose::Backup->value,
    ]);

    $baselinePurposeVersion = PolicyVersion::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'policy_id' => (int) $policy->getKey(),
        'version_number' => 2,
        'capture_purpose' => PolicyVersionCapturePurpose::BaselineCapture->value,
        'baseline_profile_id' => (int) $baselineProfile->getKey(),
    ]);

    Livewire::actingAs($user)
        ->test(ListPolicyVersions::class)
        ->assertCanSeeTableRecords([$backupVersion, $baselinePurposeVersion]);

    $this->actingAs($user)
        ->get(PolicyVersionResource::getUrl('view', ['record' => $baselinePurposeVersion], tenant: $tenant))
        ->assertOk()
        ->assertSee('Related context')
        ->assertSee('Baseline profile');
});
