<?php

declare(strict_types=1);

use App\Models\AuditLog;
use App\Models\ProviderConnection;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('audits admin consent start with platform connection metadata', function (): void {
    config()->set('graph.client_id', 'platform-app-id');
    config()->set('graph.client_secret', 'platform-app-secret');

    $workspace = Workspace::factory()->create();
    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => 'tenant-consent-start',
        'name' => 'ManagedEnvironment Consent Start',
    ]);
    $user = User::factory()->create();

    $this->actingAs($user)
        ->withSession([
            WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(),
        ])
        ->get(route('admin.consent.start', ['tenant' => $tenant->managed_environment_id]))
        ->assertRedirect();

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

    $log = AuditLog::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('action', 'provider_connection.consent_started')
        ->latest('id')
        ->first();

    expect($log)->not->toBeNull()
        ->and($log?->status)->toBe('success')
        ->and($log?->actor_id)->toBe((int) $user->getKey())
        ->and($log?->resource_type)->toBe('provider_connection')
        ->and($log?->resource_id)->toBe((string) $connection->getKey())
        ->and($log?->metadata['provider_connection_id'] ?? null)->toBe((int) $connection->getKey())
        ->and($log?->metadata['connection_type'] ?? null)->toBe('platform')
        ->and($log?->metadata['effective_client_id'] ?? null)->toBe('platform-app-id');
});

it('audits admin consent callback results with connection type and outcome metadata', function (): void {
    $tenant = ManagedEnvironment::factory()->create([
        'managed_environment_id' => 'tenant-consent-result',
        'name' => 'ManagedEnvironment Consent Result',
    ]);

    $this->get(route('admin.consent.callback', [
        'tenant' => $tenant->managed_environment_id,
        'admin_consent' => 'true',
    ]))->assertOk();

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

    $log = AuditLog::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('action', 'provider_connection.consent_result')
        ->latest('id')
        ->first();

    expect($log)->not->toBeNull()
        ->and($log?->status)->toBe('success')
        ->and($log?->resource_type)->toBe('provider_connection')
        ->and($log?->resource_id)->toBe((string) $connection->getKey())
        ->and($log?->metadata['provider_connection_id'] ?? null)->toBe((int) $connection->getKey())
        ->and($log?->metadata['connection_type'] ?? null)->toBe('platform')
        ->and($log?->metadata['consent_status'] ?? null)->toBe('granted')
        ->and($log?->metadata['verification_status'] ?? null)->toBe('unknown');
});
