[ [ 'parts' => [ ['fileData' => ['mimeType' => 'application/pdf', 'fileUri' => $fileUri]], ['text' => $prompt] ] ] ], 'generationConfig' => ['responseMimeType' => 'application/json', 'temperature' => 0.1] ]; // Delay 4 seconds to respect free tier rate limits updateState($stateFile, 'analyzing', 70, 'جاري تطبيقหน่วงزمني (4 ثوانٍ) لتفادي حدود الاستخدام (Rate Limit)...'); sleep(4); // Allow custom model from .env (e.g. gemini-2.0-flash-lite-preview-02-05 or gemini-2.0-flash) $geminiModel = Env::get('GEMINI_MODEL') ?: getenv('GEMINI_MODEL'); if (empty($geminiModel)) { $geminiModel = "gemini-flash-lite-latest"; // fallback to latest flash lite } updateState($stateFile, 'analyzing', 75, "جاري إرسال البيانات للنموذج [{$geminiModel}]..."); $url = "https://generativelanguage.googleapis.com/v1beta/models/{$geminiModel}:generateContent?key=" . $geminiKey; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 300 // AI might take 2 minutes ]); $res = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code !== 200 || empty($res)) { updateState($stateFile, 'error', 0, 'فشل توليد المحتوى من الذكاء الاصطناعي. قد يكون الملف ضخماً جداً أو الـ API Key غير صالح.'); exit; } $jsonResponse = json_decode($res, true); $text = $jsonResponse['candidates'][0]['content']['parts'][0]['text'] ?? ''; $parsedStructure = json_decode($text, true); if (empty($parsedStructure) || empty($parsedStructure['units'])) { updateState($stateFile, 'error', 0, 'فشل الذكاء الاصطناعي في إرجاع بنية JSON صالحة.'); exit; } updateState($stateFile, 'generating', 80, 'الذكاء الاصطناعي انتهى من القراءة! جاري بناء الملفات وحفظها على السيرفر...'); // Save to disk $updatedTree = CurriculumService::mergeExtractedCurriculum($parsedStructure); $firstLessonFile = ''; if (!empty($parsedStructure['units'][0]['lessons'][0])) { $firstLes = $parsedStructure['units'][0]['lessons'][0]; $firstLessonFile = "{$parsedStructure['grade_key']}/{$parsedStructure['subject_key']}/{$parsedStructure['semester_key']}/{$parsedStructure['units'][0]['unit_key']}/{$firstLes['lesson_id']}.md"; } updateState($stateFile, 'completed', 100, 'تم الاستخراج المعتمد على الـ AI بالكامل بنجاح!', [ 'active_file' => $firstLessonFile, 'tree' => $updatedTree, 'extracted_data' => $parsedStructure ]);