<?php

declare(strict_types=1);

namespace App\Http\Controllers\Settings;

use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Models\ArtworkMaturityAuditFinding;
use App\Models\User;
use App\Services\Maturity\ArtworkMaturityAuditService;
use App\Services\Maturity\ArtworkMaturityService;
use App\Services\ThumbnailPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;

final class ArtworkMaturityAdminController extends Controller
{
    public function __construct(
        private readonly ArtworkMaturityService $maturity,
        private readonly ArtworkMaturityAuditService $audit,
    )
    {
    }

    public function index(Request $request): Response
    {
        $stats = $this->queueStats();
        $status = $this->initialStatus($request, $stats);
        $routes = $this->routeNamesForRequest($request);

        return Inertia::render('Moderation/ArtworkMaturityQueue', [
            'title' => 'Artwork Maturity Queue',
            'initialItems' => $this->queueItems($status),
            'initialFilters' => [
                'status' => $status,
                'ai_action' => 'all',
                'ai_status' => 'all',
            ],
            'stats' => $stats,
            'endpoints' => [
                'list' => route($routes['list']),
                'reviewPattern' => route($routes['review'], ['artwork' => '__ARTWORK__']),
            ],
            'filterOptions' => [
                'aiAction' => [
                    ['value' => 'all', 'label' => 'All actions'],
                    ['value' => ArtworkMaturityService::AI_ACTION_SAFE, 'label' => 'Safe'],
                    ['value' => ArtworkMaturityService::AI_ACTION_REVIEW, 'label' => 'Review'],
                    ['value' => ArtworkMaturityService::AI_ACTION_FLAG_HIGH, 'label' => 'Flag high'],
                ],
                'aiStatus' => [
                    ['value' => 'all', 'label' => 'All statuses'],
                    ['value' => ArtworkMaturityService::AI_STATUS_SUCCEEDED, 'label' => 'Succeeded'],
                    ['value' => ArtworkMaturityService::AI_STATUS_PENDING, 'label' => 'Pending'],
                    ['value' => ArtworkMaturityService::AI_STATUS_FAILED, 'label' => 'Failed'],
                    ['value' => ArtworkMaturityService::AI_STATUS_SKIPPED, 'label' => 'Skipped'],
                ],
            ],
            'reviewActions' => [
                ['value' => 'mark_safe', 'label' => 'Mark safe'],
                ['value' => 'mark_mature', 'label' => 'Mark mature'],
                ['value' => 'confirm_current', 'label' => 'Confirm current state'],
            ],
        ])->rootView('moderation');
    }

    public function list(Request $request): JsonResponse
    {
        $status = $this->normalizeStatus((string) $request->query('status', 'suspected'));
        $aiAction = strtolower((string) $request->query('ai_action', 'all'));
        $aiStatus = strtolower((string) $request->query('ai_status', 'all'));

        return response()->json([
            'data' => $this->queueItems($status, $aiAction, $aiStatus),
            'meta' => [
                'stats' => $this->queueStats(),
                'status' => $status,
                'filters' => [
                    'ai_action' => $aiAction,
                    'ai_status' => $aiStatus,
                ],
            ],
        ]);
    }

    public function review(Request $request, Artwork $artwork): JsonResponse
    {
        $validated = $request->validate([
            'action' => ['required', 'in:mark_safe,mark_mature,confirm_current'],
            'note' => ['nullable', 'string', 'max:2000'],
        ]);

        /** @var User $moderator */
        $moderator = $request->user('controlpanel') ?? $request->user() ?? abort(403, 'Admin access required.');
        $artwork = $this->maturity->review($artwork, (string) $validated['action'], $moderator, $validated['note'] ?? null);
        $this->audit->resolveFindingForReview($artwork, $moderator, (string) $validated['action'], $validated['note'] ?? null);

        return response()->json([
            'success' => true,
            'artwork' => $this->mapQueueItem($artwork->loadMissing(['user.profile', 'group', 'categories.contentType'])),
            'stats' => $this->queueStats(),
        ]);
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function queueItems(string $status, string $aiAction = 'all', string $aiStatus = 'all'): array
    {
        if ($status === 'audit') {
            return $this->auditQueueItems($aiAction, $aiStatus);
        }

        $query = Artwork::query()
            ->with(['user.profile', 'group', 'categories.contentType'])
            ->where(function ($builder): void {
                $builder->where('maturity_status', ArtworkMaturityService::STATUS_SUSPECTED)
                    ->orWhere(function ($reviewed): void {
                        $reviewed->where('maturity_status', ArtworkMaturityService::STATUS_REVIEWED)
                            ->whereNotNull('maturity_reviewed_at');
                    });
            })
            ->latest('maturity_flagged_at')
            ->latest('published_at')
            ->limit(100);

        if ($status === 'reviewed') {
            $query->where('maturity_status', ArtworkMaturityService::STATUS_REVIEWED);
        } else {
            $query->where('maturity_status', ArtworkMaturityService::STATUS_SUSPECTED);
        }

        if (in_array($aiAction, [
            ArtworkMaturityService::AI_ACTION_SAFE,
            ArtworkMaturityService::AI_ACTION_REVIEW,
            ArtworkMaturityService::AI_ACTION_FLAG_HIGH,
        ], true)) {
            $query->where('maturity_ai_action_hint', $aiAction);
        }

        if (in_array($aiStatus, [
            ArtworkMaturityService::AI_STATUS_SUCCEEDED,
            ArtworkMaturityService::AI_STATUS_PENDING,
            ArtworkMaturityService::AI_STATUS_FAILED,
            ArtworkMaturityService::AI_STATUS_SKIPPED,
        ], true)) {
            $query->where('maturity_ai_status', $aiStatus);
        }

        return $query->get()->map(fn (Artwork $artwork): array => $this->mapQueueItem($artwork))->all();
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function auditQueueItems(string $aiAction = 'all', string $aiStatus = 'all'): array
    {
        $query = $this->audit->openFindingsQuery()
            ->latest('detected_at')
            ->latest('updated_at')
            ->limit(100);

        if (in_array($aiAction, [
            ArtworkMaturityService::AI_ACTION_SAFE,
            ArtworkMaturityService::AI_ACTION_REVIEW,
            ArtworkMaturityService::AI_ACTION_FLAG_HIGH,
        ], true)) {
            $query->where('ai_action_hint', $aiAction);
        }

        if (in_array($aiStatus, [
            ArtworkMaturityService::AI_STATUS_SUCCEEDED,
            ArtworkMaturityService::AI_STATUS_PENDING,
            ArtworkMaturityService::AI_STATUS_FAILED,
            ArtworkMaturityService::AI_STATUS_SKIPPED,
            ArtworkMaturityService::AI_STATUS_NOT_REQUESTED,
        ], true)) {
            $query->where('ai_status', $aiStatus);
        }

        return $query->get()->map(fn (ArtworkMaturityAuditFinding $finding): array => $this->mapAuditQueueItem($finding))->all();
    }

    /**
     * @return array<string, int>
     */
    private function queueStats(): array
    {
        return [
            'suspected' => (int) Artwork::query()->where('maturity_status', ArtworkMaturityService::STATUS_SUSPECTED)->count(),
            'audit' => $this->audit->openFindingsCount(),
            'reviewed' => (int) Artwork::query()->where('maturity_status', ArtworkMaturityService::STATUS_REVIEWED)->count(),
            'mature' => (int) Artwork::query()->where('is_mature', true)->count(),
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function mapAuditQueueItem(ArtworkMaturityAuditFinding $finding): array
    {
        $artwork = $finding->artwork;

        return $this->mapQueueItem($artwork, [
            'status' => (string) $finding->status,
            'thumbnail_variant' => $finding->thumbnail_variant,
            'detected_at' => optional($finding->detected_at)->toIsoString(),
            'last_scanned_at' => optional($finding->last_scanned_at)->toIsoString(),
            'ai_label' => $finding->ai_label,
            'ai_confidence' => $finding->ai_confidence,
            'ai_score' => $finding->ai_score,
            'ai_labels' => $finding->ai_labels,
            'ai_model' => $finding->ai_model,
            'ai_threshold_used' => $finding->ai_threshold_used,
            'ai_analysis_time_ms' => $finding->ai_analysis_time_ms,
            'ai_action_hint' => $finding->ai_action_hint,
            'ai_status' => $finding->ai_status,
            'ai_advisory' => $finding->ai_advisory,
            'legacy_unset' => $this->audit->isArtworkEligible($artwork),
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    private function mapQueueItem(Artwork $artwork, ?array $audit = null): array
    {
        $category = $artwork->categories->sortBy('sort_order')->first();
        $publisherName = $artwork->group?->name ?: $artwork->user?->name ?: $artwork->user?->username ?: 'Artist';
        $thumb = ThumbnailPresenter::present($artwork, 'md');
        $preview = ThumbnailPresenter::present($artwork, 'xl');

        return [
            'id' => (int) $artwork->id,
            'title' => (string) $artwork->title,
            'url' => route('art.show', ['id' => $artwork->id, 'slug' => Str::slug((string) ($artwork->slug ?: $artwork->title)) ?: (string) $artwork->id]),
            'admin_url' => route('admin.cp.artworks.edit', ['id' => $artwork->id]),
            'thumbnail' => $thumb['url'] ?? null,
            'preview_image' => $preview['url'] ?? ($thumb['url'] ?? null),
            'publisher' => $publisherName,
            'published_at' => optional($artwork->published_at)->toIsoString(),
            'content_type' => $category?->contentType?->name,
            'category' => $category?->name,
            'maturity' => $this->maturity->presentation($artwork, null),
            'audit' => $audit,
            'review' => [
                'reviewed_at' => optional($artwork->maturity_reviewed_at)->toIsoString(),
                'reviewed_by' => $artwork->maturity_reviewed_by,
                'reviewer_note' => $artwork->maturity_reviewer_note,
            ],
        ];
    }

    private function normalizeStatus(string $status): string
    {
        $normalized = Str::lower(trim($status));

        return in_array($normalized, ['suspected', 'reviewed', 'audit'], true)
            ? $normalized
            : 'suspected';
    }

    /**
     * @param array<string, int> $stats
     */
    private function initialStatus(Request $request, array $stats): string
    {
        if ($request->query->has('status')) {
            return $this->normalizeStatus((string) $request->query('status'));
        }

        if (($stats['suspected'] ?? 0) > 0) {
            return 'suspected';
        }

        if (($stats['audit'] ?? 0) > 0) {
            return 'audit';
        }

        if (($stats['reviewed'] ?? 0) > 0) {
            return 'reviewed';
        }

        return 'suspected';
    }

    /**
     * @return array{list: string, review: string}
     */
    private function routeNamesForRequest(Request $request): array
    {
        $routeName = (string) $request->route()?->getName();

        if (Str::startsWith($routeName, 'admin.cp.artworks.maturity.')) {
            return [
                'list' => 'admin.cp.artworks.maturity.queue',
                'review' => 'admin.cp.artworks.maturity.review',
            ];
        }

        return [
            'list' => 'cp.maturity.list',
            'review' => 'cp.maturity.review',
        ];
    }
}