<?php

namespace App\Console\Commands;

use App\Jobs\DownloadAndStoreRecordingJob;
use App\Models\Communication\Recording;
use Illuminate\Console\Command;

/**
 * Re-downloads recordings that completed but never got a stored audio file.
 *
 * Historically DownloadAndStoreRecordingJob aborted whenever the call's
 * communicable was not a Client (e.g. first-contact "initial" inbound calls from
 * an unmatched number). Those recordings sit with status=completed and a
 * recording_url but no storage_path — so the Contact Screen can play no audio and
 * no transcript is ever produced. This sweep re-dispatches the (now fixed)
 * download job for them, which stores the file and kicks off transcription.
 */
class BackfillMissingRecordingFiles extends Command
{
    protected $signature = 'recordings:backfill-missing
        {--days=30 : Only reprocess recordings created within this many days}
        {--limit=0 : Cap the number reprocessed (0 = no cap)}
        {--dry-run : List what would be reprocessed without dispatching anything}';

    protected $description = 'Re-download completed call recordings that are missing their stored audio file so audio + transcripts load.';

    public function handle(): int
    {
        $days    = max(1, (int) $this->option('days'));
        $limit   = max(0, (int) $this->option('limit'));
        $dryRun  = (bool) $this->option('dry-run');

        // Console context: the BelongsToSolicitor global scope is inactive, so a
        // single pass covers every tenant.
        $query = Recording::query()
            ->where('status', 'completed')
            ->whereNotNull('recording_url')
            ->where(fn ($q) => $q->whereNull('storage_path')->orWhere('storage_path', ''))
            ->where('created_at', '>=', now()->subDays($days))
            ->orderBy('id');

        if ($limit > 0) {
            $query->limit($limit);
        }

        $recordings = $query->get();

        if ($recordings->isEmpty()) {
            $this->info("No completed recordings missing a stored file in the last {$days} day(s).");

            return self::SUCCESS;
        }

        foreach ($recordings as $recording) {
            if ($dryRun) {
                $this->line(sprintf(
                    '  #%d  sid=%s  created %s',
                    $recording->id,
                    $recording->provider_recording_sid ?? 'n/a',
                    optional($recording->created_at)->diffForHumans() ?? 'unknown',
                ));

                continue;
            }

            DownloadAndStoreRecordingJob::dispatch($recording->id);
        }

        $verb = $dryRun ? 'Would reprocess' : 'Dispatched download jobs for';
        $this->info("{$verb} {$recordings->count()} recording(s).");

        return self::SUCCESS;
    }
}
