<?php

namespace App\Console\Commands;

use App\Services\DataverseService;
use Illuminate\Console\Command;
use Throwable;

/**
 * Purge finished AutoCount job rows from cr6f2_autocountjobs.
 *
 * The job table is an append-only work queue — runJob/dispatch insert rows but
 * nothing ever deletes them, so it grows forever. This command deletes rows in
 * a terminal state (done / error) older than N days. Pending/running rows are
 * never touched.
 *
 *   php artisan autocount:cleanup-jobs
 *   php artisan autocount:cleanup-jobs --days=14
 *   php artisan autocount:cleanup-jobs --dry-run
 *
 * Suggested cron (daily, 3am):
 *   0 3 * * * cd /path/to/syhc-api && /usr/local/bin/lsphp artisan autocount:cleanup-jobs >> storage/logs/cleanup-jobs.log 2>&1
 */
class CleanupAutoCountJobs extends Command
{
    protected $signature = 'autocount:cleanup-jobs
                            {--days=7 : Delete done/error rows older than this many days}
                            {--dry-run : Print what would be deleted, do not delete}';

    protected $description = 'Delete finished (done/error) AutoCount job rows older than N days.';

    public function handle(DataverseService $dv): int
    {
        $days   = max(0, (int) $this->option('days'));
        $dryRun = (bool) $this->option('dry-run');
        $table  = config('autocount.job_table', 'cr6f2_autocountjobs');

        $cutoff = now()->subDays($days)->toIso8601String();

        $this->info("Cleaning up '{$table}': done/error rows older than {$days} day(s) (before {$cutoff}).");
        if ($dryRun) $this->warn('Dry run — no deletions will be made.');
        $this->newLine();

        try {
            $rows = $dv->getAll($table, [
                'select' => ['cr6f2_autocountjobid', 'cr6f2_status', 'cr6f2_type', 'createdon'],
                'filter' => "(cr6f2_status eq 'done' or cr6f2_status eq 'error') and createdon lt {$cutoff}",
            ])['value'] ?? [];
        } catch (Throwable $e) {
            $this->error('Failed to fetch job rows: ' . $e->getMessage());
            return self::FAILURE;
        }

        $total = count($rows);
        if ($total === 0) {
            $this->info('Nothing to clean up.');
            return self::SUCCESS;
        }

        $this->info(($dryRun ? 'Would delete' : 'Deleting') . " {$total} row(s)...");

        $deleted = 0;
        $failed  = 0;
        foreach ($rows as $row) {
            $id = $row['cr6f2_autocountjobid'] ?? null;
            if (!$id) { continue; }
            if ($dryRun) { $deleted++; continue; }
            try {
                $dv->delete($table, $id);
                $deleted++;
            } catch (Throwable $e) {
                $failed++;
                $this->warn("  failed to delete {$id}: " . $e->getMessage());
            }
        }

        $this->newLine();
        $this->info(($dryRun ? 'Would delete' : 'Deleted') . " {$deleted} row(s)" . ($failed ? ", {$failed} failed." : '.'));

        return $failed > 0 ? self::FAILURE : self::SUCCESS;
    }
}
