<?php

namespace App\Http\Controllers;

use App\Helpers\FirstParty\Credits\CreditsService;
use App\Jobs\GenerateMemeJob;
use App\Models\Category;
use App\Models\UserMemeGeneration;
use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class UserAIController extends Controller
{
    public function generateMeme(Request $request)
    {
        $user = Auth::user();

        // Check if user has an active job
        $activeJobId = Cache::get("user_active_job_{$user->id}");
        if ($activeJobId) {
            $activeGeneration = UserMemeGeneration::where('job_id', $activeJobId)
                ->where('user_id', $user->id)
                ->whereIn('status', ['pending', 'processing'])
                ->first();

            if ($activeGeneration) {
                return response()->json([
                    'error' => [
                        'message' => 'You already have a meme generation in progress. Please wait for it to complete.',
                    ],
                ], 400);
            }
        }

        if (! CreditsService::canSpend($user->id, 2)) {
            return response()->json([
                'error' => [
                    'message' => 'You do not have enough credits to generate a meme. Please purchase credits from the Store.',
                ],
            ]);
        }

        CreditsService::spend($user->id, 2);

        $jobId = Str::uuid()->toString();

        // Create database record
        $generation = UserMemeGeneration::create([
            'user_id' => $user->id,
            'job_id' => $jobId,
            'prompt' => $request->prompt,
            'status' => 'pending',
            'credits_to_be_charged' => 2,
            'credits_are_processed' => false,
        ]);

        // Set active job in cache
        Cache::put("user_active_job_{$user->id}", $jobId, 300);
        Cache::put("meme_job_status_{$jobId}", 'pending', 300);

        $job = new GenerateMemeJob($user->id, $request->prompt, $jobId);
        dispatch($job);

        return response()->json([
            'success' => [
                'data' => [
                    'job_id' => $jobId,
                    'status' => 'pending',
                ],
            ],
        ]);
    }

    public function checkMemeJobStatus(Request $request)
    {
        $jobId = $request->job_id;

        if (! $jobId) {
            return response()->json([
                'error' => [
                    'message' => 'Job ID is required.',
                ],
            ], 400);
        }

        $status = Cache::get("meme_job_status_{$jobId}");

        if (! $status) {
            return response()->json([
                'error' => [
                    'message' => 'Job not found or expired.',
                ],
            ], 404);
        }

        $response = [
            'success' => [
                'data' => [
                    'job_id' => $jobId,
                    'status' => $status,
                ],
            ],
        ];

        if ($status === 'completed') {
            $result = Cache::get("meme_job_result_{$jobId}");
            if ($result) {
                $response['success']['data']['result'] = $result;
            }
        } elseif ($status === 'failed') {
            $error = Cache::get("meme_job_error_{$jobId}");
            if ($error) {
                $response['success']['data']['error'] = $error;
            }
        }

        return response()->json($response);
    }

    public function getActiveJob()
    {
        $user = Auth::user();

        $activeJobId = Cache::get("user_active_job_{$user->id}");

        if (! $activeJobId) {
            return response()->json([
                'success' => [
                    'data' => null,
                ],
            ]);
        }

        $generation = UserMemeGeneration::where('job_id', $activeJobId)
            ->where('user_id', $user->id)
            ->with('meme.meme_media', 'meme.background_media')
            ->first();

        if (! $generation) {
            // Clean up stale cache
            Cache::forget("user_active_job_{$user->id}");

            return response()->json([
                'success' => [
                    'data' => null,
                ],
            ]);
        }

        $response = [
            'success' => [
                'data' => [
                    'job_id' => $generation->job_id,
                    'status' => $generation->status,
                    'prompt' => $generation->prompt,
                    'created_at' => $generation->created_at,
                ],
            ],
        ];

        // If completed, include the meme result
        if ($generation->status === 'completed' && $generation->meme) {
            $meme = $generation->meme;
            $meme_media = $generation->meme->meme_media;

            $response['success']['data']['result'] = [
                'generate' => [
                    'info' => $meme,
                    'caption' => $meme->caption,
                    'meme' => $meme_media,
                    'background' => $meme->background_media,
                ],
            ];
        }

        return response()->json($response);
    }

    public function getMemeHistory()
    {
        $user = Auth::user();

        $generations = UserMemeGeneration::where('user_id', $user->id)
            ->with('meme.meme_media', 'meme.background_media')
            ->orderBy('created_at', 'desc')
            ->limit(20)
            ->get();

        $history = $generations->map(function ($generation) {
            $data = [
                'job_id' => $generation->job_id,
                'prompt' => $generation->prompt,
                'status' => $generation->status,
                'created_at' => $generation->created_at,
            ];

            if ($generation->status === 'completed' && $generation->meme) {
                $meme = $generation->meme;
                $data['meme'] = [
                    'info' => $meme,
                    'caption' => $meme->caption,
                    'meme_media' => $meme->meme_media,
                    'background_media' => $meme->background_media,
                ];
            }

            return $data;
        });

        return response()->json([
            'success' => [
                'data' => [
                    'history' => $history,
                ],
            ],
        ]);
    }

    public function aiHints()
    {
        $categories = Category::whereNotNull('keywords')
            ->inRandomOrder()
            ->take(8)
            ->get();

        if ($categories->isEmpty()) {
            return response()->json([
                'success' => [
                    'data' => [
                        'keywords' => [],
                    ],
                ],
            ]);
        }

        $keywords = $categories->map(function ($category) {
            return collect($category->keywords)->random();
        })->toArray();

        return response()->json([
            'success' => [
                'data' => [
                    'keywords' => $keywords,
                ],
            ],
        ]);
    }
}
