<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class MoveMediaToPublic extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'media:move-to-public {--dry-run : Show what would be moved without actually moving files}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Move all media files from private/local disk to public disk';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $dryRun = $this->option('dry-run');
        
        if ($dryRun) {
            $this->warn('DRY RUN MODE - No files will actually be moved');
        }

        // Get all media records using local disk
        $mediaRecords = Media::where('disk', 'local')->get();

        if ($mediaRecords->isEmpty()) {
            $this->info('No media records found using local disk.');
            return self::SUCCESS;
        }

        $this->info("Found {$mediaRecords->count()} media records to migrate.");

        $progressBar = $this->output->createProgressBar($mediaRecords->count());
        $progressBar->start();

        $moved = 0;
        $errors = 0;

        foreach ($mediaRecords as $media) {
            // Use relative path: {id}/{filename}
            $relativePath = $media->id . '/' . $media->file_name;

            // Check if source file exists
            if (!Storage::disk('local')->exists($relativePath)) {
                $this->newLine();
                $this->error("Source file not found: {$relativePath}");
                $errors++;
                $progressBar->advance();
                continue;
            }

            try {
                if (!$dryRun) {
                    // Copy file from local to public disk
                    $fileContent = Storage::disk('local')->get($relativePath);
                    Storage::disk('public')->put($relativePath, $fileContent);

                    // Verify the file was copied successfully
                    if (Storage::disk('public')->exists($relativePath)) {
                        // Update the database record
                        $media->update([
                            'disk' => 'public',
                            'conversions_disk' => 'public',
                        ]);

                        // Delete the old file from local disk
                        Storage::disk('local')->delete($relativePath);

                        $moved++;
                    } else {
                        throw new \Exception("Failed to copy file to public disk");
                    }
                } else {
                    $this->newLine();
                    $this->line("Would move: local:{$relativePath} -> public:{$relativePath}");
                    $moved++;
                }
            } catch (\Exception $e) {
                $this->newLine();
                $this->error("Error moving {$relativePath}: {$e->getMessage()}");
                $errors++;
            }

            $progressBar->advance();
        }

        $progressBar->finish();
        $this->newLine(2);

        if ($dryRun) {
            $this->info("DRY RUN: Would move {$moved} files, {$errors} errors encountered.");
            $this->info("Run without --dry-run to actually perform the migration.");
        } else {
            $this->info("Successfully moved {$moved} files, {$errors} errors encountered.");
        }

        return self::SUCCESS;
    }
}
