<?php

declare(strict_types=1);

use App\Jobs\ExecuteRestoreRunJob;
use App\Models\OperationRun;
use App\Models\RestoreRun;
use App\Services\Intune\AuditLogger;
use App\Services\Intune\RestoreService;
use App\Services\OperationRunService;

it('syncs restore execution into OperationRun even if restore status updates bypass model events', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $tenant->forceFill([
        'rbac_status' => 'ok',
        'rbac_last_checked_at' => now(),
    ])->saveQuietly();

    $this->actingAs($user);

    $backupSet = \App\Models\BackupSet::factory()->create([
        'managed_environment_id' => $tenant->id,
    ]);

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

    // Canonical OperationRun must exist at dispatch time and be passed into the job.
    $operationRun = app(OperationRunService::class)->ensureRun(
        tenant: $tenant,
        type: 'restore.execute',
        inputs: [
            'restore_run_id' => $restoreRun->id,
            'backup_set_id' => $backupSet->id,
            'is_dry_run' => (bool) ($restoreRun->is_dry_run ?? false),
        ],
        initiator: $user,
    );

    expect($operationRun)->not->toBeNull();
    expect($operationRun?->status)->toBe('queued');

    // Simulate downstream code updating RestoreRun status via query builder (no model events).
    $this->mock(RestoreService::class, function ($mock) use ($restoreRun): void {
        $mock->shouldReceive('executeForRun')
            ->once()
            ->andReturnUsing(function () use ($restoreRun): RestoreRun {
                RestoreRun::query()->whereKey($restoreRun->id)->update([
                    'status' => 'completed',
                    'completed_at' => now(),
                ]);

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

    $job = new ExecuteRestoreRunJob($restoreRun->id, null, null, $operationRun);
    $job->handle(
        app(RestoreService::class),
        app(AuditLogger::class),
    );

    $operationRun = $operationRun?->fresh();

    expect($operationRun)->not->toBeNull();
    expect($operationRun?->status)->toBe('completed');
    expect($operationRun?->outcome)->toBe('succeeded');
    expect($operationRun?->completed_at)->not->toBeNull();
})->group('ops-ux');
