<?php

namespace Tests\Feature;

use App\Livewire\Audit\Index;
use App\Models\AuditEvent;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Livewire\Livewire;
use Tests\TestCase;

class AuditRetentionTest extends TestCase
{
    use RefreshDatabase;

    /** Seed an audit_events row with an explicit created_at timestamp. */
    private function seedEvent(Carbon $createdAt, string $action = 'test.event'): AuditEvent
    {
        return AuditEvent::forceCreate([
            'actor' => 'tester',
            'action' => $action,
            'target' => null,
            'ip' => '127.0.0.1',
            'created_at' => $createdAt,
            'updated_at' => $createdAt,
        ]);
    }

    public function test_prune_deletes_events_older_than_retention_and_keeps_newer(): void
    {
        Setting::put('audit_retention_days', '30');

        $old = $this->seedEvent(now()->subDays(45), 'old.event');
        $recent = $this->seedEvent(now()->subDays(5), 'recent.event');

        $this->artisan('clusev:prune-audit')->assertExitCode(0);

        $this->assertDatabaseMissing('audit_events', ['id' => $old->id]);
        $this->assertDatabaseHas('audit_events', ['id' => $recent->id]);
    }

    public function test_prune_with_zero_retention_deletes_nothing(): void
    {
        Setting::put('audit_retention_days', '0');

        $old = $this->seedEvent(now()->subDays(1000), 'ancient.event');

        $this->artisan('clusev:prune-audit')->assertExitCode(0);

        $this->assertDatabaseHas('audit_events', ['id' => $old->id]);
    }

    public function test_prune_with_empty_retention_deletes_nothing(): void
    {
        // No setting persisted at all → treated as unlimited.
        $old = $this->seedEvent(now()->subDays(1000), 'ancient.event');

        $this->artisan('clusev:prune-audit')->assertExitCode(0);

        $this->assertDatabaseHas('audit_events', ['id' => $old->id]);
    }

    public function test_audit_component_saves_retention_and_writes_audit_event(): void
    {
        $this->actingAs(User::factory()->create(['must_change_password' => false]));

        Livewire::test(Index::class)
            ->set('retentionDays', '30')
            ->call('saveRetention')
            ->assertHasNoErrors();

        $this->assertSame('30', Setting::get('audit_retention_days'));

        $this->assertDatabaseHas('audit_events', [
            'action' => 'audit.retention_set',
            'target' => 'audit_retention_days=30',
        ]);
    }
}
