<?php

declare(strict_types=1);

namespace App\Http\Controllers\Studio;

use App\Http\Controllers\Controller;
use App\Services\Uploads\UploadQueueService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

final class StudioUploadQueueApiController extends Controller
{
    public function index(Request $request, UploadQueueService $queue): JsonResponse
    {
        return response()->json(
            $queue->listPayload($request->user(), $request->only(['batch_id', 'status', 'sort']))
        );
    }

    public function store(Request $request, UploadQueueService $queue): JsonResponse
    {
        $validated = $request->validate([
            'name' => ['nullable', 'string', 'max:160'],
            'files' => ['required', 'array', 'min:1', 'max:50'],
            'files.*.name' => ['required', 'string', 'max:255'],
            'defaults' => ['nullable', 'array'],
            'defaults.category_id' => ['nullable', 'integer', 'exists:categories,id'],
            'defaults.tags' => ['nullable', 'array', 'max:' . (int) config('tags.max_user_tags', 30)],
            'defaults.tags.*' => ['string', 'max:64'],
            'defaults.visibility' => ['nullable', 'string', 'in:public,unlisted,private'],
            'defaults.is_mature' => ['nullable', 'boolean'],
            'defaults.group' => ['nullable', 'string', 'max:90'],
        ]);

        $batch = $queue->createBatch(
            $request->user(),
            (array) $validated['files'],
            (array) ($validated['defaults'] ?? []),
            Arr::get($validated, 'name')
        );

        return response()->json([
            'batch' => [
                'id' => (int) $batch->id,
                'name' => $batch->name,
            ],
            'items' => $batch->items->map(fn ($item): array => [
                'id' => (int) $item->id,
                'artwork_id' => (int) $item->artwork_id,
                'original_filename' => (string) $item->original_filename,
            ])->values()->all(),
            'queue' => $queue->listPayload($request->user(), ['batch_id' => (int) $batch->id]),
        ], 201);
    }

    public function markFailed(Request $request, int $id, UploadQueueService $queue): JsonResponse
    {
        $validated = $request->validate([
            'error_code' => ['nullable', 'string', 'max:64'],
            'error_message' => ['nullable', 'string', 'max:4000'],
        ]);

        $queue->markItemFailedForUser(
            $request->user(),
            $id,
            (string) ($validated['error_code'] ?? 'upload_failed'),
            (string) ($validated['error_message'] ?? 'Upload failed before processing completed.')
        );

        return response()->json(['ok' => true]);
    }

    public function bulk(Request $request, UploadQueueService $queue): JsonResponse
    {
        $validated = $request->validate([
            'action' => ['required', 'string', 'in:publish,delete,apply_category,apply_tags,set_visibility,generate_ai'],
            'item_ids' => ['required', 'array', 'min:1', 'max:200'],
            'item_ids.*' => ['integer'],
            'params' => ['nullable', 'array'],
            'params.category_id' => ['nullable', 'integer', 'exists:categories,id'],
            'params.tags' => ['nullable', 'array', 'max:' . (int) config('tags.max_user_tags', 30)],
            'params.tags.*' => ['string', 'max:64'],
            'params.visibility' => ['nullable', 'string', 'in:public,unlisted,private'],
            'confirm' => ['required_if:action,delete', 'string'],
        ]);

        if (($validated['action'] ?? '') === 'delete' && ($validated['confirm'] ?? '') !== 'DELETE') {
            return response()->json([
                'errors' => ['You must type DELETE to confirm draft deletion.'],
                'success' => 0,
                'failed' => count((array) ($validated['item_ids'] ?? [])),
            ], 422);
        }

        $result = $queue->bulkAction(
            $request->user(),
            (string) $validated['action'],
            (array) $validated['item_ids'],
            (array) ($validated['params'] ?? [])
        );

        return response()->json($result, $result['success'] > 0 ? 200 : 422);
    }

    public function retry(Request $request, int $id, UploadQueueService $queue): JsonResponse
    {
        $queue->retryProcessingForUser($request->user(), $id);

        return response()->json(['ok' => true]);
    }
}