<?php

namespace App\Http\Controllers;

use App\Jobs\GenerateImageCreativeJob;
use App\Jobs\RenderVideoCreativeJob;
use App\Models\Creative;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class CreativeController extends Controller
{
    public function index(Request $request): View
    {
        $sortable = ['id', 'status', 'source', 'created'];
        $sort = in_array($request->query('sort'), $sortable, true) ? $request->query('sort') : 'created';
        $dir = $request->query('dir') === 'asc' ? 'asc' : 'desc';
        $perPage = in_array((int) $request->query('per_page'), [10, 25, 50], true) ? (int) $request->query('per_page') : 10;

        $query = $request->user()->creatives()
            ->when($request->filled('status') && $request->query('status') !== 'all', fn ($q) => $q->where('status', $request->query('status')))
            ->when($request->filled('source') && $request->query('source') !== 'all', fn ($q) => $q->where('source', $request->query('source')))
            ->when($request->filled('q'), fn ($q) => $q->where(fn ($q2) => $q2
                ->where('prompt', 'like', '%'.$request->query('q').'%')
                ->orWhere('product_url', 'like', '%'.$request->query('q').'%')
            ))
            ->orderBy($sort === 'created' ? 'created_at' : $sort, $dir);

        $creatives = $query->paginate($perPage)->withQueryString();

        $stats = [
            'all' => $request->user()->creatives()->count(),
            'completed' => $request->user()->creatives()->where('status', 'completed')->count(),
            'active' => $request->user()->creatives()->whereIn('status', ['queued', 'processing', 'generating'])->count(),
            'failed' => $request->user()->creatives()->where('status', 'failed')->count(),
        ];

        return view('creatives.index', ['creatives' => $creatives, 'stats' => $stats, 'sort' => $sort, 'dir' => $dir]);
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'source' => 'required|in:prompt,product_url',
            'prompt' => 'required_if:source,prompt|nullable|string|max:2000',
            'product_url' => 'required_if:source,product_url|nullable|url|max:2000',
            'ratio' => 'required|in:1:1,4:5,9:16,16:9',
            'style' => 'nullable|string|max:255',
        ]);

        $creative = $request->user()->creatives()->create([
            'type' => 'image',
            'status' => 'queued',
            'source' => $validated['source'],
            'ratio' => $validated['ratio'],
            'style' => $validated['style'] ?? null,
            'product_url' => $validated['product_url'] ?? null,
            'prompt' => $validated['prompt'] ?? null,
        ]);

        try {
            GenerateImageCreativeJob::dispatch($creative->id);
        } catch (\Throwable $e) {
            // The job already records failure on the creative before rethrowing
            // (so queue workers can retry it); with the sync driver that rethrow
            // would otherwise surface as a 500 instead of the failed-status page.
        }

        return redirect()->route('creatives.show', $creative);
    }

    public function show(Creative $creative): View
    {
        $this->authorizeCreative($creative);

        return view('creatives.show', ['creative' => $creative]);
    }

    public function destroy(Creative $creative): RedirectResponse
    {
        $this->authorizeCreative($creative);

        $creative->delete();

        return redirect()->route('creatives.index');
    }

    public function regenerate(Creative $creative): RedirectResponse
    {
        $this->authorizeCreative($creative);

        $creative->update([
            'status' => $creative->type === 'video' ? 'queued' : 'generating',
            'failure_reason' => null,
            'asset_path' => null,
            'thumbnail_path' => null,
        ]);

        if ($creative->type === 'video') {
            RenderVideoCreativeJob::dispatch(
                $creative->id,
                $creative->avatar_id,
                $creative->voice_id,
                $creative->script,
                $creative->storyboard,
                $creative->duration,
                $creative->ratio,
            );
        } else {
            try {
                GenerateImageCreativeJob::dispatch($creative->id);
            } catch (\Throwable $e) {
                // The job already records failure on the creative before rethrowing
                // (so queue workers can retry it); with the sync driver that rethrow
                // would otherwise surface as a 500 instead of the failed-status page.
            }
        }

        return redirect()->route('creatives.show', $creative);
    }

    private function authorizeCreative(Creative $creative): void
    {
        abort_unless($creative->user_id === auth()->id(), 403);
    }
}
