<?php

declare(strict_types=1);

use App\Filament\Resources\StoredReportResource;
use App\Filament\Resources\StoredReportResource\Pages\ListStoredReports;
use App\Models\StoredReport;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Livewire\Livewire;

uses(RefreshDatabase::class);

function storedReportResourcePermissionReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport
{
    return StoredReport::factory()
        ->permissionPosture($payload)
        ->create(array_merge([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'fingerprint' => hash('sha256', 'permission-'.$tenant->getKey().'-'.microtime(true)),
        ], $attributes));
}

function storedReportResourceEntraReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport
{
    return StoredReport::factory()
        ->entraAdminRoles($payload)
        ->create(array_merge([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'fingerprint' => hash('sha256', 'entra-'.$tenant->getKey().'-'.microtime(true)),
        ], $attributes));
}

it('renders the tenant stored-reports register and keeps global search disabled', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $this->actingAs($user)
        ->get(StoredReportResource::getUrl('index', tenant: $tenant, panel: 'admin'))
        ->assertOk()
        ->assertSee('Stored reports');

    $reflection = new ReflectionClass(StoredReportResource::class);

    expect($reflection->getStaticPropertyValue('isGloballySearchable'))->toBeFalse()
        ->and(array_keys(StoredReportResource::getPages()))->toContain('view');
});

it('lists only current supported tenant reports by default and can reveal history', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $otherTenant = ManagedEnvironment::factory()->create();

    $historical = storedReportResourceEntraReport($tenant, [], [
        'created_at' => now()->subDays(2),
        'updated_at' => now()->subDays(2),
        'fingerprint' => 'entra-old',
    ]);
    $current = storedReportResourceEntraReport($tenant, [], [
        'created_at' => now()->subDay(),
        'updated_at' => now()->subDay(),
        'fingerprint' => 'entra-current',
        'previous_fingerprint' => 'entra-old',
    ]);
    $permission = storedReportResourcePermissionReport($tenant, [
        'posture_score' => 92,
        'required_count' => 10,
        'granted_count' => 9,
    ]);
    $wrongWorkspace = Workspace::factory()->create();
    $wrongWorkspaceReportId = DB::table('stored_reports')->insertGetId([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $wrongWorkspace->getKey(),
        'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE,
        'payload' => json_encode([
            'posture_score' => 1,
            'required_count' => 1,
            'granted_count' => 0,
        ], JSON_THROW_ON_ERROR),
        'fingerprint' => 'permission-wrong-workspace',
        'created_at' => now()->addMinute(),
        'updated_at' => now()->addMinute(),
    ]);
    $wrongWorkspaceReport = StoredReport::query()->findOrFail($wrongWorkspaceReportId);

    storedReportResourcePermissionReport($otherTenant);
    StoredReport::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'report_type' => 'future.report',
        'payload' => ['name' => 'Unexpected'],
    ]);

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

    Livewire::test(ListStoredReports::class)
        ->assertCanSeeTableRecords([$current, $permission])
        ->assertCanNotSeeTableRecords([$historical, $wrongWorkspaceReport])
        ->assertSee('Entra admin roles report')
        ->assertSee('Permission posture report')
        ->searchTable('Permission posture')
        ->assertCanSeeTableRecords([$permission])
        ->assertCanNotSeeTableRecords([$current]);

    Livewire::test(ListStoredReports::class)
        ->filterTable('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES)
        ->assertCanSeeTableRecords([$current])
        ->assertCanNotSeeTableRecords([$permission])
        ->filterTable('history', 'all')
        ->assertCanSeeTableRecords([$historical, $current]);
});

it('uses clickable rows without row or bulk mutation actions', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $report = storedReportResourcePermissionReport($tenant);

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

    $component = Livewire::test(ListStoredReports::class)
        ->assertCanSeeTableRecords([$report]);

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

    expect($table->getActions())->toBeEmpty()
        ->and($table->getBulkActions())->toBeEmpty()
        ->and($table->getRecordUrl($report))->toBe(StoredReportResource::getUrl('view', ['record' => $report]));
});

it('shows an honest empty state that points back to the tenant overview', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

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

    Livewire::test(ListStoredReports::class)
        ->assertSee('No stored reports yet')
        ->assertSee('Stored reports appear here after their origin surfaces create retained report records.')
        ->assertTableEmptyStateActionsExistInOrder(['open_tenant_overview']);
});
