'failure', 'message' => 'Unauthorized']); exit; } try { $countryCode = resolveAdminCountry(filterRequest('country_code'), $role, $admin_country ?? null); if (!$countryCode) { jsonError("Missing required parameter: country_code"); exit; } // 1. Analyze the most common hours for competitor surges in the last 14 days $sql = "SELECT HOUR(created_at) as surge_hour, COUNT(*) as frequency FROM price_anomalies WHERE country_code = :country AND anomaly_type = 'opportunity' AND created_at >= DATE_SUB(NOW(), INTERVAL 14 DAY) GROUP BY surge_hour ORDER BY frequency DESC LIMIT 3"; $stmt = $con->prepare($sql); $stmt->execute([':country' => strtoupper($countryCode)]); $peakHours = $stmt->fetchAll(PDO::FETCH_ASSOC); // 2. Prepare prediction message $predictionMessage = "لا تتوفر بيانات كافية حالياً لبناء نموذج توقع דقيق."; $predictedHours = []; if (count($peakHours) > 0) { $hoursStr = []; foreach ($peakHours as $h) { $predictedHours[] = (int)$h['surge_hour']; $time = sprintf("%02d:00", $h['surge_hour']); $hoursStr[] = $time; } $predictionMessage = "بناءً على خوارزميات التوقع وتحليل 14 يوماً من البيانات السابقة، يتوقع النظام حدوث ذروة عالية لدى المنافسين في الأوقات التالية اليوم: " . implode('، ', $hoursStr) . ". يُنصح بتجهيز كباتن سيرو مسبقاً في هذه الأوقات."; } // Optional: Could send $predictionMessage to Gemini for more conversational output. // For performance, we return the deterministic heuristic here. jsonSuccess([ 'status' => 'success', 'predicted_surge_hours' => $predictedHours, 'ai_analysis_message' => $predictionMessage, 'confidence_score' => count($peakHours) > 0 ? 85 : 0 ]); } catch (Exception $e) { error_log("[ai_price_prediction] Error: " . $e->getMessage()); jsonError("Failed to run AI prediction"); }