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, ], ], ]); } }