<?php

namespace App\Console\Commands;

use App\Models\CronLog;
use Illuminate\Console\Command;

class PruneCronLogs extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cron-logs:prune {--keep= : Rows to keep per (command, tenant) - defaults to config cron_logs.keep_per_task}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Trim cron_logs to the latest N rows per command+tenant (count-based retention)';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $keep = (int) ($this->option('keep') ?? config('cron_logs.keep_per_task', 10));

        if ($keep < 1) {
            $this->error('--keep must be at least 1.');

            return self::FAILURE;
        }

        // Keep the newest $keep rows per (command, tenant_id) group, delete the surplus.
        // The table is held small by frequent pruning, so selecting the lightweight
        // (id, command, tenant_id) columns and grouping in PHP stays cheap - and unlike a
        // window-function DELETE it runs the same on MariaDB and the SQLite test database.
        $surplusIds = CronLog::query()
            ->select(['id', 'command', 'tenant_id'])
            ->orderByDesc('id')
            ->get()
            ->groupBy(fn (CronLog $log) => $log->command . '|' . $log->tenant_id)
            ->flatMap(fn ($group) => $group->slice($keep)->pluck('id'))
            ->all();

        $deleted = 0;

        foreach (array_chunk($surplusIds, 1000) as $chunk) {
            $deleted += CronLog::query()->whereIn('id', $chunk)->delete();
        }

        $this->info("Pruned {$deleted} cron log rows, keeping the latest {$keep} per command+tenant.");

        return self::SUCCESS;
    }
}
