<?php

declare(strict_types=1);

use App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard;
use App\Models\AuditLog;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\ManagedEnvironment;
use App\Models\ManagedEnvironmentPermission;
use App\Models\ManagedEnvironmentOnboardingSession;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Support\Audit\AuditActionId;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\Providers\ProviderConsentStatus;
use App\Support\Providers\ProviderReasonCodes;
use App\Support\Providers\ProviderConnectionType;
use App\Support\Verification\VerificationReportWriter;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Testing\TestAction;
use Livewire\Livewire;

function managedReadinessPermissionKeys(): array
{
    $configured = array_merge(
        config('intune_permissions.permissions', []),
        config('entra_permissions.permissions', []),
    );

    return array_values(array_filter(array_map(static function (mixed $permission): ?string {
        if (! is_array($permission)) {
            return null;
        }

        $key = $permission['key'] ?? null;

        return is_string($key) && trim($key) !== '' ? trim($key) : null;
    }, $configured)));
}

function seedManagedReadinessPermissions(ManagedEnvironment $tenant, ?int $staleDays = null, ?string $missingKey = null): ?string
{
    $keys = managedReadinessPermissionKeys();
    $missingKey ??= $keys[0] ?? null;

    foreach ($keys as $key) {
        if ($missingKey !== null && $key === $missingKey) {
            continue;
        }

        ManagedEnvironmentPermission::query()->create([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'permission_key' => $key,
            'status' => 'granted',
            'details' => ['source' => 'readiness-test'],
            'last_checked_at' => $staleDays === null ? now() : now()->subDays($staleDays),
        ]);
    }

    return $missingKey;
}

/**
 * @return array{0: User, 1: ManagedEnvironmentOnboardingSession, 2: ProviderConnection, 3: OperationRun|null, 4: string|null}
 */
function createManagedReadinessBlockerDraft(string $state): array
{
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenant = ManagedEnvironment::factory()->onboarding()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => fake()->uuid(),
        'name' => 'Blocker ManagedEnvironment '.str_replace('_', ' ', $state),
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connectionState = [
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'display_name' => 'Blocker connection',
        'is_default' => true,
    ];

    if ($state === 'missing_consent') {
        $connectionState['consent_status'] = ProviderConsentStatus::Required->value;
    }

    if ($state === 'revoked_consent') {
        $connectionState['consent_status'] = ProviderConsentStatus::Revoked->value;
    }

    if ($state === 'disabled_connection') {
        $connectionState['is_enabled'] = false;
        $connectionState['consent_status'] = ProviderConsentStatus::Granted->value;
    }

    $connection = ProviderConnection::factory()->platform()->create($connectionState);
    $run = null;
    $missingKey = null;

    if ($state === 'blocked_verification' || $state === 'permission_gap') {
        $connection->forceFill([
            'is_enabled' => true,
            'consent_status' => ProviderConsentStatus::Granted->value,
        ])->save();

        $missingKey = seedManagedReadinessPermissions($tenant);

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $workspace->getKey(),
            'managed_environment_id' => (int) $tenant->getKey(),
            'type' => 'provider.connection.check',
            'status' => OperationRunStatus::Completed->value,
            'outcome' => OperationRunOutcome::Blocked->value,
            'context' => [
                'provider_connection_id' => (int) $connection->getKey(),
                'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                    [
                        'key' => 'permissions.admin_consent',
                        'title' => 'Required application permissions',
                        'status' => 'fail',
                        'severity' => 'critical',
                        'blocking' => true,
                        'reason_code' => ProviderReasonCodes::ProviderPermissionMissing,
                        'message' => 'Missing required provider permissions.',
                        'evidence' => [],
                        'next_steps' => [],
                    ],
                ]),
            ],
        ]);
    }

    $draft = createOnboardingDraft([
        'workspace' => $workspace,
        'tenant' => $tenant,
        'started_by' => $user,
        'updated_by' => $user,
        'current_step' => 'verify',
        'state' => array_filter([
            'entra_tenant_id' => (string) $tenant->managed_environment_id,
            'environment_name' => (string) $tenant->name,
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => $run instanceof OperationRun ? (int) $run->getKey() : null,
        ], static fn (mixed $value): bool => $value !== null),
    ]);

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

    return [$user, $draft, $connection, $run, $missingKey];
}

it('returns 404 for non-members when starting onboarding with a selected workspace', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user)
        ->get('/admin/onboarding')
        ->assertNotFound();
});

it('forbids workspace members without onboarding capability from loading the wizard or executing actions', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $this->actingAs($user)
        ->get('/admin/onboarding')
        ->assertForbidden();

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->assertForbidden();

    expect(ManagedEnvironment::query()->count())->toBe(0);
    expect(ManagedEnvironmentOnboardingSession::query()->count())->toBe(0);
});

it('renders onboarding wizard for workspace owners and allows identifying a managed environment', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());
    $this->actingAs($user)
        ->get('/admin/onboarding')
        ->assertSuccessful();

    $entraTenantId = '22222222-2222-2222-2222-222222222222';

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->call('identifyManagedEnvironment', [
            'entra_tenant_id' => $entraTenantId,
            'environment' => 'prod',
            'name' => 'Acme',
            'primary_domain' => 'acme.example',
            'notes' => 'Initial onboarding',
        ]);

    $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail();

    expect((int) $tenant->workspace_id)->toBe((int) $workspace->getKey());
    expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING);

    $this->assertDatabaseHas('managed_environment_memberships', [
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'readonly',
    ]);

    $this->assertDatabaseHas('managed_environment_onboarding_sessions', [
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $entraTenantId,
        'current_step' => 'identify',
    ]);
});

it('renders neutral tenant id placeholder guidance for onboarding input', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $this->actingAs($user)
        ->get('/admin/onboarding')
        ->assertSuccessful()
        ->assertSee('Entra tenant ID (GUID)')
        ->assertSee('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', false);
});

it('uses target-scope wording in the onboarding provider setup step', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = '34343434-3434-3434-3434-343434343434';

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->call('identifyManagedEnvironment', [
            'entra_tenant_id' => $entraTenantId,
            'environment' => 'prod',
            'name' => 'Target Scope ManagedEnvironment',
        ])
        ->set('data.connection_mode', 'new')
        ->assertSee('Target scope ID')
        ->assertSee('The provider connection will point to this tenant target scope.')
        ->assertSee($entraTenantId)
        ->assertDontSee('Directory (tenant) ID')
        ->assertDontSee('Graph API calls');
});

it('renders review summary guidance and activation consequences for ready onboarding sessions', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = 'abababab-abab-abab-abab-abababababab';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'name' => 'Activation Ready ManagedEnvironment',
    ]);

    $connection = ProviderConnection::factory()->platform()->consentGranted()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $entraTenantId,
        'display_name' => 'Platform onboarding connection',
        'is_default' => true,
        'is_enabled' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
                'entra_tenant_name' => 'Activation Ready ManagedEnvironment',
            ],
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'consent',
                    'title' => 'Required application permissions',
                    'status' => 'pass',
                    'severity' => 'low',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Consent is ready.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $entraTenantId,
        'current_step' => 'bootstrap',
        'state' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    $this->actingAs($user)
        ->followingRedirects()
        ->get('/admin/onboarding')
        ->assertSuccessful()
        ->assertSee('Skipped - No bootstrap actions selected')
        ->assertSee('ManagedEnvironment status will be set to Active.')
        ->assertSee('The provider connection will be used for provider API calls.');
});

it('renders selected bootstrap actions in the review summary before any bootstrap run starts', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = 'cdcdcdcd-cdcd-cdcd-cdcd-cdcdcdcdcdcd';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'name' => 'Bootstrap Selected ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connection = ProviderConnection::factory()->platform()->consentGranted()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $entraTenantId,
        'display_name' => 'Platform onboarding connection',
        'is_default' => true,
        'is_enabled' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
                'entra_tenant_name' => 'Bootstrap Selected ManagedEnvironment',
            ],
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'consent',
                    'title' => 'Required application permissions',
                    'status' => 'pass',
                    'severity' => 'low',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Consent is ready.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $entraTenantId,
        'current_step' => 'complete',
        'state' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
            'bootstrap_operation_types' => ['inventory_sync', 'compliance.snapshot'],
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    $component = Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class, ['onboardingDraft' => (int) $session->getKey()]);

    $component
        ->assertDontSee('Bootstrap needs attention')
        ->assertDontSee('Selected bootstrap actions must complete before activation. Return to Bootstrap to remove the selected actions and skip this optional step, or resolve the required permission and start the blocked action again.');

    $summaryMethod = new \ReflectionMethod($component->instance(), 'completionSummaryBootstrapSummary');
    $summaryMethod->setAccessible(true);

    expect($summaryMethod->invoke($component->instance()))->toBe('Selected - 2 action(s) selected');
});

it('renders blocked bootstrap runs as action required in the review summary', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = 'efefefef-efef-efef-efef-efefefefefef';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'name' => 'Bootstrap Blocked ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connection = ProviderConnection::factory()->platform()->consentGranted()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $entraTenantId,
        'display_name' => 'Platform onboarding connection',
        'is_default' => true,
        'is_enabled' => true,
    ]);

    $verificationRun = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
                'entra_tenant_name' => 'Bootstrap Blocked ManagedEnvironment',
            ],
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'consent',
                    'title' => 'Required application permissions',
                    'status' => 'pass',
                    'severity' => 'low',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Consent is ready.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $bootstrapRun = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'inventory.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Blocked->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'reason_translation' => [
                'operator_label' => 'Permission required',
            ],
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $entraTenantId,
        'current_step' => 'complete',
        'state' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $verificationRun->getKey(),
            'bootstrap_operation_types' => ['inventory_sync', 'compliance.snapshot'],
            'bootstrap_operation_runs' => ['inventory_sync' => (int) $bootstrapRun->getKey()],
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    $component = Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class, ['onboardingDraft' => (int) $session->getKey()]);

    $summaryMethod = new \ReflectionMethod($component->instance(), 'completionSummaryBootstrapSummary');
    $summaryMethod->setAccessible(true);

    expect($summaryMethod->invoke($component->instance()))->toBe('Action required - Permission required');
});

it('initializes entangled wizard state keys to avoid Livewire entangle errors', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->assertSet('data.notes', '')
        ->assertSet('data.bootstrap_operation_types', [])
        ->assertSet('data.override_blocked', false)
        ->assertSet('data.override_reason', '');
});

it('persists selected bootstrap actions in the onboarding draft state', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = 'dededede-dede-dede-dede-dededededede';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'name' => 'Persist Bootstrap ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connection = ProviderConnection::factory()->platform()->consentGranted()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $entraTenantId,
        'display_name' => 'Platform onboarding connection',
        'is_default' => true,
        'is_enabled' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'consent',
                    'title' => 'Required application permissions',
                    'status' => 'pass',
                    'severity' => 'low',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Consent is ready.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $entraTenantId,
        'current_step' => 'bootstrap',
        'state' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    $component = Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class, ['onboardingDraft' => (int) $session->getKey()]);

    $persistMethod = new \ReflectionMethod($component->instance(), 'persistBootstrapSelection');
    $persistMethod->setAccessible(true);
    $persistMethod->invoke($component->instance(), ['inventory_sync', 'compliance.snapshot']);

    $session->refresh();

    expect($session->state['bootstrap_operation_types'] ?? null)->toBe(['inventory.sync', 'compliance.snapshot']);
});

it('filters unsupported bootstrap selections from persisted onboarding drafts', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $tenantGuid = '12121212-1212-1212-1212-121212121212';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $tenantGuid,
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'name' => 'Acme',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connection = ProviderConnection::factory()->platform()->consentGranted()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'display_name' => 'Platform onboarding connection',
        'is_default' => true,
        'is_enabled' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'target_scope' => [
                'entra_tenant_id' => $tenantGuid,
                'entra_tenant_name' => 'Acme',
            ],
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'consent',
                    'title' => 'Required application permissions',
                    'status' => 'pass',
                    'severity' => 'low',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Consent is ready.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $tenantGuid,
        'current_step' => 'complete',
        'state' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
            'bootstrap_operation_types' => [
                'inventory_sync',
                'compliance.snapshot',
                'restore.execute',
                'entra_group_sync',
                'directory_role_definitions.sync',
            ],
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    $component = Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class, ['onboardingDraft' => (int) $session->getKey()]);

    $normalizeMethod = new \ReflectionMethod($component->instance(), 'normalizeBootstrapOperationTypes');
    $normalizeMethod->setAccessible(true);

    expect($normalizeMethod->invoke($component->instance(), [
        'inventory_sync',
        'compliance.snapshot',
        'restore.execute',
        'entra_group_sync',
        'directory_role_definitions.sync',
    ]))->toBe(['inventory.sync', 'compliance.snapshot']);

    $optionsMethod = new \ReflectionMethod($component->instance(), 'bootstrapOperationOptions');
    $optionsMethod->setAccessible(true);

    expect(array_keys($optionsMethod->invoke($component->instance())))->toBe(['inventory.sync', 'compliance.snapshot']);
});

it('returns resumable drafts with missing provider connections to the provider connection step', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $draft = ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'current_step' => 'verify',
        'state' => [
            'entra_tenant_id' => (string) $tenant->managed_environment_id,
            'environment_name' => (string) $tenant->name,
            'provider_connection_id' => 999999,
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

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

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class, ['onboardingDraft' => (int) $draft->getKey()])
        ->assertWizardCurrentStep(2)
        ->assertSet('selectedProviderConnectionId', null)
        ->assertSet('data.provider_connection_id', null);
});

it('allows workspace owners to create a dedicated override connection explicitly during onboarding', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = '55555555-5555-5555-5555-555555555555';

    $component = Livewire::actingAs($user)->test(ManagedEnvironmentOnboardingWizard::class);

    $component->call('identifyManagedEnvironment', [
        'entra_tenant_id' => $entraTenantId,
        'environment' => 'prod',
        'name' => 'Dedicated ManagedEnvironment',
    ]);

    $component
        ->set('data.connection_mode', 'new')
        ->assertSee('Dedicated override')
        ->call('createProviderConnection', [
            'display_name' => 'Dedicated onboarding connection',
            'connection_type' => ProviderConnectionType::Dedicated->value,
            'client_id' => 'dedicated-onboarding-client',
            'client_secret' => 'dedicated-onboarding-secret',
            'is_default' => true,
        ]);

    $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail();

    $connection = \App\Models\ProviderConnection::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('provider', 'microsoft')
        ->firstOrFail();

    expect($connection->connection_type)->toBe(ProviderConnectionType::Dedicated)
        ->and($connection->credential)->not->toBeNull()
        ->and($connection->credential?->payload['client_id'] ?? null)->toBe('dedicated-onboarding-client');
});

it('forbids workspace managers from creating dedicated override connections during onboarding', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = '66666666-6666-6666-6666-666666666666';

    $component = Livewire::actingAs($user)->test(ManagedEnvironmentOnboardingWizard::class);

    $component->call('identifyManagedEnvironment', [
        'entra_tenant_id' => $entraTenantId,
        'environment' => 'prod',
        'name' => 'Managed ManagedEnvironment',
    ]);

    $component
        ->assertDontSee('Dedicated override')
        ->call('createProviderConnection', [
            'display_name' => 'Forbidden dedicated connection',
            'connection_type' => ProviderConnectionType::Dedicated->value,
            'client_id' => 'forbidden-dedicated-client',
            'client_secret' => 'forbidden-dedicated-secret',
            'is_default' => true,
        ])
        ->assertForbidden();
});

it('is idempotent when identifying the same Entra tenant ID twice', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $entraTenantId = '33333333-3333-3333-3333-333333333333';

    $component = Livewire::actingAs($user)->test(ManagedEnvironmentOnboardingWizard::class);

    $component->call('identifyManagedEnvironment', [
        'entra_tenant_id' => $entraTenantId,
        'environment' => 'prod',
        'name' => 'Acme',
    ]);

    $component->call('identifyManagedEnvironment', [
        'entra_tenant_id' => $entraTenantId,
        'environment' => 'prod',
        'name' => 'Acme',
    ]);

    expect(ManagedEnvironment::query()->where('slug', $entraTenantId)->count())->toBe(1);
    expect(ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('entra_tenant_id', $entraTenantId)
        ->whereNull('completed_at')
        ->count())->toBe(1);
});

it('returns 404 and does not create anything when entra_tenant_id exists in another workspace', function (): void {
    $entraTenantId = '44444444-4444-4444-4444-444444444444';

    $workspaceA = Workspace::factory()->create();
    $workspaceB = Workspace::factory()->create();

    $user = User::factory()->create();

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

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

    ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspaceA->getKey(),
        'managed_environment_id' => $entraTenantId,
        'status' => ManagedEnvironment::STATUS_ACTIVE,
    ]);

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

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->call('identifyManagedEnvironment', [
            'entra_tenant_id' => $entraTenantId,
            'environment' => 'prod',
            'name' => 'Other Workspace',
        ])
        ->assertStatus(404);
});

it('returns 404 for legacy onboarding entry points', function (): void {
    $user = User::factory()->create();
    $this->actingAs($user);

    $this->get('/admin/register-tenant')->assertNotFound();
    $this->get('/admin/managed-tenants')->assertNotFound();
    $this->get('/admin/managed-tenants/onboarding')->assertNotFound();
    $this->get('/admin/new')->assertNotFound();
});

it('shows resume context and derived stage when loading a concrete draft route', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create(['name' => 'Draft Owner']);

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

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

    $draft = createOnboardingDraft([
        'workspace' => $workspace,
        'started_by' => $user,
        'updated_by' => $user,
        'current_step' => 'connection',
        'state' => [
            'entra_tenant_id' => '77777777-7777-7777-7777-777777777777',
            'environment_name' => 'Resume Draft',
            'provider_connection_id' => 42,
        ],
    ]);

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class, [
            'onboardingDraft' => (int) $draft->getKey(),
        ])
        ->assertSuccessful()
        ->assertSee('Onboarding draft')
        ->assertSee('Resume Draft')
        ->assertSee('Verify access')
        ->assertSee('Draft Owner');
});

it('shows route-bound readiness progress and check-not-run guidance with one primary next action', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create(['name' => 'Readiness Owner']);

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

    $tenant = ManagedEnvironment::factory()->onboarding()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => '31313131-3131-3131-3131-313131313131',
        'name' => 'No Check ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connection = ProviderConnection::factory()->platform()->consentGranted()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'display_name' => 'No check connection',
        'is_default' => true,
    ]);

    $draft = createOnboardingDraft([
        'workspace' => $workspace,
        'tenant' => $tenant,
        'started_by' => $user,
        'updated_by' => $user,
        'current_step' => 'verify',
        'state' => [
            'entra_tenant_id' => (string) $tenant->managed_environment_id,
            'environment_name' => (string) $tenant->name,
            'provider_connection_id' => (int) $connection->getKey(),
        ],
    ]);

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

    $response = $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Onboarding readiness')
        ->assertSee('Step')
        ->assertDontSee('Current checkpoint')
        ->assertSee('Verify access')
        ->assertSee('Verification has not run yet')
        ->assertSee('Provider connection')
        ->assertSee('Primary next action')
        ->assertSee('Start verification');

    expect(substr_count($response->getContent(), 'Primary next action'))->toBe(1);
});

it('shows route-bound ready readiness with freshness and canonical operation evidence', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenant = ManagedEnvironment::factory()->onboarding()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => '32323232-3232-3232-3232-323232323232',
        'name' => 'Ready Readiness ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    seedManagedReadinessPermissions($tenant, missingKey: '__none__');

    $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'display_name' => 'Ready connection',
        'is_default' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'provider.connection.check',
                    'title' => 'Provider connection check',
                    'status' => 'pass',
                    'severity' => 'info',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Connection is healthy.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $draft = createOnboardingDraft([
        'workspace' => $workspace,
        'tenant' => $tenant,
        'started_by' => $user,
        'updated_by' => $user,
        'current_step' => 'complete',
        'state' => [
            'entra_tenant_id' => (string) $tenant->managed_environment_id,
            'environment_name' => (string) $tenant->name,
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ],
    ]);

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

    $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Ready for activation')
        ->assertSee('Verification and permission evidence are current.')
        ->assertSee('Complete onboarding')
        ->assertSee('Supporting evidence')
        ->assertSee('Open operation')
        ->assertSee(\App\Support\OperationRunLinks::tenantlessView($run), false);
});

it('classifies consent, disabled connection, and blocked verification readiness blockers', function (string $state, string $summary, string $nextAction): void {
    [$user, $draft] = createManagedReadinessBlockerDraft($state);

    $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Onboarding readiness')
        ->assertSee($summary)
        ->assertSee($nextAction);
})->with([
    'missing consent' => ['missing_consent', 'Provider consent required', 'Grant admin consent'],
    'revoked consent' => ['revoked_consent', 'Provider consent revoked', 'Grant admin consent'],
    'disabled connection' => ['disabled_connection', 'Provider connection disabled', 'Review provider connection'],
    'blocked verification' => ['blocked_verification', 'Provider connection check capability needs attention', 'Review provider capability'],
]);

it('keeps permission gap detail out of the top-level page once a verification report is present', function (): void {
    [$user, $draft, , , $missingKey] = createManagedReadinessBlockerDraft('permission_gap');

    $response = $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Provider connection check capability needs attention')
        ->assertDontSee('Permission diagnostics')
        ->assertSee('Supporting evidence')
        ->assertSee('View required permissions')
        ->assertSee('Review provider capability');

    if (is_string($missingKey) && $missingKey !== '') {
        $response->assertDontSee($missingKey);
    }

    $response->assertDontSee('Microsoft Graph readiness');
});

it('shows permission diagnostics as a fallback when no verification report is present', function (): void {
    [$user, $draft] = createManagedReadinessBlockerDraft('missing_consent');

    $tenant = $draft->managedEnvironment()->firstOrFail();
    $missingKey = seedManagedReadinessPermissions($tenant);

    $response = $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Permission diagnostics')
        ->assertDontSee('Supporting evidence');

    if (is_string($missingKey) && $missingKey !== '') {
        $response->assertSee($missingKey);
    }
});

it('downgrades route-bound readiness when permission evidence is stale and keeps the operation link canonical', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenant = ManagedEnvironment::factory()->onboarding()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => '52525252-5252-5252-5252-525252525252',
        'name' => 'Stale Evidence ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    seedManagedReadinessPermissions($tenant, staleDays: 45, missingKey: '__none__');

    $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'display_name' => 'Stale readiness connection',
        'is_default' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'provider.connection.check',
                    'title' => 'Provider connection check',
                    'status' => 'pass',
                    'severity' => 'info',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Connection is healthy.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $draft = createOnboardingDraft([
        'workspace' => $workspace,
        'tenant' => $tenant,
        'started_by' => $user,
        'updated_by' => $user,
        'current_step' => 'complete',
        'state' => [
            'entra_tenant_id' => (string) $tenant->managed_environment_id,
            'environment_name' => (string) $tenant->name,
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ],
    ]);

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

    $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Provider connection check capability needs refreshed evidence')
        ->assertSee('Permission data is older than the 30-day freshness window.')
        ->assertSee('Rerun verification')
        ->assertSee('Open operation')
        ->assertSee(\App\Support\OperationRunLinks::tenantlessView($run), false);
});

it('downgrades route-bound readiness when verification evidence belongs to another selected connection', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenant = ManagedEnvironment::factory()->onboarding()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => '53535353-5353-5353-5353-535353535353',
        'name' => 'Mismatched Evidence ManagedEnvironment',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    seedManagedReadinessPermissions($tenant, missingKey: '__none__');

    $oldConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => '54545454-5454-5454-5454-545454545454',
        'display_name' => 'Previous connection',
    ]);
    $selectedConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'display_name' => 'Selected connection',
        'is_default' => true,
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'context' => [
            'provider_connection_id' => (int) $oldConnection->getKey(),
            'verification_report' => VerificationReportWriter::build('provider.connection.check', [
                [
                    'key' => 'provider.connection.check',
                    'title' => 'Provider connection check',
                    'status' => 'pass',
                    'severity' => 'info',
                    'blocking' => false,
                    'reason_code' => 'ok',
                    'message' => 'Connection is healthy.',
                    'evidence' => [],
                    'next_steps' => [],
                ],
            ]),
        ],
    ]);

    $draft = createOnboardingDraft([
        'workspace' => $workspace,
        'tenant' => $tenant,
        'started_by' => $user,
        'updated_by' => $user,
        'current_step' => 'complete',
        'state' => [
            'entra_tenant_id' => (string) $tenant->managed_environment_id,
            'environment_name' => (string) $tenant->name,
            'provider_connection_id' => (int) $selectedConnection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ],
    ]);

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

    $this->actingAs($user)
        ->get(route('admin.onboarding.draft', ['onboardingDraft' => $draft->getKey()]))
        ->assertSuccessful()
        ->assertSee('Verification needs refresh')
        ->assertSee('Verification evidence belongs to a different provider connection.')
        ->assertSee('Rerun verification')
        ->assertSee('Open operation')
        ->assertSee(\App\Support\OperationRunLinks::tenantlessView($run), false);
});

it('resumes an existing draft for the same tenant instead of creating a duplicate', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $existingDraft = createOnboardingDraft([
        'workspace' => $workspace,
        'started_by' => $user,
        'updated_by' => $user,
        'entra_tenant_id' => '88888888-8888-8888-8888-888888888888',
        'state' => [
            'entra_tenant_id' => '88888888-8888-8888-8888-888888888888',
            'environment_name' => 'Existing Draft ManagedEnvironment',
        ],
    ]);

    createOnboardingDraft([
        'workspace' => $workspace,
        'started_by' => $user,
        'updated_by' => $user,
        'entra_tenant_id' => '12121212-1212-1212-1212-121212121212',
        'state' => [
            'entra_tenant_id' => '12121212-1212-1212-1212-121212121212',
            'environment_name' => 'Keep Landing Stable',
        ],
    ]);

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->call('identifyManagedEnvironment', [
            'entra_tenant_id' => '88888888-8888-8888-8888-888888888888',
            'environment' => 'prod',
            'name' => 'Existing Draft ManagedEnvironment',
        ])
        ->assertRedirect(route('admin.onboarding.draft', ['onboardingDraft' => $existingDraft->getKey()]));

    expect(ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('entra_tenant_id', '88888888-8888-8888-8888-888888888888')
        ->count())->toBe(1);
});

it('allows resuming a selected draft from the picker', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

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

    $draftToResume = createOnboardingDraft([
        'workspace' => $workspace,
        'started_by' => $user,
        'updated_by' => $user,
        'state' => [
            'entra_tenant_id' => '99999999-9999-9999-9999-999999999999',
            'environment_name' => 'Resume Me',
        ],
    ]);

    createOnboardingDraft([
        'workspace' => $workspace,
        'started_by' => $user,
        'updated_by' => $user,
        'state' => [
            'entra_tenant_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
            'environment_name' => 'Leave Me',
        ],
    ]);

    Livewire::actingAs($user)
        ->test(ManagedEnvironmentOnboardingWizard::class)
        ->callAction(
            TestAction::make('resume_draft_'.$draftToResume->getKey())
                ->schemaComponent('draft_picker_actions_'.$draftToResume->getKey())
        )
        ->assertRedirect(route('admin.onboarding.draft', ['onboardingDraft' => $draftToResume->getKey()]));
});

/*
|--------------------------------------------------------------------------
| Legacy onboarding suite (deprecated)
|--------------------------------------------------------------------------
|
| The remainder of this file previously contained an end-to-end onboarding
| suite that relied on deprecated routes and pre-enterprise state semantics.
| Spec 073 replaces it with focused coverage under tests/Feature/Onboarding
| and tests/Feature/Rbac.
|
| Keeping the legacy assertions around (commented) is intentional to avoid
| reintroducing removed routes or old semantics.


    $this->actingAs($user);

    $tenantGuid = '22222222-2222-2222-2222-222222222222';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);

    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    expect(ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->count())->toBe(1);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    expect(ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', $workspace->getKey())
        ->where('managed_environment_id', $tenant->getKey())
        ->count())->toBe(1);

    $this->assertDatabaseHas('managed_environment_onboarding_sessions', [
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
    ]);
});

it('returns 404 and does not create anything when managed_environment_id exists in another workspace', function (): void {
    $workspaceA = Workspace::factory()->create();
    $workspaceB = Workspace::factory()->create();

    $user = User::factory()->create();

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

    $tenantGuid = '33333333-3333-3333-3333-333333333333';

    ManagedEnvironment::factory()->create([
        'workspace_id' => $workspaceA->getKey(),
        'managed_environment_id' => $tenantGuid,
        'name' => 'Acme',
        'status' => 'active',
    ]);

    $this->actingAs($user);

    Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspaceB])
        ->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme'])
        ->assertStatus(404);

    expect(ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->count())->toBe(1);

    expect(ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', $workspaceB->getKey())
        ->whereIn('managed_environment_id', ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->pluck('id'))
        ->count())->toBe(0);
});

it('binds an unscoped existing tenant to the current workspace when safe and allows identifying it', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenantGuid = '77777777-7777-7777-7777-777777777777';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => null,
        'managed_environment_id' => $tenantGuid,
        'name' => 'Acme',
        'status' => 'active',
    ]);

    \App\Models\ManagedEnvironmentMembership::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'owner',
        'source' => 'manual',
        'created_by_user_id' => (int) $user->getKey(),
    ]);

    $this->assertDatabaseHas('tenants', [
        'id' => (int) $tenant->getKey(),
        'workspace_id' => null,
        'managed_environment_id' => $tenantGuid,
    ]);

    $this->assertDatabaseHas('managed_environment_memberships', [
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
    ]);

    $this->actingAs($user);

    Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace])
        ->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme'])
        ->assertOk();

    $this->assertDatabaseHas('tenants', [
        'id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $tenantGuid,
    ]);
});

it('auto-selects the default provider connection and allows switching', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $tenantGuid = '99999999-9999-9999-9999-999999999999';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'managed_environment_id' => $tenantGuid,
        'name' => 'Acme',
        'status' => 'pending',
    ]);

    $default = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'display_name' => 'Default',
        'is_default' => true,
    ]);

    $other = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft_alt',
        'entra_tenant_id' => $tenantGuid,
        'display_name' => 'Other',
        'is_default' => false,
    ]);

    $this->actingAs($user);

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);

    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $component->assertSet('selectedProviderConnectionId', (int) $default->getKey());

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    expect($session->state['provider_connection_id'] ?? null)->toBe((int) $default->getKey());

    $component->call('selectProviderConnection', (int) $other->getKey());
    $component->assertSet('selectedProviderConnectionId', (int) $other->getKey());

    $session->refresh();
    expect($session->state['provider_connection_id'] ?? null)->toBe((int) $other->getKey());
});

it('dedupes verification runs: starting verification twice returns the active run and dispatches only once', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = '77777777-7777-7777-7777-777777777777';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'is_default' => true,
    ]);

    $component->set('selectedProviderConnectionId', (int) $connection->getKey());

    $component->call('startVerification');
    $component->call('startVerification');

    $component
        ->assertSee('Onboarding readiness')
        ->assertSee('Open operation');

    expect(OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'provider.connection.check')
        ->count())->toBe(1);

    Bus::assertDispatchedTimes(\App\Jobs\ProviderConnectionHealthCheckJob::class, 1);

    $this->assertDatabaseHas('audit_logs', [
        'workspace_id' => (int) $workspace->getKey(),
        'actor_id' => (int) $user->getKey(),
        'action' => 'managed_environment_onboarding.verification_start',
        'resource_type' => 'operation_run',
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    expect($session->state['verification_operation_run_id'] ?? null)->not->toBeNull();
});

it('creates a provider connection with encrypted credentials and does not persist secrets in session state', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa';
    $secret = 'super-secret-123';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);

    $component
        ->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme'])
        ->call('createProviderConnection', [
            'display_name' => 'Onboarding Connection',
            'client_id' => 'client-id-1',
            'client_secret' => $secret,
            'is_default' => true,
        ])
        ->assertDontSee($secret);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('provider', 'microsoft')
        ->where('entra_tenant_id', $tenantGuid)
        ->firstOrFail();

    expect($connection->credential)->toBeInstanceOf(ProviderCredential::class);
    expect($connection->credential->toArray())->not->toHaveKey('payload');

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    $state = $session->state ?? [];
    expect($state)->not->toHaveKey('client_id');
    expect($state)->not->toHaveKey('client_secret');
    expect($state['provider_connection_id'] ?? null)->toBe((int) $connection->getKey());
});

it('starts verification, creates an operation run, dispatches the job, and does not include secrets in run context', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'is_default' => true,
    ]);

    $component->set('selectedProviderConnectionId', (int) $connection->getKey());
    $component->call('startVerification');

    $run = OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'provider.connection.check')
        ->latest('id')
        ->firstOrFail();

    expect($run->context)->toBeArray();
    expect($run->context['provider_connection_id'] ?? null)->toBe((int) $connection->getKey());
    expect($run->context)->not->toHaveKey('client_id');
    expect($run->context)->not->toHaveKey('client_secret');

    Bus::assertDispatched(\App\Jobs\ProviderConnectionHealthCheckJob::class);
});

it('can resume the latest onboarding session as a different authorized workspace member', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();

    $initiator = User::factory()->create();
    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $initiator->getKey(),
        'role' => 'owner',
    ]);

    $resumer = User::factory()->create();
    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $resumer->getKey(),
        'role' => 'manager',
    ]);

    $tenantGuid = 'cccccccc-cccc-cccc-cccc-cccccccccccc';

    $this->actingAs($initiator);

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'is_default' => true,
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    $session->update([
        'state' => array_merge($session->state ?? [], [
            'provider_connection_id' => (int) $connection->getKey(),
        ]),
    ]);

    $this->actingAs($resumer);

    Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace])
        ->call('startVerification');

    Bus::assertDispatched(\App\Jobs\ProviderConnectionHealthCheckJob::class);
});

it('completes onboarding only after verification succeeded and redirects to tenant dashboard', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = 'dddddddd-dddd-dddd-dddd-dddddddddddd';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'is_default' => true,
    ]);

    $run = OperationRun::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'run_identity_hash' => sha1('verify-ok-'.(string) $connection->getKey()),
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    $session->update([
        'state' => array_merge($session->state ?? [], [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ]),
    ]);

    $component
        ->call('completeOnboarding')
        ->assertRedirect(EnvironmentDashboard::getUrl(tenant: $tenant));

    $tenant->refresh();
    expect($tenant->status)->toBe('active');

    $session->refresh();
    expect($session->completed_at)->not->toBeNull();
});

it('starts one selected bootstrap action at a time and persists the remaining selections', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'is_default' => true,
    ]);

    $verificationRun = OperationRun::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'run_identity_hash' => sha1('verify-ok-bootstrap-'.(string) $connection->getKey()),
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    $session->update([
        'state' => array_merge($session->state ?? [], [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $verificationRun->getKey(),
        ]),
    ]);

    $component->call('startBootstrap', [
        'inventory_sync' => true,
        'compliance.snapshot' => true,
    ]);

    Bus::assertDispatchedTimes(\App\Jobs\ProviderInventorySyncJob::class, 1);
    Bus::assertNotDispatched(\App\Jobs\ProviderComplianceSnapshotJob::class);

    expect(OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'inventory.sync')
        ->count())->toBe(1);

    expect(OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'compliance.snapshot')
        ->count())->toBe(0);

    $session->refresh();
    $runs = $session->state['bootstrap_operation_runs'] ?? [];
    expect($runs)->toBeArray();
    expect($runs['inventory.sync'] ?? null)->toBeInt();
    expect($runs['compliance.snapshot'] ?? null)->toBeNull();
    expect($session->state['bootstrap_operation_types'] ?? null)->toBe(['inventory.sync', 'compliance.snapshot']);

    $audit = AuditLog::query()
        ->where('action', AuditActionId::ManagedEnvironmentOnboardingBootstrapStarted->value)
        ->latest('id')
        ->firstOrFail();

    expect(data_get($audit->metadata, 'operation_types'))->toBe(['inventory.sync', 'compliance.snapshot'])
        ->and(data_get($audit->metadata, 'started_operation_type'))->toBe('inventory.sync');
});

it('starts the next pending bootstrap action after the prior one completes successfully', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = 'ffffffff-ffff-ffff-ffff-ffffffffffff';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'is_default' => true,
    ]);

    $verificationRun = OperationRun::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'run_identity_hash' => sha1('verify-ok-bootstrap-next-'.(string) $connection->getKey()),
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
        ],
    ]);

    $session = ManagedEnvironmentOnboardingSession::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->firstOrFail();

    $session->update([
        'state' => array_merge($session->state ?? [], [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $verificationRun->getKey(),
        ]),
    ]);

    $component->call('startBootstrap', ['inventory.sync', 'compliance.snapshot']);

    $inventoryRun = OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'inventory.sync')
        ->latest('id')
        ->firstOrFail();

    $inventoryRun->forceFill([
        'status' => 'completed',
        'outcome' => 'succeeded',
    ])->save();

    $component->call('startBootstrap', ['inventory.sync', 'compliance.snapshot']);

    Bus::assertDispatchedTimes(\App\Jobs\ProviderInventorySyncJob::class, 1);
    Bus::assertDispatchedTimes(\App\Jobs\ProviderComplianceSnapshotJob::class, 1);

    expect(OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'compliance.snapshot')
        ->count())->toBe(1);

    $session->refresh();
    $runs = $session->state['bootstrap_operation_runs'] ?? [];
    expect($runs['inventory.sync'] ?? null)->toBeInt();
    expect($runs['compliance.snapshot'] ?? null)->toBeInt();
});

it('returns scope-busy semantics for verification when another run is active for the same connection scope', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = '88888888-8888-8888-8888-888888888888';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'is_default' => true,
    ]);

    OperationRun::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
        'type' => 'inventory.sync',
        'status' => 'queued',
        'outcome' => 'pending',
        'run_identity_hash' => sha1('busy-'.(string) $connection->getKey()),
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
        ],
    ]);

    $component->set('selectedProviderConnectionId', (int) $connection->getKey());

    $component->call('startVerification');

    expect(OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'provider.connection.check')
        ->count())->toBe(0);

    Bus::assertNotDispatched(\App\Jobs\ProviderConnectionHealthCheckJob::class);
});

it('fails a stale queued verification run and allows starting a new verification run', function (): void {
    Bus::fake();

    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

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

    $this->actingAs($user);

    $tenantGuid = '99999999-9999-9999-9999-999999999999';

    $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard::class, ['workspace' => $workspace]);
    $component->call('identifyManagedEnvironment', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']);

    $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail();

    $connection = ProviderConnection::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'entra_tenant_id' => $tenantGuid,
        'is_default' => true,
    ]);

    $staleRun = OperationRun::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
        'type' => 'provider.connection.check',
        'status' => 'queued',
        'outcome' => 'pending',
        'run_identity_hash' => sha1('stale-queued-verify-'.(string) $connection->getKey()),
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
        ],
        'created_at' => now()->subMinutes(10),
        'updated_at' => now()->subMinutes(10),
    ]);

    $component->set('selectedProviderConnectionId', (int) $connection->getKey());
    $component->call('startVerification');

    $staleRun->refresh();
    expect($staleRun->status)->toBe('completed');
    expect($staleRun->outcome)->toBe('failed');
    expect($staleRun->context)->toBeArray();
    expect($staleRun->context['verification_report'] ?? null)->toBeArray();

    $report = $staleRun->context['verification_report'] ?? null;
    expect($report['checks'] ?? null)->toBeArray();
    expect($report['checks'][0]['message'] ?? null)->toBe('Run was queued but never started. A queue worker may not be running.');

    $newRun = OperationRun::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('type', 'provider.connection.check')
        ->latest('id')
        ->firstOrFail();

    expect((int) $newRun->getKey())->not->toBe((int) $staleRun->getKey());

    Bus::assertDispatched(\App\Jobs\ProviderConnectionHealthCheckJob::class);
});

it('registers the onboarding capability in the canonical registry', function (): void {
    expect(Capabilities::isKnown(Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD))->toBeTrue();
});

it('maps onboarding capability to owner and manager workspace roles', function (): void {
    expect(WorkspaceRoleCapabilityMap::hasCapability('owner', Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD))->toBeTrue();
    expect(WorkspaceRoleCapabilityMap::hasCapability('manager', Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD))->toBeTrue();

    expect(WorkspaceRoleCapabilityMap::hasCapability('operator', Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD))->toBeFalse();
    expect(WorkspaceRoleCapabilityMap::hasCapability('readonly', Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD))->toBeFalse();
});

it('authorizes onboarding via Gate for owner and manager memberships', function (): void {
    $workspace = Workspace::factory()->create();

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

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

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

    expect(Gate::forUser($owner)->allows(Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD, $workspace))->toBeTrue();
    expect(Gate::forUser($manager)->allows(Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD, $workspace))->toBeTrue();
    expect(Gate::forUser($readonly)->allows(Capabilities::WORKSPACE_MANAGED_ENVIRONMENT_ONBOARD, $workspace))->toBeFalse();
});

it('keeps filament tenant routing key stable for workspace environment routes', function (): void {
    [$user, $tenant] = createUserWithTenant(
        ManagedEnvironment::factory()->create([
            'workspace_id' => null,
            'managed_environment_id' => '11111111-1111-1111-1111-111111111111',
        ]),
        role: 'owner',
    );

    $this->actingAs($user)
        ->get(EnvironmentDashboard::getUrl(tenant: $tenant))
        ->assertSuccessful();

    $tenant->refresh();

    expect($tenant->external_id)->toBe($tenant->managed_environment_id);
});

it('can persist a managed environment onboarding session row', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $session = ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'current_step' => 'identify',
        'state' => ['example' => 'value'],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    expect($session->exists)->toBeTrue();
    $this->assertDatabaseHas('managed_environment_onboarding_sessions', [
        'id' => $session->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'current_step' => 'identify',
    ]);
});

*/
