<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Services\Maturity\ArtworkMaturityAuditService;
use App\Services\Maturity\ArtworkMaturityService;
use App\Services\Vision\VisionService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Throwable;

final class AuditArtworkMaturityThumbnailsCommand extends Command
{
    protected $signature = 'artworks:audit-thumbnail-maturity
        {--id= : Audit only this artwork ID}
        {--after-id=0 : Skip artworks with ID less than or equal to this value}
        {--limit= : Stop after processing this many artworks}
        {--chunk=25 : Number of artworks to scan per batch}
        {--variant= : Thumbnail variant to analyze (defaults to vision.image_variant)}
        {--refresh : Re-scan artworks that already have an open audit finding}
        {--dry-run : Report candidates without writing audit findings}';

    protected $description = 'Scan artwork thumbnails for possible mature content without mutating artwork maturity fields.';

    public function handle(VisionService $vision, ArtworkMaturityAuditService $audit): int
    {
        $artworkId = $this->option('id') !== null ? max(1, (int) $this->option('id')) : null;
        $afterId = max(0, (int) $this->option('after-id'));
        $limit = $this->option('limit') !== null ? max(1, (int) $this->option('limit')) : null;
        $chunkSize = max(1, min((int) $this->option('chunk'), 200));
        $dryRun = (bool) $this->option('dry-run');
        $refresh = (bool) $this->option('refresh');
        $variant = trim((string) ($this->option('variant') ?: config('vision.image_variant', 'md')));

        if (! $vision->isEnabled()) {
            $this->error('Vision maturity analysis is disabled.');

            return self::FAILURE;
        }

        if (! $dryRun && ! Schema::hasTable('artwork_maturity_audit_findings')) {
            $this->error('Artwork maturity audit findings table is missing. Run the latest database migrations first.');

            return self::FAILURE;
        }

        $this->info(sprintf(
            'Starting artwork maturity thumbnail audit. order=id_desc variant=%s chunk=%d limit=%s refresh=%s dry_run=%s',
            $variant !== '' ? $variant : 'md',
            $chunkSize,
            $limit !== null ? (string) $limit : 'all',
            $refresh ? 'yes' : 'no',
            $dryRun ? 'yes' : 'no',
        ));

        $query = $audit->eligibleArtworkQuery($refresh)
            ->orderByDesc('id');

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

        if ($afterId > 0) {
            $query->where('id', '>', $afterId);
        }
        
        $processed = 0;
        $flagged = 0;
        $safe = 0;
        $written = 0;
        $failed = 0;

        $query->chunkByIdDesc($chunkSize, function ($artworks) use ($vision, $audit, $variant, $limit, $dryRun, $refresh, &$processed, &$flagged, &$safe, &$written, &$failed) {
            foreach ($artworks as $artwork) {
                if ($limit !== null && $processed >= $limit) {
                    return false;
                }

                try {
                    $assessment = (array) ($vision->analyzeArtworkMaturityDetailed($artwork, (string) $artwork->hash, $variant)['assessment'] ?? []);
                    $processed++;

                    if ($audit->shouldOpenFinding($assessment)) {
                        $flagged++;
                        $message = sprintf(
                            'Artwork %d flagged for moderator review. action=%s confidence=%s label=%s',
                            (int) $artwork->id,
                            (string) ($assessment['action_hint'] ?? 'unknown'),
                            is_numeric($assessment['confidence'] ?? null) ? number_format((float) $assessment['confidence'], 4, '.', '') : 'n/a',
                            (string) ($assessment['maturity_label'] ?? 'unknown'),
                        );

                        $this->warn($message);
                        Log::warning('artworks:audit-thumbnail-maturity candidate detected', [
                            'artwork_id' => (int) $artwork->id,
                            'title' => (string) $artwork->title,
                            'assessment' => $assessment,
                            'variant' => $variant,
                        ]);

                        if (! $dryRun) {
                            $audit->recordFinding($artwork, $assessment, $variant !== '' ? $variant : 'md');
                            $written++;
                        }

                        continue;
                    }

                    if (($assessment['status'] ?? ArtworkMaturityService::AI_STATUS_FAILED) === ArtworkMaturityService::AI_STATUS_SUCCEEDED) {
                        $safe++;
                        $this->line(sprintf('Artwork %d scanned safe for audit purposes.', (int) $artwork->id));

                        if (! $dryRun && $refresh) {
                            $audit->markFindingCleared($artwork, 'Thumbnail maturity rescan no longer indicates moderator review.');
                        }

                        continue;
                    }

                    $failed++;
                    $this->warn(sprintf(
                        'Artwork %d maturity audit failed: %s',
                        (int) $artwork->id,
                        (string) ($assessment['advisory'] ?? $assessment['status'] ?? 'unknown failure'),
                    ));
                } catch (Throwable $exception) {
                    $processed++;
                    $failed++;
                    $this->warn(sprintf('Artwork %d audit failed: %s', (int) $artwork->id, $exception->getMessage()));
                    Log::warning('artworks:audit-thumbnail-maturity failed', [
                        'artwork_id' => (int) $artwork->id,
                        'title' => (string) $artwork->title,
                        'variant' => $variant,
                        'error' => $exception->getMessage(),
                    ]);
                }
            }

            return true;
        });

        $this->info(sprintf(
            'Artwork maturity thumbnail audit complete. processed=%d flagged=%d safe=%d written=%d failed=%d',
            $processed,
            $flagged,
            $safe,
            $written,
            $failed,
        ));

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