<?php

declare(strict_types=1);

use App\Models\AuditLog;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\StoredReport;
use App\Models\ManagedEnvironment;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use App\Support\Providers\ProviderReasonCodes;
use App\Support\Providers\ProviderVerificationStatus;
use App\Support\SupportRequests\SupportRequestContextBuilder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('builds deterministic canonical context with omission markers when diagnostics are not attached', function (): void {
    $tenant = ManagedEnvironment::factory()->create(['name' => 'Omission ManagedEnvironment']);
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator');

    $builder = app(SupportRequestContextBuilder::class);

    $first = $builder->forTenant($tenant, $user, false);
    $second = $builder->forTenant($tenant->fresh(), $user, false);
    $sections = collect($first['canonical_context']['sections'])->keyBy('key');

    expect($first)
        ->toEqual($second)
        ->and($first['attachment_mode'])
        ->toBe(SupportRequestContextBuilder::ATTACHMENT_MODE_CANONICAL_CONTEXT_ONLY)
        ->and($first['diagnostic_snapshot'])
        ->toBeNull()
        ->and(data_get($first, 'primary_context.type'))
        ->toBe('tenant')
        ->and(data_get($first, 'omissions.0.reason'))
        ->toBe('omitted_without_support_diagnostics_view')
        ->and(data_get($sections->get('provider_connection'), 'references.0.label'))
        ->toBe('Provider connection not observed')
        ->and(data_get($sections->get('operation_context'), 'references.0.label'))
        ->toBe('Operation not yet observed')
        ->and(data_get($sections->get('audit_history'), 'references.0.label'))
        ->toBe('Audit event not yet observed');
});

it('attaches a redacted diagnostic snapshot without raw payload content', function (): void {
    $tenant = ManagedEnvironment::factory()->create(['name' => 'Redaction ManagedEnvironment']);
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator');

    $connection = ProviderConnection::factory()
        ->withCredential()
        ->create([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'display_name' => 'Redaction Connection',
            'verification_status' => ProviderVerificationStatus::Blocked->value,
            'last_error_reason_code' => ProviderReasonCodes::ProviderPermissionMissing,
            'last_error_message' => 'raw-provider-secret-message',
            'last_health_check_at' => now()->subMinutes(15),
        ]);

    $run = OperationRun::factory()
        ->forTenant($tenant)
        ->create([
            'type' => OperationRunType::BaselineCompare->value,
            'status' => OperationRunStatus::Completed->value,
            'outcome' => OperationRunOutcome::Failed->value,
            'summary_counts' => [
                'total' => 0,
                'processed' => 0,
            ],
            'context' => [
                'provider_connection_id' => (int) $connection->getKey(),
                'raw_response_body' => 'secret-provider-body',
            ],
            'failure_summary' => [[
                'message' => 'Run failed after provider validation.',
            ]],
            'completed_at' => now()->subMinutes(10),
        ]);

    StoredReport::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE,
        'payload' => [
            'raw_response_body' => 'stored-report-secret-body',
        ],
    ]);

    AuditLog::query()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'operation_run_id' => (int) $run->getKey(),
        'action' => 'operation.failed',
        'resource_type' => 'operation_run',
        'resource_id' => (string) $run->getKey(),
        'target_label' => 'Operation #'.$run->getKey(),
        'metadata' => [
            'raw_response_body' => 'audit-secret-body',
        ],
        'outcome' => 'success',
        'recorded_at' => now()->subMinutes(5),
    ]);

    $builder = app(SupportRequestContextBuilder::class);
    $envelope = $builder->forOperationRun($run, $user, true);
    $encoded = json_encode($envelope, JSON_THROW_ON_ERROR);

    expect($envelope['attachment_mode'])
        ->toBe(SupportRequestContextBuilder::ATTACHMENT_MODE_DIAGNOSTIC_SNAPSHOT_ATTACHED)
        ->and(data_get($envelope, 'primary_context.type'))
        ->toBe('operation_run')
        ->and(data_get($envelope, 'primary_context.operation_run_id'))
        ->toBe((int) $run->getKey())
        ->and(data_get($envelope, 'diagnostic_snapshot.redaction.mode'))
        ->toBe('default_redacted')
        ->and(data_get($envelope, 'diagnostic_snapshot.sections.0.key'))
        ->toBe('overview')
        ->and($encoded)
        ->not->toContain('raw-provider-secret-message')
        ->and($encoded)
        ->not->toContain('secret-provider-body')
        ->and($encoded)
        ->not->toContain('stored-report-secret-body')
        ->and($encoded)
        ->not->toContain('audit-secret-body');
});
