<?php

use App\Models\AuditLog;
use App\Models\ManagedEnvironmentMembership;
use App\Models\User;
use App\Models\WorkspaceMembership;
use App\Services\Auth\ManagedEnvironmentMembershipManager;
use App\Support\Audit\AuditActionId;

it('writes canonical audit action IDs for environment access-scope mutations', function () {
    [$owner, $tenant] = createUserWithTenant(role: 'owner');

    $member = User::factory()->create();
    WorkspaceMembership::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'user_id' => (int) $member->getKey(),
        'role' => 'readonly',
    ]);

    /** @var ManagedEnvironmentMembershipManager $manager */
    $manager = app(ManagedEnvironmentMembershipManager::class);

    $membership = $manager->grantScope(
        tenant: $tenant,
        actor: $owner,
        member: $member,
        source: 'manual',
    );

    $manager->removeMember(
        tenant: $tenant,
        actor: $owner,
        membership: $membership,
    );

    $logs = AuditLog::query()
        ->where('managed_environment_id', $tenant->id)
        ->whereIn('action', [
            AuditActionId::ManagedEnvironmentAccessScopeGrant->value,
            AuditActionId::ManagedEnvironmentAccessScopeRemove->value,
        ])
        ->get()
        ->keyBy('action');

    expect($logs)->toHaveCount(2);

    $grantLog = $logs->get(AuditActionId::ManagedEnvironmentAccessScopeGrant->value);
    $removeLog = $logs->get(AuditActionId::ManagedEnvironmentAccessScopeRemove->value);

    expect($grantLog)->not->toBeNull();
    expect($removeLog)->not->toBeNull();

    expect($grantLog->status)->toBe('success');
    expect($removeLog->status)->toBe('success');

    expect($grantLog->metadata)
        ->toHaveKey('member_user_id', $member->id)
        ->toHaveKey('workspace_role', 'readonly')
        ->toHaveKey('source', 'manual')
        ->not->toHaveKey('member_email')
        ->not->toHaveKey('member_name');

    expect($removeLog->metadata)
        ->toHaveKey('member_user_id', $member->id)
        ->not->toHaveKey('member_email')
        ->not->toHaveKey('member_name');
});

it('rejects managed-environment role-change attempts without writing role-change audit truth', function () {
    [$owner, $tenant] = createUserWithTenant(role: 'owner');

    $membership = ManagedEnvironmentMembership::query()
        ->where('managed_environment_id', $tenant->id)
        ->where('user_id', $owner->id)
        ->firstOrFail();

    /** @var ManagedEnvironmentMembershipManager $manager */
    $manager = app(ManagedEnvironmentMembershipManager::class);

    expect(fn () => $manager->changeRole(
        tenant: $tenant,
        actor: $owner,
        membership: $membership,
        newRole: 'manager',
    ))->toThrow(DomainException::class);

    expect(AuditLog::query()
        ->where('managed_environment_id', $tenant->id)
        ->where('action', AuditActionId::TenantMembershipRoleChange->value)
        ->exists())->toBeFalse();
});
