<?php

declare(strict_types=1);

use App\Jobs\ProviderConnectionHealthCheckJob;
use App\Models\AuditLog;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Services\Graph\GraphClientInterface;
use App\Services\Graph\GraphResponse;
use App\Services\OperationRunService;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('audits provider connection verification results with resolved identity metadata', function (): void {
    config()->set('graph.client_id', 'platform-client-id');
    config()->set('graph.client_secret', 'platform-client-secret');

    app()->instance(GraphClientInterface::class, new class implements GraphClientInterface
    {
        public function listPolicies(string $policyType, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function getPolicy(string $policyType, string $policyId, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function getOrganization(array $options = []): GraphResponse
        {
            return new GraphResponse(true, data: ['id' => 'org-id', 'displayName' => 'Contoso']);
        }

        public function applyPolicy(string $policyType, string $policyId, array $payload, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function getServicePrincipalPermissions(array $options = []): GraphResponse
        {
            return new GraphResponse(true, data: ['permissions' => []]);
        }

        public function request(string $method, string $path, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }
    });

    $user = User::factory()->create();
    $tenant = ManagedEnvironment::factory()->create([
        'managed_environment_id' => 'verification-audit-tenant-id',
    ]);
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, user: $user, role: 'owner', ensureDefaultMicrosoftProviderConnection: false);

    $connection = ProviderConnection::factory()->platform()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'provider' => 'microsoft',
        'entra_tenant_id' => 'verification-audit-tenant-id',
        'is_default' => true,
        'is_enabled' => true,
        'consent_status' => 'granted',
    ]);

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
        'type' => 'provider.connection.check',
        'status' => 'running',
        'outcome' => 'pending',
        'context' => [
            'provider' => 'microsoft',
            'module' => 'health_check',
            'provider_connection_id' => (int) $connection->getKey(),
            'target_scope' => [
                'entra_tenant_id' => $connection->entra_tenant_id,
            ],
        ],
    ]);

    $job = new ProviderConnectionHealthCheckJob(
        tenantId: (int) $tenant->getKey(),
        userId: (int) $user->getKey(),
        providerConnectionId: (int) $connection->getKey(),
        operationRun: $run,
    );

    $job->handle(app(\App\Services\Providers\MicrosoftProviderHealthCheck::class), app(OperationRunService::class));

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

    $metadata = is_array($log?->metadata ?? null) ? $log->metadata : [];

    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['is_enabled'] ?? null)->toBeTrue()
        ->and($log?->metadata['consent_status'] ?? null)->toBe('granted')
        ->and($log?->metadata['verification_status'] ?? null)->toBe('healthy')
        ->and($log?->metadata['effective_client_id'] ?? null)->toBe('platform-client-id')
        ->and($log?->metadata['credential_source'] ?? null)->toBe('platform_config');

    expect($metadata)->not->toHaveKey('status')
        ->and($metadata)->not->toHaveKey('health_status');
});
