<?php

declare(strict_types=1);

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

uses(RefreshDatabase::class);

it('returns the remembered tenant 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_TENANT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $tenant->getKey(),
    ]);

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

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

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

    $this->actingAs($user);

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

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

it('clears remembered tenant context when the stored tenant no longer exists', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $missingTenant = Tenant::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_TENANT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => $missingTenantId,
    ]);

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

it('clears remembered tenant context when the actor is no longer entitled to the tenant', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $nonEntitledTenant = Tenant::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_TENANT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $nonEntitledTenant->getKey(),
    ]);

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

it('clears remembered tenant context when the tenant becomes selector ineligible', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $onboardingTenant = Tenant::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_TENANT_IDS_SESSION_KEY, [
        (string) $tenant->workspace_id => (int) $onboardingTenant->getKey(),
    ]);

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