<?php

use App\Models\OperationRun;
use App\Models\RestoreRun;
use App\Support\RestoreRunStatus;

it('creates an operation run only from previewed onward', function () {
    $restoreRun = RestoreRun::factory()->create([
        'status' => RestoreRunStatus::Checked->value,
    ]);

    expect(OperationRun::query()
        ->where('managed_environment_id', $restoreRun->managed_environment_id)
        ->where('type', 'restore.execute')
        ->count())->toBe(0);

    $restoreRun->update(['status' => RestoreRunStatus::Previewed->value]);

    $opRun = OperationRun::query()
        ->where('managed_environment_id', $restoreRun->managed_environment_id)
        ->where('type', 'restore.execute')
        ->latest('id')
        ->first();

    expect($opRun)->not->toBeNull();
    expect($opRun?->status)->toBe('completed');
    expect($opRun?->outcome)->toBe('succeeded');
    expect($opRun?->context)->toMatchArray([
        'restore_run_id' => (int) $restoreRun->getKey(),
        'backup_set_id' => (int) $restoreRun->backup_set_id,
        'is_dry_run' => (bool) $restoreRun->is_dry_run,
    ]);
});

it('updates the operation run when restore completes', function () {
    $restoreRun = RestoreRun::factory()->create([
        'status' => RestoreRunStatus::Queued->value,
        'metadata' => [
            'total' => 3,
            'succeeded' => 1,
            'failed' => 1,
            'skipped' => 1,
        ],
    ]);

    $opRun = OperationRun::query()
        ->where('managed_environment_id', $restoreRun->managed_environment_id)
        ->where('type', 'restore.execute')
        ->latest('id')
        ->first();

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

    $restoreRun->update([
        'status' => RestoreRunStatus::Completed->value,
        'metadata' => [
            'total' => 3,
            'succeeded' => 1,
            'failed' => 1,
            'skipped' => 1,
        ],
    ]);

    $opRun->refresh();

    expect($opRun->status)->toBe('completed');
    expect($opRun->outcome)->toBe('succeeded');
    expect($opRun->summary_counts)->toMatchArray([
        'total' => 3,
        'succeeded' => 1,
        'failed' => 1,
        'skipped' => 1,
    ]);
    expect($opRun->completed_at)->not->toBeNull();
});

it('maps cancelled restore runs to failed outcome (cancelled is reserved)', function () {
    $restoreRun = RestoreRun::factory()->create([
        'status' => RestoreRunStatus::Queued->value,
    ]);

    $opRun = OperationRun::query()
        ->where('managed_environment_id', $restoreRun->managed_environment_id)
        ->where('type', 'restore.execute')
        ->latest('id')
        ->first();

    expect($opRun)->not->toBeNull();

    $restoreRun->update(['status' => RestoreRunStatus::Cancelled->value]);

    $opRun->refresh();

    expect($opRun->status)->toBe('completed');
    expect($opRun->outcome)->toBe('failed');
    expect($opRun->failure_summary)->toBeArray();
    expect($opRun->failure_summary[0]['code'] ?? null)->toBe('restore.cancelled');
});
