<?php

declare(strict_types=1);

use App\Filament\Pages\ChooseEnvironment;
use App\Filament\Pages\ChooseWorkspace;
use App\Filament\Pages\EnvironmentDashboard;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Support\OperationRunLinks;
use App\Support\Workspaces\WorkspaceRedirectResolver;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->resolver = app(WorkspaceRedirectResolver::class);
});

it('redirects to managed tenants index when workspace has zero tenants', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $user->getKey(),
        'role' => 'owner',
    ]);

    $url = $this->resolver->resolve($workspace, $user);

    $expectedRoute = url('/admin/workspaces/'.($workspace->slug ?? $workspace->getKey()).'/environments');

    expect($url)->toBe($expectedRoute);
});

it('redirects to tenant dashboard when workspace has exactly one active tenant', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $user->getKey(),
        'role' => 'owner',
    ]);

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'status' => 'active',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $url = $this->resolver->resolve($workspace, $user);

    $expectedUrl = url('/admin/workspaces/'.($workspace->slug ?? $workspace->getKey()).'/environments/'.$tenant->getRouteKey());

    expect($url)->toBe($expectedUrl);
});

it('redirects to choose tenant page when workspace has multiple active tenants', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $user->getKey(),
        'role' => 'owner',
    ]);

    $tenantA = ManagedEnvironment::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'status' => 'active',
    ]);

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'status' => 'active',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenantA->getKey() => ['role' => 'owner'],
        $tenantB->getKey() => ['role' => 'owner'],
    ]);

    $url = $this->resolver->resolve($workspace, $user);

    expect($url)->toBe(url('/admin/workspaces/'.($workspace->slug ?? $workspace->getKey()).'/environments'));
});

it('falls back to chooser page when workspace ID is invalid', function (): void {
    $user = User::factory()->create();

    $url = $this->resolver->resolveFromId(999999, $user);

    expect($url)->toBe(ChooseWorkspace::getUrl());
});

it('resolves correctly from workspace ID', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $user->getKey(),
        'role' => 'owner',
    ]);

    $url = $this->resolver->resolveFromId((int) $workspace->getKey(), $user);

    $expectedRoute = url('/admin/workspaces/'.($workspace->slug ?? $workspace->getKey()).'/environments');

    expect($url)->toBe($expectedRoute);
});

it('preserves a safe intended admin url that targets a tenant in the selected workspace', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $user->getKey(),
        'role' => 'owner',
    ]);

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'status' => 'active',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $intendedUrl = OperationRunLinks::index($tenant);

    $url = $this->resolver->resolve($workspace, $user, $intendedUrl);

    expect($url)->toBe($intendedUrl);
});

it('rejects an unsafe intended admin url when its tenant hint targets another workspace', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'user_id' => $user->getKey(),
        'role' => 'owner',
    ]);

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => $workspace->getKey(),
        'status' => 'active',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $foreignTenant = ManagedEnvironment::factory()->create([
        'status' => 'active',
    ]);

    $intendedUrl = OperationRunLinks::index($foreignTenant);

    $url = $this->resolver->resolve($workspace, $user, $intendedUrl);

    expect($url)->toBe(url('/admin/workspaces/'.($workspace->slug ?? $workspace->getKey()).'/environments/'.$tenant->getRouteKey()));
});
