<?php

declare(strict_types=1);

use App\Filament\Resources\BaselineProfileResource;
use App\Filament\Resources\BaselineProfileResource\Pages\ViewBaselineProfile;
use App\Jobs\CaptureBaselineSnapshotJob;
use App\Models\BaselineProfile;
use App\Models\OperationRun;
use App\Support\Baselines\BaselineCaptureMode;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Livewire\Livewire;

uses(RefreshDatabase::class);

it('redirects unauthenticated users (302) when accessing the capture start surface', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

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

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    $this->get(BaselineProfileResource::getUrl('view', ['record' => $profile], panel: 'admin'))
        ->assertStatus(302);
});

it('returns 404 for authenticated users accessing a baseline profile from another workspace', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    [$otherUser, $otherTenant] = createUserWithTenant(role: 'owner');

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

    session()->put(WorkspaceContext::SESSION_KEY, (int) $otherTenant->workspace_id);

    $this->actingAs($otherUser)
        ->get(BaselineProfileResource::getUrl('view', ['record' => $profile], panel: 'admin'))
        ->assertNotFound();
});

it('does not start capture for workspace members missing workspace_baselines.manage', function (): void {
    Queue::fake();

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

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

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    Livewire::actingAs($user)
        ->test(ViewBaselineProfile::class, ['record' => $profile->getKey()])
        ->assertActionVisible('capture')
        ->assertActionHasLabel('capture', 'Capture baseline')
        ->assertActionDisabled('capture')
        ->callAction('capture', data: ['source_tenant_id' => (int) $tenant->getKey()])
        ->assertStatus(200);

    Queue::assertNotPushed(CaptureBaselineSnapshotJob::class);
});

it('starts capture successfully for authorized workspace members', function (): void {
    Queue::fake();
    config()->set('tenantpilot.baselines.full_content_capture.enabled', true);

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

    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'capture_mode' => BaselineCaptureMode::FullContent->value,
    ]);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    Livewire::actingAs($user)
        ->test(ViewBaselineProfile::class, ['record' => $profile->getKey()])
        ->assertActionVisible('capture')
        ->assertActionHasLabel('capture', 'Capture baseline (full content)')
        ->assertActionEnabled('capture')
        ->callAction('capture', data: ['source_tenant_id' => (int) $tenant->getKey()])
        ->assertStatus(200);

    Queue::assertPushed(CaptureBaselineSnapshotJob::class);

    $run = OperationRun::query()
        ->where('tenant_id', (int) $tenant->getKey())
        ->where('type', 'baseline_capture')
        ->latest('id')
        ->first();

    expect($run)->not->toBeNull();
    expect($run?->status)->toBe('queued');
});

it('does not start full-content capture when rollout is disabled', function (): void {
    Queue::fake();
    config()->set('tenantpilot.baselines.full_content_capture.enabled', false);

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

    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'capture_mode' => BaselineCaptureMode::FullContent->value,
    ]);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    Livewire::actingAs($user)
        ->test(ViewBaselineProfile::class, ['record' => $profile->getKey()])
        ->assertActionVisible('capture')
        ->assertActionHasLabel('capture', 'Capture baseline (full content)')
        ->assertActionEnabled('capture')
        ->callAction('capture', data: ['source_tenant_id' => (int) $tenant->getKey()])
        ->assertNotified('Cannot start capture')
        ->assertStatus(200);

    Queue::assertNotPushed(CaptureBaselineSnapshotJob::class);
    expect(OperationRun::query()->where('type', 'baseline_capture')->count())->toBe(0);
});
