<?php

declare(strict_types=1);

use App\Filament\Pages\Workspaces\ManagedEnvironmentOnboardingWizard;
use App\Filament\Resources\ProviderConnectionResource;
use App\Models\ManagedEnvironment;
use App\Models\ManagedEnvironmentOnboardingSession;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Support\Links\RequiredPermissionsLinks;
use App\Support\OperationRunLinks;
use App\Support\Verification\VerificationReportWriter;
use App\Support\Workspaces\WorkspaceContext;
use Livewire\Livewire;

it('renders clustered verification checks issues-first in the onboarding wizard verify 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 = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'external_id' => 'tenant-clusters-a',
        'status' => 'onboarding',
    ]);

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

    $checks = [
        [
            'key' => 'provider.connection.check',
            'title' => 'Provider connection check',
            'status' => 'pass',
            'severity' => 'info',
            'blocking' => false,
            'reason_code' => 'ok',
            'message' => 'Connection is healthy.',
            'evidence' => [],
            'next_steps' => [],
        ],
        [
            'key' => 'permissions.admin_consent',
            'title' => 'Required application permissions',
            'status' => 'fail',
            'severity' => 'critical',
            'blocking' => true,
            'reason_code' => 'ext.missing_permission',
            'message' => 'Missing required application permissions.',
            'evidence' => [
                ['kind' => 'missing_permission', 'value' => 'DeviceManagementConfiguration.Read.All'],
            ],
            'next_steps' => [
                [
                    'label' => 'Open required permissions',
                    'url' => RequiredPermissionsLinks::requiredPermissions($tenant),
                ],
            ],
        ],
        [
            'key' => 'permissions.intune_configuration',
            'title' => 'Intune configuration access',
            'status' => 'pass',
            'severity' => 'info',
            'blocking' => false,
            'reason_code' => 'ok',
            'message' => 'All required permissions are granted.',
            'evidence' => [],
            'next_steps' => [],
        ],
    ];

    $verificationReport = VerificationReportWriter::build('provider.connection.check', $checks);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'context' => [
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
                'entra_tenant_name' => 'Contoso',
            ],
            'verification_report' => $verificationReport,
        ],
    ]);

    ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => $entraTenantId,
        'current_step' => 'verify',
        'state' => [
            '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('Technical details')
        ->assertSee(OperationRunLinks::openLabel())
        ->assertSee('Required application permissions')
        ->assertSee('Open required permissions')
        ->assertSee('Issues')
        ->assertDontSee('Open previous operation')
        ->assertDontSee('Open operation in Monitoring (advanced)')
        ->assertSee($entraTenantId);
});

it('can open the onboarding verification technical details slideover without 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());

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

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'external_id' => 'tenant-clusters-b',
        'status' => 'onboarding',
    ]);

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

    $verificationReport = VerificationReportWriter::build('provider.connection.check', []);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'context' => [
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
                'entra_tenant_name' => 'Contoso',
            ],
            'verification_report' => $verificationReport,
        ],
    ]);

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

    $this->actingAs($user);

    Livewire::test(ManagedEnvironmentOnboardingWizard::class, [
        'onboardingDraft' => (int) $session->getKey(),
    ])
        ->mountAction('wizardVerificationTechnicalDetails')
        ->assertMountedActionModalSee('Verification technical details')
        ->assertMountedActionModalSee(OperationRunLinks::advancedMonitoringLabel())
        ->assertMountedActionModalSee(OperationRunLinks::identifier((int) $run->getKey()));
});

it('keeps previous-run and advanced monitoring links inside technical details only', 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 = 'dddddddd-dddd-dddd-dddd-dddddddddddd';

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => $entraTenantId,
        'external_id' => 'tenant-clusters-d',
        'status' => 'onboarding',
    ]);

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

    $previousReport = VerificationReportWriter::build('provider.connection.check', []);

    $previousRun = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'context' => [
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
            ],
            'verification_report' => $previousReport,
        ],
    ]);

    $currentReport = VerificationReportWriter::build('provider.connection.check', []);
    $currentReport['previous_report_id'] = (int) $previousRun->getKey();

    $currentRun = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'failed',
        'context' => [
            'target_scope' => [
                'entra_tenant_id' => $entraTenantId,
            ],
            'verification_report' => $currentReport,
        ],
    ]);

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

    $this->actingAs($user)
        ->followingRedirects()
        ->get('/admin/onboarding')
        ->assertSuccessful()
        ->assertSee(OperationRunLinks::openLabel())
        ->assertDontSee('Open previous operation')
        ->assertDontSee(OperationRunLinks::advancedMonitoringLabel());

    Livewire::test(ManagedEnvironmentOnboardingWizard::class, [
        'onboardingDraft' => (int) $session->getKey(),
    ])
        ->mountAction('wizardVerificationTechnicalDetails')
        ->assertMountedActionModalSee('Open previous operation')
        ->assertMountedActionModalSee(OperationRunLinks::advancedMonitoringLabel());
});

it('routes permission-related verification next steps through the required permissions assist', 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());

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => 'cccccccc-cccc-cccc-cccc-cccccccccccc',
        'external_id' => 'tenant-clusters-c',
        'status' => 'onboarding',
    ]);

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

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

    $verificationReport = VerificationReportWriter::build('provider.connection.check', [
        [
            'key' => 'provider.connection.preflight',
            'title' => 'Required application permissions',
            'status' => 'fail',
            'severity' => 'critical',
            'blocking' => true,
            'reason_code' => 'provider_permission_missing',
            'message' => 'Missing required application permissions.',
            'evidence' => [],
            'next_steps' => [
                [
                    'label' => 'Grant admin consent',
                    'url' => 'https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/grant-admin-consent',
                ],
                [
                    'label' => 'Review platform connection',
                    'url' => ProviderConnectionResource::getUrl(
                        'edit',
                        ['tenant' => $tenant, 'record' => (int) $connection->getKey()],
                        panel: 'admin',
                    ),
                ],
            ],
        ],
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'blocked',
        'context' => [
            'target_scope' => [
                'entra_tenant_id' => (string) $tenant->managed_environment_id,
                'entra_tenant_name' => (string) $tenant->name,
            ],
            'verification_report' => $verificationReport,
        ],
    ]);

    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' => [
            '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('Grant admin consent')
        ->assertSee('Review platform connection')
        ->assertSee('Open in assist')
        ->assertSee('data-testid="verification-next-step-grant-admin-consent"', false)
        ->assertSee('data-testid="verification-next-step-review-platform-connection"', false)
        ->assertSee('wire:click="mountAction(\'wizardVerificationRequiredPermissionsAssist\')"', false)
        ->assertDontSee('href="https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/grant-admin-consent"', false)
        ->assertDontSee(ProviderConnectionResource::getUrl(
            'edit',
            ['tenant' => $tenant, 'record' => (int) $connection->getKey()],
            panel: 'admin',
        ), false);
});
