<?php

declare(strict_types=1);

use App\Jobs\ExecuteRestoreRunJob;
use App\Models\BackupSet;
use App\Models\RestoreRun;
use App\Notifications\OperationRunCompleted;
use App\Services\Intune\AuditLogger;
use App\Services\Intune\RestoreService;
use App\Services\OperationRunService;
use Filament\Facades\Filament;

it('persists exactly one canonical terminal notification for initiated restore execution runs', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $tenant->forceFill([
        'rbac_status' => 'ok',
        'rbac_last_checked_at' => now(),
    ])->saveQuietly();

    $this->actingAs($user);

    $tenant->makeCurrent();
    Filament::setTenant($tenant, true);

    $backupSet = BackupSet::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
    ]);

    $restoreRun = RestoreRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'backup_set_id' => (int) $backupSet->getKey(),
        'requested_by' => $user->email,
        'status' => 'queued',
        'started_at' => null,
        'completed_at' => null,
    ]);

    /** @var OperationRunService $operationRuns */
    $operationRuns = app(OperationRunService::class);
    $operationRun = $operationRuns->ensureRun(
        tenant: $tenant,
        type: 'restore.execute',
        inputs: [
            'restore_run_id' => (int) $restoreRun->getKey(),
            'backup_set_id' => (int) $backupSet->getKey(),
            'is_dry_run' => (bool) ($restoreRun->is_dry_run ?? false),
        ],
        initiator: $user,
    );

    $operationRun->forceFill([
        'user_id' => (int) $user->getKey(),
        'initiator_name' => $user->name,
    ])->save();

    $this->mock(RestoreService::class, function ($mock) use ($restoreRun): void {
        $mock->shouldReceive('executeForRun')
            ->once()
            ->andReturnUsing(function () use ($restoreRun): RestoreRun {
                RestoreRun::query()->whereKey($restoreRun->getKey())->update([
                    'status' => 'completed',
                    'completed_at' => now(),
                ]);

                return RestoreRun::query()->findOrFail($restoreRun->getKey());
            });
    });

    $job = new ExecuteRestoreRunJob(
        restoreRunId: (int) $restoreRun->getKey(),
        actorEmail: $user->email,
        actorName: $user->name,
        operationRun: $operationRun,
    );

    expect($user->notifications()->count())->toBe(0);

    $job->handle(app(RestoreService::class), app(AuditLogger::class));

    $operationRun->refresh();

    expect($operationRun->status)->toBe('completed');
    expect($operationRun->outcome)->toBe('succeeded');
    expect($user->notifications()->count())->toBe(1);

    $this->assertDatabaseHas('notifications', [
        'notifiable_id' => $user->getKey(),
        'notifiable_type' => $user->getMorphClass(),
        'type' => OperationRunCompleted::class,
    ]);
})->group('ops-ux');
