<?php

declare(strict_types=1);

use App\Models\AuditLog;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Services\Settings\SettingsWriter;
use App\Support\Audit\AuditActionId;

it('writes a workspace-scoped audit entry when a workspace setting is updated', 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',
    ]);

    app(SettingsWriter::class)->updateWorkspaceSetting(
        actor: $user,
        workspace: $workspace,
        domain: 'backup',
        key: 'retention_keep_last_default',
        value: 44,
    );

    $audit = AuditLog::query()->latest('id')->first();

    expect($audit)->not->toBeNull()
        ->and($audit?->workspace_id)->toBe((int) $workspace->getKey())
        ->and($audit?->managed_environment_id)->toBeNull()
        ->and($audit?->action)->toBe(AuditActionId::WorkspaceSettingUpdated->value)
        ->and(data_get($audit?->metadata, 'domain'))->toBe('backup')
        ->and(data_get($audit?->metadata, 'key'))->toBe('retention_keep_last_default')
        ->and(data_get($audit?->metadata, 'scope'))->toBe('workspace')
        ->and(data_get($audit?->metadata, 'before_value'))->toBeNull()
        ->and(data_get($audit?->metadata, 'after_value'))->toBe(44);
});

it('writes a workspace-scoped audit entry when a workspace setting is reset', 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',
    ]);

    $writer = app(SettingsWriter::class);

    $writer->updateWorkspaceSetting(
        actor: $user,
        workspace: $workspace,
        domain: 'backup',
        key: 'retention_keep_last_default',
        value: 48,
    );

    $writer->resetWorkspaceSetting(
        actor: $user,
        workspace: $workspace,
        domain: 'backup',
        key: 'retention_keep_last_default',
    );

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

    expect($audit)->not->toBeNull()
        ->and($audit?->workspace_id)->toBe((int) $workspace->getKey())
        ->and($audit?->managed_environment_id)->toBeNull()
        ->and(data_get($audit?->metadata, 'scope'))->toBe('workspace')
        ->and(data_get($audit?->metadata, 'before_value'))->toBe(48)
        ->and(data_get($audit?->metadata, 'after_value'))->toBe(30);
});

it('writes a workspace-scoped audit entry when ai policy mode is updated', 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',
    ]);

    app(SettingsWriter::class)->updateWorkspaceSetting(
        actor: $user,
        workspace: $workspace,
        domain: 'ai',
        key: 'policy_mode',
        value: 'private_only',
    );

    $audit = AuditLog::query()->latest('id')->first();

    expect($audit)->not->toBeNull()
        ->and($audit?->workspace_id)->toBe((int) $workspace->getKey())
        ->and($audit?->managed_environment_id)->toBeNull()
        ->and($audit?->action)->toBe(AuditActionId::WorkspaceSettingUpdated->value)
        ->and(data_get($audit?->metadata, 'domain'))->toBe('ai')
        ->and(data_get($audit?->metadata, 'key'))->toBe('policy_mode')
        ->and(data_get($audit?->metadata, 'scope'))->toBe('workspace')
        ->and(data_get($audit?->metadata, 'before_value'))->toBeNull()
        ->and(data_get($audit?->metadata, 'after_value'))->toBe('private_only');
});

it('writes a workspace-scoped audit entry when ai policy mode is reset', 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',
    ]);

    $writer = app(SettingsWriter::class);

    $writer->updateWorkspaceSetting(
        actor: $user,
        workspace: $workspace,
        domain: 'ai',
        key: 'policy_mode',
        value: 'private_only',
    );

    $writer->resetWorkspaceSetting(
        actor: $user,
        workspace: $workspace,
        domain: 'ai',
        key: 'policy_mode',
    );

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

    expect($audit)->not->toBeNull()
        ->and($audit?->workspace_id)->toBe((int) $workspace->getKey())
        ->and($audit?->managed_environment_id)->toBeNull()
        ->and(data_get($audit?->metadata, 'domain'))->toBe('ai')
        ->and(data_get($audit?->metadata, 'key'))->toBe('policy_mode')
        ->and(data_get($audit?->metadata, 'scope'))->toBe('workspace')
        ->and(data_get($audit?->metadata, 'before_value'))->toBe('private_only')
        ->and(data_get($audit?->metadata, 'after_value'))->toBe('disabled');
});
