<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\Artwork;
use App\Services\Images\ArtworkSquareThumbnailBackfillService;
use Illuminate\Console\Command;
use Throwable;

final class GenerateMissingSquareThumbnailsCommand extends Command
{
    protected $signature = 'artworks:generate-missing-sq-thumbs
        {--id= : Generate only for this artwork ID}
        {--limit= : Stop after processing this many artworks}
        {--force : Regenerate even if an sq variant row already exists}
        {--dry-run : Report what would be generated without writing files}';

    protected $description = 'Generate missing smart square artwork thumbnails';

    public function handle(ArtworkSquareThumbnailBackfillService $backfill): int
    {
        $artworkId = $this->option('id') !== null ? max(1, (int) $this->option('id')) : null;
        $limit = $this->option('limit') !== null ? max(1, (int) $this->option('limit')) : null;
        $force = (bool) $this->option('force');
        $dryRun = (bool) $this->option('dry-run');

        $query = Artwork::query()
            ->whereNotNull('hash')
            ->where('hash', '!=', '')
            ->orderBy('id');

        if ($artworkId !== null) {
            $query->whereKey($artworkId);
        }

        $processed = 0;
        $generated = 0;
        $planned = 0;
        $skipped = 0;
        $failed = 0;

        $query->chunkById(100, function ($artworks) use ($backfill, $force, $dryRun, $limit, &$processed, &$generated, &$planned, &$skipped, &$failed) {
            foreach ($artworks as $artwork) {
                if ($limit !== null && $processed >= $limit) {
                    return false;
                }

                try {
                    $result = $backfill->ensureSquareThumbnail($artwork, $force, $dryRun);
                    $status = (string) ($result['status'] ?? 'skipped');

                    if ($status === 'generated') {
                        $generated++;
                    } elseif ($status === 'dry_run') {
                        $planned++;
                    } else {
                        $skipped++;
                    }
                } catch (Throwable $e) {
                    $failed++;
                    $this->warn(sprintf('Artwork %d failed: %s', (int) $artwork->getKey(), $e->getMessage()));
                }

                $processed++;
            }

            return true;
        });

        $this->info(sprintf(
            'Square thumbnail backfill complete. processed=%d generated=%d planned=%d skipped=%d failed=%d',
            $processed,
            $generated,
            $planned,
            $skipped,
            $failed,
        ));

        return $failed > 0 ? self::FAILURE : self::SUCCESS;
    }
}