<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Services\TagNormalizer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

/**
 * One-time (and idempotent) command to convert slug-style tag names to
 * human-readable display names.
 *
 * A tag is considered "slug-style" when its name is identical to its slug
 * (e.g. name="digital-art", slug="digital-art").  Tags that already have a
 * custom name (user-edited) are left untouched.
 *
 * Usage:
 *   php artisan tags:fix-names
 *   php artisan tags:fix-names --dry-run
 */
final class FixTagNamesCommand extends Command
{
    protected $signature = 'tags:fix-names
        {--dry-run : Show what would change without writing to the database}
    ';

    protected $description = 'Convert slug-style tag names (e.g. "digital-art") to readable names ("Digital Art")';

    public function __construct(private readonly TagNormalizer $normalizer)
    {
        parent::__construct();
    }

    public function handle(): int
    {
        $dryRun = (bool) $this->option('dry-run');

        if ($dryRun) {
            $this->warn('DRY-RUN — no changes will be written.');
        }

        // Only fix rows where name === slug (those were created by the old code).
        $rows = DB::table('tags')
            ->whereColumn('name', 'slug')
            ->orderBy('id')
            ->get(['id', 'name', 'slug']);

        if ($rows->isEmpty()) {
            $this->info('Nothing to fix — all tag names are already human-readable.');
            return self::SUCCESS;
        }

        $this->info("Found {$rows->count()} tag(s) with slug-style names.");

        $updated = 0;
        $bar     = $this->output->createProgressBar($rows->count());
        $bar->start();

        foreach ($rows as $row) {
            $displayName = $this->normalizer->toDisplayName($row->slug);

            if ($displayName === $row->name) {
                $bar->advance();
                continue; // Already correct (e.g. single-word tag "cars" → "Cars" — wait, that would differ)
            }

            if ($this->output->isVerbose()) {
                $this->newLine();
                $this->line("  {$row->slug}  →  \"{$displayName}\"");
            }

            if (!$dryRun) {
                DB::table('tags')
                    ->where('id', $row->id)
                    ->update(['name' => $displayName]);
            }

            $updated++;
            $bar->advance();
        }

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

        $suffix = $dryRun ? ' (dry-run, nothing written)' : '';
        $this->info("Updated {$updated} of {$rows->count()} tag(s){$suffix}.");

        return self::SUCCESS;
    }
}
