<?php

use App\Models\BackupItem;
use App\Models\BackupSet;
use App\Models\Policy;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Services\Intune\BackupService;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function () {
    $this->tenant = ManagedEnvironment::create([
        'managed_environment_id' => 'tenant-123',
        'name' => 'Test ManagedEnvironment',
    ]);
    $this->tenant->makeCurrent();

    $this->user = User::factory()->create();
    $this->actingAs($this->user);

    $this->policy = Policy::create([
        'managed_environment_id' => $this->tenant->id,
        'external_id' => 'policy-456',
        'policy_type' => 'settingsCatalogPolicy',
        'display_name' => 'Test Policy',
        'platform' => 'windows',
    ]);

    $this->backupSet = BackupSet::create([
        'managed_environment_id' => $this->tenant->id,
        'name' => 'Test Backup Set',
        'status' => 'completed',
        'created_by' => $this->user->email,
    ]);
});

it('excludes soft-deleted items when listing available policies to add', function () {
    // Create a backup item
    $backupItem = BackupItem::create([
        'managed_environment_id' => $this->tenant->id,
        'backup_set_id' => $this->backupSet->id,
        'policy_id' => $this->policy->id,
        'policy_identifier' => $this->policy->external_id,
        'policy_type' => $this->policy->policy_type,
        'platform' => $this->policy->platform,
        'payload' => ['test' => 'data'],
        'captured_at' => now(),
    ]);

    // Get available policies (should be empty since policy is already in backup)
    $existingPolicyIds = $this->backupSet->items()->pluck('policy_id')->filter()->all();

    expect($existingPolicyIds)->toContain($this->policy->id);

    // Soft-delete the backup item
    $backupItem->delete();

    // Verify it's soft-deleted
    expect($this->backupSet->items()->count())->toBe(0);
    expect($this->backupSet->items()->withTrashed()->count())->toBe(1);

    // Get available policies again - soft-deleted items should NOT be in the list (UI can re-add them)
    $existingPolicyIds = $this->backupSet->items()->pluck('policy_id')->filter()->all();

    expect($existingPolicyIds)->not->toContain($this->policy->id)
        ->and($existingPolicyIds)->toHaveCount(0);
});

it('prevents re-adding soft-deleted policies via BackupService', function () {
    // Create initial backup item
    $backupItem = BackupItem::create([
        'managed_environment_id' => $this->tenant->id,
        'backup_set_id' => $this->backupSet->id,
        'policy_id' => $this->policy->id,
        'policy_identifier' => $this->policy->external_id,
        'policy_type' => $this->policy->policy_type,
        'platform' => $this->policy->platform,
        'payload' => ['test' => 'data'],
        'captured_at' => now(),
    ]);

    // Soft-delete it
    $backupItem->delete();

    // Try to add the same policy again via BackupService
    $service = app(BackupService::class);

    $result = $service->addPoliciesToSet(
        tenant: $this->tenant,
        backupSet: $this->backupSet->refresh(),
        policyIds: [$this->policy->id],
        actorEmail: $this->user->email,
        actorName: $this->user->name,
    );

    // Should restore the soft-deleted item, not create a new one
    expect($this->backupSet->items()->count())->toBe(1)
        ->and($this->backupSet->items()->withTrashed()->count())->toBe(1)
        ->and($result->item_count)->toBe(1)
        ->and($backupItem->fresh()->deleted_at)->toBeNull(); // Item should be restored
});

it('allows adding different policy after one was soft-deleted', function () {
    // Create initial backup item
    $backupItem = BackupItem::create([
        'managed_environment_id' => $this->tenant->id,
        'backup_set_id' => $this->backupSet->id,
        'policy_id' => $this->policy->id,
        'policy_identifier' => $this->policy->external_id,
        'policy_type' => $this->policy->policy_type,
        'platform' => $this->policy->platform,
        'payload' => ['test' => 'data'],
        'captured_at' => now(),
    ]);

    // Soft-delete it
    $backupItem->delete();

    // Create a different policy
    $otherPolicy = Policy::create([
        'managed_environment_id' => $this->tenant->id,
        'external_id' => 'policy-789',
        'policy_type' => 'settingsCatalogPolicy',
        'display_name' => 'Other Policy',
        'platform' => 'windows',
    ]);

    // Check available policies - should include the new one but not the deleted one
    $existingPolicyIds = $this->backupSet->items()->withTrashed()->pluck('policy_id')->filter()->all();

    expect($existingPolicyIds)->toContain($this->policy->id)
        ->and($existingPolicyIds)->not->toContain($otherPolicy->id);
});
