Sindbad~EG File Manager

Current Path : /home/zada/public_html/app/Services/
Upload File :
Current File : /home/zada/public_html/app/Services/AiService.php

<?php

namespace App\Services;

use App\Models\AiPrompt;
use App\Models\aiUsageLogs;
use App\Models\Language;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

class AiService
{
    public function productGenerateWithAI(array $data)
    {
        //Log::info('asf',$data);
       try {

            $productName  = trim($data['product_name'] ?? '');
            $section      = $data['section'] ?? null;
            $language     = $data['lang'] ?? default_language();
            $existingData = $data['existing_data'] ?? [];

            if(!$productName){
                return response()->json([
                    'success'=>false,
                    'message'=>'Product name is required'
                ]);
            }

            if(!$section){
                return response()->json([
                    'success'=>false,
                    'message'=>'Section is required'
                ]);
            }

            // language name
            $languageName = Language::where('code',$language)->value('name') ?? 'English';


            /*
            |--------------------------------------------------------------------------
            | Field Config
            |--------------------------------------------------------------------------
            */

            $fieldMap = [

                'basic-information'=>[
                    'fields'=>['name'],
                    'prompt_fields'=>"name: a clean, attractive, SEO-friendly product title (max 100 characters)",
                    'language_target'=>$languageName,
                ],

                'product-description'=>[
                    'fields'=>['description'],
                    'prompt_fields'=>"description: 2–4 paragraphs, attractive, benefit-focused HTML",
                    'language_target'=>$languageName,
                ],

                'product-seo-meta-tag'=>[
                    'fields'=>['meta_title','meta_description','meta_keywords'],
                    'prompt_fields'=>"meta_title, meta_description, meta_keywords (SEO optimized)",
                    'language_target'=>'English',
                ],

                'product-configuration'=>[
                    'fields'=>['unit','weight','min_qty','tags'],
                    'prompt_fields'=>"unit, weight (kg), min_qty, tags",
                    'language_target'=>$languageName,
                ],
            ];

            if(!isset($fieldMap[$section])){
                return response()->json([
                    'success'=>false,
                    'message'=>'Invalid section'
                ]);
            }

            $config = $fieldMap[$section];


            /*
            |--------------------------------------------------------------------------
            | Load Prompt From DB
            |--------------------------------------------------------------------------
            */

            $promptTemplate = AiPrompt::where('identifier','product_add_edit_prompt')
                ->value('prompt');

            if(!$promptTemplate){
                return response()->json([
                    'success'=>false,
                    'message'=>'AI prompt not configured'
                ]);
            }


            /*
            |--------------------------------------------------------------------------
            | Build Prompt
            |--------------------------------------------------------------------------
            */

            $prompt = str_replace(
                ['{product_name}','{language}','{prompt_fields}'],
                [$productName,$config['language_target'],$config['prompt_fields']],
                $promptTemplate
            );

            if(!empty($existingData)){
                $prompt .= "\nImprove this content:\n".json_encode($existingData);
            }


            /*
            |--------------------------------------------------------------------------
            | Gemini API Call
            |--------------------------------------------------------------------------
            */

            $model  = get_setting('gemini_model') ?? 'gemini-2.0-flash-lite';
            $apiKey = env('GEMINI_API_KEY');

            $response = Http::withHeaders([
                'Content-Type'=>'application/json'
            ])->post(
                "https://generativelanguage.googleapis.com/v1/models/{$model}:generateContent?key={$apiKey}",
                [
                    'contents'=>[
                        [
                            'parts'=>[
                                ['text'=>$prompt]
                            ]
                        ]
                    ],
                    'generationConfig'=>[
                        'temperature'=>0.7,
                        'topP'=>0.95,
                        'maxOutputTokens'=>1024
                    ]
                ]
            );

            if(!$response->successful()){

                Log::error('Gemini API Error', [
                    'status'=>$response->status(),
                    'response'=>$response->body()
                ]);

                return response()->json([
                    'success'=>false,
                    'message'=>'AI request failed'
                ]);
            }

            $result = $response->json();


            /*
            |--------------------------------------------------------------------------
            | Extract AI Text
            |--------------------------------------------------------------------------
            */

            $text = $result['candidates'][0]['content']['parts'][0]['text'] ?? '';

            if(!$text){
                return response()->json([
                    'success'=>false,
                    'message'=>'AI returned empty response'
                ]);
            }

            // Clean markdown code blocks
            $text = preg_replace('/^```json\s*|\s*```$/m','',$text);
            $text = preg_replace('/^```\s*|\s*```$/m','',$text);
            $text = trim($text);

            $data = json_decode($text,true);

            if(json_last_error() !== JSON_ERROR_NONE){

                Log::error('Invalid AI JSON', [
                    'response'=>$text,
                    'error'=>json_last_error_msg()
                ]);

                return response()->json([
                    'success'=>false,
                    'message'=>'Invalid AI JSON response'
                ]);
            }


            /*
            |--------------------------------------------------------------------------
            | Filter Needed Fields Only
            |--------------------------------------------------------------------------
            */

            $clean = [];

            foreach($config['fields'] as $field){
                $clean[$field] = $data[$field] ?? null;
            }


            /*
            |--------------------------------------------------------------------------
            | Token Usage
            |--------------------------------------------------------------------------
            */

            $tokenUsage = $result['usageMetadata'] ?? [];

            // Log::info('AI Usage',[
            //     'product'=>$productName,
            //     'section'=>$section,
            //     'tokens'=>$tokenUsage
            // ]);

            if (auth()->check()) {
                try {
                    $totalTokens = $tokenUsage['totalTokenCount'] ?? 0;
                    $promptTokens = $tokenUsage['promptTokenCount'] ?? 0;
                    $completionTokens = $tokenUsage['candidatesTokenCount'] ?? 0;
                    
                    aiUsageLogs::create([
                        'user_id' => auth()->id(),
                        'prompt_tokens' => $promptTokens,
                        'completion_tokens' => $completionTokens,
                        'total_tokens' => $totalTokens,
                        'model' => $model
                    ]);
                    
                } catch (\Exception $e) {
                    Log::error('Failed to log AI usage', ['error' => $e->getMessage()]);
                }
            }


            return response()->json([
                'success'=>true,
                'data'=>$clean,
                'section'=>$section,
                'language'=>$language,
                'is_regenerated'=>!empty($existingData),
                'tokens'=>$tokenUsage
            ]);

        }
        catch(\Exception $e){

            Log::error('AI Generate Error', [
                'message'=>$e->getMessage(),
                'trace'=>$e->getTraceAsString()
            ]);

            return response()->json([
                'success'=>false,
                'message'=>$e->getMessage()
            ],500);
        } 
    }

}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists (>^ω^<)看过哭02teddd(>^ω^<)看过哭02teddd