<?php

declare(strict_types=1);

namespace App\Jobs;

use App\Models\AuditLog;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

/**
 * Monthly prune of audit_logs rows older than 24 months, per
 * docs/05-performance-and-scale.md §8 — never one giant DELETE (locks +
 * binlog); chunks of 5,000 with the same 40s-budget self-redispatch
 * pattern as the import/export jobs.
 */
class PruneAuditLogsJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private const CHUNK_SIZE = 5000;

    private const TIME_BUDGET_SECONDS = 40;

    private const RETENTION_MONTHS = 24;

    public function handle(): void
    {
        $cutoff = now()->subMonths(self::RETENTION_MONTHS);
        $startTime = microtime(true);

        while (true) {
            $deleted = AuditLog::query()
                ->where('created_at', '<', $cutoff)
                ->limit(self::CHUNK_SIZE)
                ->delete();

            if ($deleted === 0) {
                return;
            }

            if (microtime(true) - $startTime > self::TIME_BUDGET_SECONDS) {
                self::dispatch();

                return;
            }
        }
    }
}
