<?php

declare(strict_types=1);

use App\Filament\Pages\CrossEnvironmentComparePage;
use App\Jobs\Operations\CrossEnvironmentPromotionExecutionJob;
use App\Models\OperationRun;
use App\Support\OperationRunLinks;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Livewire\Livewire;
use Tests\Feature\Concerns\BuildsPortfolioCompareFixtures;

uses(RefreshDatabase::class, BuildsPortfolioCompareFixtures::class);

it('uses the shared queued and deduped start-result ux for promotion execution', function (): void {
    Queue::fake();

    $fixture = $this->makeCrossEnvironmentCompareFixture();

    $this->createPortfolioCompareSubject(
        tenant: $fixture['sourceEnvironment'],
        displayName: 'Run UX Policy',
        snapshot: ['settings' => [['key' => 'ux', 'value' => 1]]],
    );

    $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']);

    $query = [
        'source_environment_id' => (int) $fixture['sourceEnvironment']->getKey(),
        'target_environment_id' => (int) $fixture['targetEnvironment']->getKey(),
        'policy_type' => ['deviceConfiguration'],
    ];

    $component = Livewire::withQueryParams($query)
        ->actingAs($fixture['user'])
        ->test(CrossEnvironmentComparePage::class)
        ->call('generatePromotionPreflight')
        ->mountAction('executePromotion')
        ->callMountedAction()
        ->assertHasNoActionErrors()
        ->assertNotified('Promotion execution queued');

    $run = OperationRun::query()->latest('id')->first();

    expect($run)->not->toBeNull()
        ->and($run?->type)->toBe('promotion.execute')
        ->and(data_get($run?->context, 'required_capability'))->toBe('tenant.manage')
        ->and(data_get($run?->context, 'workspace_required_capability'))->toBe('workspace_baselines.manage')
        ->and(data_get($run?->context, 'target_scope.workspace_id'))->toBe((int) $fixture['workspace']->getKey())
        ->and(data_get($run?->context, 'selection.sourceEnvironmentId'))->toBe((int) $fixture['sourceEnvironment']->getKey())
        ->and(data_get($run?->context, 'selection.targetEnvironmentId'))->toBe((int) $fixture['targetEnvironment']->getKey());

    $component
        ->mountAction('executePromotion')
        ->callMountedAction()
        ->assertHasNoActionErrors()
        ->assertNotified('Promotion execution already running');

    expect(OperationRun::query()->where('type', 'promotion.execute')->count())->toBe(1);

    Queue::assertPushed(CrossEnvironmentPromotionExecutionJob::class, 1);

    $this->actingAs($fixture['user'])
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey()])
        ->get(OperationRunLinks::tenantlessView($run))
        ->assertOk();
});