<?php

declare(strict_types=1);

use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    Http::preventStrayRequests();
});

it('serves the managed-tenants page without Livewire update failures', function (): void {
    $user = User::factory()->create();

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

    // 1. Load the page
    $response = $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(route('admin.workspace.managed-environments.index', ['workspace' => $workspace]));

    $response->assertSuccessful();

    $html = $response->getContent();

    // This landing page must not include Livewire-driven panel widgets that
    // trigger background updates (lazy-loaded database notifications, progress poller).
    expect($html)->not->toContain('Filament\\Livewire\\DatabaseNotifications');
    expect($html)->not->toContain('__lazyLoad');
    expect($html)->not->toContain('x-data="opsUxProgressWidgetPoller()"');

    // 2. Extract the first Livewire component snapshot
    preg_match('/wire:snapshot="([^"]+)"/', $html, $snapshotMatch);
    expect($snapshotMatch)->not->toBeEmpty('No Livewire snapshot found in page HTML');

    $snapshotJson = htmlspecialchars_decode($snapshotMatch[1]);
    $snapshot = json_decode($snapshotJson, true);

    expect($snapshot)->toBeArray();
    expect($snapshot['memo']['path'] ?? null)->toBe('admin/workspaces/'.$workspace->getKey().'/environments');

    // 3. POST a Livewire update request
    $updatePayload = [
        'components' => [[
            'snapshot' => $snapshotJson,
            'updates' => new \stdClass,
            'calls' => [],
        ]],
    ];

    // Get the Livewire update URI path (includes hash prefix)
    $routes = app('router')->getRoutes();
    $updateRoute = null;
    foreach ($routes as $route) {
        if (str_contains($route->getName() ?? '', 'livewire.update')) {
            $updateRoute = $route;
            break;
        }
    }
    expect($updateRoute)->not->toBeNull('Livewire update route must exist');

    $updateResponse = $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->withHeaders([
            'X-Livewire' => 'true',
        ])
        ->postJson('/'.$updateRoute->uri(), $updatePayload);

    $updateResponse->assertSuccessful();
});
