<?php

namespace App\Console\Commands;

use App\Models\Video;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class CleanupOrphanedVideos extends Command
{
    protected $signature = 'cleanup:orphaned-videos {--dry-run : List orphans without deleting (default)} {--force : Actually delete orphans}';
    protected $description = 'Remove orphaned video files not linked to any database record';

    public function handle()
    {
        $dryRun = $this->option('dry-run') !== false;
        $force = $this->option('force');

        if (!$dryRun && !$force) {
            $this->warn('Use --dry-run (default) to preview, or --force to delete.');
            return 1;
        }

        $this->info($dryRun ? 'DRY RUN MODE - No files will be deleted.' : 'FORCE MODE - Deleting orphaned files.');

        $disk = Storage::disk('public');
        $videoDir = 'videos';
        $files = $disk->files($videoDir);

        if (empty($files)) {
            $this->info('No video files found in storage/app/public/videos/');
            return 0;
        }

        // Get all valid filenames from DB (exact match for filename column)
        $dbFilenames = Video::pluck('filename')->filter()->toArray();
        $orphans = [];

        foreach ($files as $file) {
            // Only video files (skip non-videos)
            if (!str_ends_with($file, '.mp4') && !str_ends_with($file, '.webm') && !str_ends_with($file, '.mov')) {
                continue;
            }

            $basename = basename($file);

            // Check if exact match or compressed_ prefix with base in DB
            $isOrphan = true;
            if (in_array($basename, $dbFilenames)) {
                $isOrphan = false;
            } elseif (str_starts_with($basename, 'compressed_')) {
                $originalBasename = substr($basename, 10); // remove 'compressed_'
                if (in_array($originalBasename, $dbFilenames)) {
                    $isOrphan = false;
                }
            }

            if ($isOrphan) {
                $orphans[] = $file;
            }
        }

        $totalFiles = count($files);
        $orphanCount = count($orphans);

        $this->table(
            ['Stat', 'Value'],
            [
                ['Total video files scanned', $totalFiles],
                ['Orphaned files found', $orphanCount],
            ]
        );

        if ($orphanCount === 0) {
            $this->info('No orphaned videos found! ✅');
            Log::channel('orphaned-videos')->info('Cleanup run: 0 orphans found.');
            return 0;
        }

        if ($dryRun) {
            $this->table(['Orphan Files (would delete)'], array_map(fn($f) => [ $f ], $orphans));
            Log::channel('orphaned-videos')->info('DRY RUN: Found ' . $orphanCount . ' orphans', ['files' => $orphans]);
            $this->warn("Run with --force to delete these files.");
        } else {
            $bar = $this->output->createProgressBar($orphanCount);
            $bar->start();

            foreach ($orphans as $orphan) {
                $disk->delete($orphan);
                Log::channel('orphaned-videos')->info('Deleted orphan: ' . $orphan);
                $bar->advance();
            }

            $bar->finish();
            $this->newLine();
            $this->info("✅ Deleted {$orphanCount} orphaned video files.");
        }

        return 0;
    }
}
