<?php

use App\Jobs\BulkPolicyVersionPruneJob;
use App\Models\Policy;
use App\Models\PolicyVersion;
use App\Models\Tenant;
use App\Models\User;
use App\Services\BulkOperationService;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);
test('job prunes eligible versions and skips ineligible with reasons', function () {
    $tenant = Tenant::factory()->create();
    $user = User::factory()->create();

    $policyA = Policy::factory()->create(['tenant_id' => $tenant->id]);
    $eligible = PolicyVersion::factory()->create([
        'tenant_id' => $tenant->id,
        'policy_id' => $policyA->id,
        'version_number' => 1,
        'captured_at' => now()->subDays(120),
    ]);
    $current = PolicyVersion::factory()->create([
        'tenant_id' => $tenant->id,
        'policy_id' => $policyA->id,
        'version_number' => 2,
        'captured_at' => now()->subDays(120),
    ]);

    $policyB = Policy::factory()->create(['tenant_id' => $tenant->id]);
    $tooRecent = PolicyVersion::factory()->create([
        'tenant_id' => $tenant->id,
        'policy_id' => $policyB->id,
        'version_number' => 1,
        'captured_at' => now()->subDays(10),
    ]);
    PolicyVersion::factory()->create([
        'tenant_id' => $tenant->id,
        'policy_id' => $policyB->id,
        'version_number' => 2,
        'captured_at' => now()->subDays(10),
    ]);

    $service = app(BulkOperationService::class);
    $run = $service->createRun(
        $tenant,
        $user,
        'policy_version',
        'prune',
        [$eligible->id, $current->id, $tooRecent->id],
        3
    );

    (new BulkPolicyVersionPruneJob($run->id, 90))->handle($service);

    $run->refresh();
    expect($run->status)->toBe('completed')
        ->and($run->processed_items)->toBe(3)
        ->and($run->succeeded)->toBe(1)
        ->and($run->skipped)->toBe(2)
        ->and($run->failed)->toBe(0);

    expect($eligible->refresh()->trashed())->toBeTrue();
    expect($current->refresh()->trashed())->toBeFalse();
    expect($tooRecent->refresh()->trashed())->toBeFalse();

    expect($run->failures)->toBeArray();
    expect(collect($run->failures)->pluck('type')->all())->toContain('skipped');

    $reasons = collect($run->failures)->pluck('reason')->all();
    expect($reasons)->toContain('Current version')
        ->and($reasons)->toContain('Too recent');
});

test('job records failure when version is missing', function () {
    $tenant = Tenant::factory()->create();
    $user = User::factory()->create();

    $service = app(BulkOperationService::class);
    $run = $service->createRun($tenant, $user, 'policy_version', 'prune', [999999], 1);

    (new BulkPolicyVersionPruneJob($run->id, 90))->handle($service);

    $run->refresh();
    expect($run->status)->toBe('aborted')
        ->and($run->failed)->toBe(1)
        ->and($run->processed_items)->toBe(1);
});

test('job skips already archived versions instead of treating them as missing', function () {
    $tenant = Tenant::factory()->create();
    $user = User::factory()->create();

    $policy = Policy::factory()->create(['tenant_id' => $tenant->id]);
    $archived = PolicyVersion::factory()->create([
        'tenant_id' => $tenant->id,
        'policy_id' => $policy->id,
        'version_number' => 1,
        'captured_at' => now()->subDays(120),
    ]);
    $archived->delete();

    $service = app(BulkOperationService::class);
    $run = $service->createRun($tenant, $user, 'policy_version', 'prune', [$archived->id], 1);

    (new BulkPolicyVersionPruneJob($run->id, 90))->handle($service);

    $run->refresh();

    expect($run->status)->toBe('completed')
        ->and($run->processed_items)->toBe(1)
        ->and($run->succeeded)->toBe(0)
        ->and($run->skipped)->toBe(1)
        ->and($run->failed)->toBe(0);

    $reasons = collect($run->failures)->pluck('reason')->all();
    expect($reasons)->toContain('Already archived');
});
