<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Mtc\MercuryDataModels\Media;
use Symfony\Component\Console\Helper\ProgressBar;

class ConvertLegacyMediaFilesToNonLegacy extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'media:convert-legacy-files';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Convert files from legacy structure to new format';

    private bool $move = false;

    private ProgressBar $progressBar;

    public function handle()
    {
        if (empty(tenant('id'))) {
            $this->output->error('Please run for a tenant');
            return self::FAILURE;
        }

        $this->move = $this->confirm('Perform live migration (if no it will perform dry run)?');

        $sizes = collect(Storage::disk('media')->directories(tenant('id')))
            ->keyBy(fn($folder) => $folder)
            ->map(function ($folder) {
                $parts = explode('/', $folder);
                $size = end($parts);
                if (preg_match("/[0-9]{1,4}x[0-9]{1,4}/", $size)) {
                    return $size;
                }
                return null;
            })
            ->filter();

        $count = Media::query()->where('type', 'image')->where('legacy_structure', 1)->count();
        $this->output->info("$count entries to convert");
        $this->progressBar = $this->output->createProgressBar($count);

        Media::query()
            ->where('type', 'image')
            ->where('legacy_structure', 1)
            ->whereNull('external')
            ->chunk(100, fn(Collection $chunk) => $chunk->each(fn(Media $item) => $this->migrateFile($item, $sizes)));
        return self::SUCCESS;
    }

    private function migrateFile(Media $item, Collection $sizes): void
    {
        $source_path = $item->path . '/' . $item->src;
        $destination = $item->path . '/orig/' . substr($item->src, 0, 2) . '/' . substr($item->src, 0, 4);
        $destination_path = $destination . '/' . $item->src;

        // Move original
        if ($this->move) {
            $this->progressBar->advance();
            Storage::disk('media')->move($source_path, $destination_path);
        } else {
            $this->output->info("Moving original from $source_path to $destination_path");
        }
        foreach ($sizes as $size_origin => $size) {
            $size_destination = str_replace("/orig/", "/$size/", $destination_path);
            if (Storage::disk('media')->exists($size_origin . '/' . $item->src)) {
                if ($this->move) {
                    Storage::disk('media')->move($size_origin . '/' . $item->src, $size_destination);
                } else {
                    $this->output->info("Size $size_origin/$item->src => $size_destination");
                }
            }
        }
        if ($this->move) {
            $item->path = $destination;
            $item->legacy_structure = null;
            $item->save();
        }
    }
}
