<?php

declare(strict_types=1);

use App\Models\ManagedEnvironment;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('returns the remembered environment when it remains selectable and entitled', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $tenant->getKey(),
    ]);

    $rememberedEnvironment = app(WorkspaceContext::class)->rememberedEnvironment(request());

    expect($rememberedEnvironment?->is($tenant))->toBeTrue();
});

it('clears remembered environment context when the stored environment belongs to another workspace', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $otherWorkspaceTenant = ManagedEnvironment::factory()->active()->create();

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $otherWorkspaceTenant->getKey(),
    ]);

    expect(app(WorkspaceContext::class)->rememberedEnvironment(request()))->toBeNull();
    expect(session()->get(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, []))
        ->not->toHaveKey((string) $tenant->workspace_id);
});

it('clears remembered environment context when the stored environment no longer exists', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $missingTenant = ManagedEnvironment::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    createUserWithTenant(tenant: $missingTenant, user: $user, role: 'owner');
    $missingTenantId = (int) $missingTenant->getKey();
    $missingTenant->forceDelete();

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => $missingTenantId,
    ]);

    expect(app(WorkspaceContext::class)->rememberedEnvironment(request()))->toBeNull();
    expect(session()->get(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, []))
        ->not->toHaveKey((string) $tenant->workspace_id);
});

it('clears remembered environment context when the actor is no longer entitled to the environment', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $nonEntitledTenant = ManagedEnvironment::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $nonEntitledTenant->getKey(),
    ]);

    expect(app(WorkspaceContext::class)->rememberedEnvironment(request()))->toBeNull();
    expect(session()->get(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, []))
        ->not->toHaveKey((string) $tenant->workspace_id);
});

it('clears remembered environment context when the environment becomes selector ineligible', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    createUserWithTenant(
        tenant: $onboardingTenant,
        user: $user,
        role: 'owner',
        workspaceRole: 'owner',
        ensureDefaultMicrosoftProviderConnection: false,
    );

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $onboardingTenant->getKey(),
    ]);

    expect(app(WorkspaceContext::class)->rememberedEnvironment(request()))->toBeNull();
    expect(session()->get(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, []))
        ->not->toHaveKey((string) $tenant->workspace_id);
});
