<?php
/**
 * SERAJ by ONEIC Media WhatsApp Bot - Enhanced Version
 * Version: 2.0 | Date: 2024-07-06
 */


require_once __DIR__ . '/config.php';
require_once __DIR__ . '/service_cards.php';
// ======== Directory Creation (Best Practice & Error Safe) ========

if (isset($config['dirs']) && is_array($config['dirs'])) {
    foreach ($config['dirs'] as $dir) {
        if (!is_dir($dir)) {
            // Create directory with permissions if not exists
            @mkdir($dir, 0755, true);
        }
    }
}

// ======== Enhanced Logging System ========
function logMessage(string $message, string $type = 'INFO', string $user_id = null): void {
    global $config;
    $timestamp = date('Y-m-d H:i:s');
    $prefix = "[$timestamp] [$type]" . ($user_id ? " [User: $user_id]" : '');
    $entry = "$prefix $message\n";
    
    $logFiles = [
        'ERROR'      => 'logs/errors.log',
        'WARNING'    => 'logs/warnings.log',
        'RATE_LIMIT' => 'logs/rate_limits.log',
        'CONVERSION' => 'logs/conversions.log',
        'API'        => 'logs/api_requests.log'
    ];
    
    $filepath = $logFiles[$type] ?? 'logs/activity.log';
    // Ensure log directory exists
    if (!is_dir(dirname($filepath))) {
        @mkdir(dirname($filepath), 0755, true);
    }
    @file_put_contents($filepath, $entry, FILE_APPEND | LOCK_EX);
}

// ======== Security Headers (should be sent only ONCE per request) ========
// NOTE: It's best to send headers from your main entry script only ONCE!
// Here for reference, but don't repeat in every include:
if (!headers_sent()) {
    header('Content-Type: application/json; charset=utf-8');
    header('X-Content-Type-Options: nosniff');
    header('X-Frame-Options: DENY');
    header('X-XSS-Protection: 1; mode=block');
    header('Strict-Transport-Security: max-age=31536000');
}

// ======== Input Validation ========
function validateInput($input): bool {
    $input = $input ?? '';
    $trimmed = trim($input);
    return !empty($trimmed) &&
           mb_strlen($trimmed, 'UTF-8') <= 2000 &&
           mb_strlen($trimmed, 'UTF-8') >= 1;
}

function sanitizeInput($input): string {
    $input = $input ?? '';
    $input = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $input);
    $input = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/i', '', $input);
    return trim(htmlspecialchars($input, ENT_QUOTES, 'UTF-8'));
}

// ======== Defensive Helper for All Inputs ========
function safeInput($input): string {
    return isset($input) && $input !== null ? (string)$input : '';
}

function detectLanguage(string $text): string {
    return preg_match('/[\x{0600}-\x{06FF}]/u', $text) ? 'ar' : 'en';
}

function buildContactSnippet(string $lang = 'ar'): string {
    global $config;
    $isAr = ($lang === 'ar');
    $lines = [];
    $website = trim((string)($config['website_url'] ?? ''));
    $phone = trim((string)($config['contact_phone'] ?? ''));
    $email = trim((string)($config['contact_email'] ?? ''));
    $address = trim((string)($config['contact_address'] ?? ''));

    if ($website !== '') {
        $lines[] = ($isAr ? 'الموقع: ' : 'Website: ') . $website;
    }
    if ($phone !== '') {
        $lines[] = ($isAr ? 'الهاتف: ' : 'Phone: ') . $phone;
    }
    if ($email !== '') {
        $lines[] = ($isAr ? 'البريد: ' : 'Email: ') . $email;
    }
    if ($address !== '') {
        $lines[] = ($isAr ? 'العنوان: ' : 'Address: ') . $address;
    }

    return $lines ? "\n" . implode("\n", $lines) : '';
}

// ======== Token Management ========
function getOpenAIToken(): string {
    global $openaiTokens;
    static $tokenIndex = 0;
    
    if (empty($openaiTokens)) {
        throw new RuntimeException('No OpenAI tokens available');
    }
    
    $token = $openaiTokens[$tokenIndex];
    $tokenIndex = ($tokenIndex + 1) % count($openaiTokens);
    
    return $token;
}








// ======== Main Execution Flow ========
try {
    $rawInput = file_get_contents('php://input');
    if ($rawInput) {
        @file_put_contents('logs/webhook.log', "[" . date('Y-m-d H:i:s') . "] $rawInput\n", FILE_APPEND | LOCK_EX);
    }

    // Handle webhook verification challenge (GET request)
    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        handleVerification();
        exit;
    }

    // Ensure POST request
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        http_response_code(405);
        echo json_encode(['error' => 'Method not allowed']);
        exit;
    }

    // Decode WhatsApp payload
    $data = json_decode($rawInput, true) ?? [];
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new Exception('Invalid JSON received: ' . json_last_error_msg());
    }

    // Extract message (ignore if status)
// Extract message (ignore if status)
$message = extractWebhookMessage($data);
if (!$message) {
    echo json_encode(['status' => 'ignored']);
    exit;
}

// WhatsApp only: ignore other platforms for faster handling
$platform = $message['platform'] ?? 'whatsapp';
if ($platform !== 'whatsapp') {
    echo json_encode(['status' => 'ignored', 'reason' => 'whatsapp_only']);
    exit;
}

// ===== معالجة التعليقات أولاً (قبل معالجة الرسائل العادية) =====
if (($message['type'] ?? '') === 'comment') {
    $commentId = $message['comment_id'] ?? '';
    $userId = $message['from_id'] ?? '';
    $platform = $message['platform'] ?? 'facebook';
    $field = $message['field'] ?? '';
    $postId = $message['post_id'] ?? '';
    
    // الحصول على نص التعليق
// في معالجة التعليقات، بدلاً من محاولة جلب النص من API:
$commentText = trim($message['comment_text'] ?? '');

// لا تحاول جلب من API إذا كان معرف التعليق يحتوي على "_"
// لأن هذا قد يعني أنه مُركب ولا يمكن الوصول إليه مباشرة
if (empty($commentText) && !empty($commentId) && strpos($commentId, '_') === false) {
    $commentText = fetchCommentText($commentId, $config['facebook_token']);
    logMessage("Fetched comment text from API: '$commentText'", 'INFO', $userId);
}

// إذا ما زال فارغ، استخدم نص افتراضي
if (empty($commentText)) {
    $commentText = 'شكرًا لتعليقك! نقدر تفاعلك معنا';
    logMessage("Using default comment text", 'INFO', $userId);
}


    // Log البيانات الأولية للتشخيص
    file_put_contents('logs/comment_processing.log', 
        date('Y-m-d H:i:s') . " [$platform] Processing comment\n" .
        "Field: $field\n" .
        "Comment ID: $commentId\n" .
        "User ID: $userId\n" .
        "Post ID: $postId\n" .
        "Initial Text: '$commentText'\n" .
        "Raw data: " . json_encode($message, JSON_UNESCAPED_UNICODE) . "\n\n", 
        FILE_APPEND
    );
    
    // إذا كان النص فارغ، جرب جلبه من API
    if (empty($commentText) && !empty($commentId)) {
        $commentText = fetchCommentText($commentId, $config['facebook_token']);
        logMessage("Fetched comment text from API: '$commentText'", 'INFO', $userId);
    }
    
    // إذا ما زال فارغ، استخدم رسالة واضحة
    if (empty($commentText)) {
        $commentText = 'شكرًا لتعليقك!';
        logMessage("Empty comment detected for ID: $commentId - using default text", 'WARNING', $userId);
    }
    
    logMessage("$platform comment from $userId: $commentText", 'INFO', $userId);
    
    // إدارة الحالة لمنع التكرار
    $stateKey = md5($platform . '_' . $commentId);
    $commentStateFile = "cache/comment_state_{$stateKey}.json";
    $defaultState = [
        'comment_id'   => $commentId,
        'user_id'      => $userId,
        'platform'     => $platform,
        'field'        => $field,
        'post_id'      => $postId,
        'comment_text' => $commentText,
        'like_done'    => false,
        'reply_sent'   => false,
        'dm_sent'      => false,
        'ai_reply'     => null,
        'dm_text'      => null,
        'created_at'   => time(),
        'updated_at'   => time()
    ];
    $commentState = $defaultState;
    if (is_file($commentStateFile)) {
        $storedState = json_decode(file_get_contents($commentStateFile), true);
        if (is_array($storedState)) {
            $commentState = array_merge($commentState, $storedState);
        }
    }
    $saveCommentState = function () use (&$commentState, $commentStateFile) {
        $commentState['updated_at'] = time();
        @file_put_contents(
            $commentStateFile,
            json_encode($commentState, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
            LOCK_EX
        );
    };

    $commentState['comment_text'] = $commentText;
    $commentState['field'] = $field;
    $commentState['post_id'] = $postId;
    $saveCommentState();

    if ($commentState['reply_sent'] && $commentState['dm_sent'] && $commentState['like_done']) {
        logMessage("Comment already fully processed: $commentId", 'INFO', $userId);
        echo json_encode([
            'status' => 'already_processed',
            'platform' => $platform,
            'comment_id' => $commentId,
            'user_id' => $userId,
            'comment_liked' => true,
            'comment_reply_sent' => true,
            'dm_sent' => true,
            'comment_text' => $commentState['comment_text'],
            'ai_reply' => $commentState['ai_reply'],
            'dm_text' => $commentState['dm_text']
        ]);
        exit;
    }

    // إنشاء رد الذكاء الاصطناعي عند الحاجة فقط
    if (empty($commentState['ai_reply'])) {
        $conversation = [
            [
                'role' => 'system',
                'content' => buildSystemPrompt([
                    'business_type' => '',
                    'interests' => [],
                    'qualification_status' => 'new',
                    'lead_score' => 0
                ])
            ],
            [
                'role' => 'user',
                'content' => "$commentText (تعليق من $platform)"
            ]
        ];

        $aiReply = getAIResponse($conversation);
        if (!$aiReply) {
            if ($platform === 'instagram') {
                $aiReply = "شكرًا لتعليقك! 👋 راسلنا خاص للمزيد من المعلومات 📱";
            } else {
                $aiReply = "شكرًا لتعليقك! 👋\nللمزيد من المعلومات راسلنا خاص." . buildContactSnippet('ar');
            }
        }

        $aiReply = preg_replace('/\[BUTTONS:.*?\]/i', '', $aiReply);
        $aiReply = trim($aiReply);

        if (mb_strlen($aiReply) > 300) {
            $aiReply = mb_substr($aiReply, 0, 280) . "...\n🔗 للمزيد راسلنا خاص";
        }

        $commentState['ai_reply'] = $aiReply;
        $saveCommentState();
    } else {
        $aiReply = (string)$commentState['ai_reply'];
    }

    // حارس لمنع تكرار الردود: رد واحد فقط لكل (منصة + بوست + مستخدم)
    $replyOnceKey = md5(implode('_', [
        (string)$platform,
        (string)$postId,
        (string)$userId
    ]));
    $replyOnceFile = "cache/replied_once_{$replyOnceKey}.flag";

    // 1. لايك التعليق مرة واحدة
    if (!$commentState['like_done'] && !empty($commentId)) {
        if (likeComment($commentId, $config['facebook_token'])) {
            $commentState['like_done'] = true;
            $saveCommentState();
            logMessage("Comment liked successfully", 'INFO', $userId);
        } else {
            logMessage("Comment like failed", 'WARNING', $userId);
        }
    }

    // 2. إرسال الرد مع المنشن مرة واحدة (حقيقي) على مستوى (post_id + from_id)
    if (!file_exists($replyOnceFile) && !$commentState['reply_sent'] && !empty($commentId)) {
        $replyWithMention = createReplyWithMention($aiReply, $userId, $platform);
        if (replyToComment($commentId, $replyWithMention, $config['facebook_token'], $platform)) {
            $commentState['reply_sent'] = true;
            $saveCommentState();
            // وضع علامة أن هذا المستخدم تم الرد عليه لهذا البوست
            @file_put_contents($replyOnceFile, (string)time());
            logMessage("Single comment reply sent successfully", 'INFO', $userId);
        } else {
            logMessage("Comment reply failed", 'ERROR', $userId);
        }
    }

    // 3. إرسال رسالة خاصة مرة واحدة فقط أيضاً حسب (post_id + from_id)
    if (!file_exists($replyOnceFile) && !$commentState['dm_sent'] && !empty($userId)) {
        $dmText = $commentState['dm_text'] ?? (
            "شكرًا لاهتمامك بـ SERAJ by ONEIC MEDIA! 🙏✨\n\n" . $aiReply .
            "\n\n💬 يسعدنا الرد على أي استفسار إضافي في أي وقت." .
            buildContactSnippet('ar')
        );
        $commentState['dm_text'] = $dmText;
        $saveCommentState();

        if ($platform === 'instagram') {
            $dmSent = sendInstagramDM($userId, $dmText, $config['facebook_token']);
        } else {
            $dmSent = sendMessengerMessage($userId, $dmText);
        }

        if ($dmSent) {
            $commentState['dm_sent'] = true;
            $saveCommentState();
            // ضع نفس العلامة حتى لا نرسل DM أو رد ثاني مرة
            @file_put_contents($replyOnceFile, (string)time());
            logMessage("Private message sent successfully", 'INFO', $userId);
        } else {
            logMessage("Private message failed to send", 'WARNING', $userId);
        }
    }

    echo json_encode([
        'status' => 'comment_processed',
        'platform' => $platform,
        'comment_liked' => (bool)$commentState['like_done'],
        'comment_reply_sent' => (bool)$commentState['reply_sent'],
        'dm_sent' => (bool)$commentState['dm_sent'],
        'timestamp' => time(),
        'comment_id' => $commentId,
        'user_id' => $userId,
        'comment_text' => $commentState['comment_text'],
        'ai_reply' => $commentState['ai_reply'],
        'dm_text' => $commentState['dm_text']
    ]);
    exit;


}


// باقي الكود للرسائل العادية...
// في أعلى الملف أو بعد require_once:
$forwardNumbers = ['96896651520'];
$targetNumber = '96896651520';

// ... بعد استخراج الرسالة:
$from = $message['from'] ?? '';
$userInput = extractMessageText($message) ?? '';
$platform = $message['platform'] ?? 'whatsapp';
$meta = [
    'type' => $message['type'] ?? 'unknown',
    'raw' => $message
];
// معالجة الميديا لواتساب: تنزيل الصوت ونسخ الكلام، حفظ الصور
try {
    if ($platform === 'whatsapp') {
        $msgType = $message['type'] ?? '';
        if (in_array($msgType, ['audio','voice'])) {
            $mediaId = $message[$msgType]['id'] ?? '';
            if ($mediaId) {
                $download = downloadWhatsAppMedia($mediaId);
                if ($download && !empty($download['path'])) {
                    $transcribed = transcribeAudioOpenAI($download['path']);
                    if ($transcribed) {
                        $userInput = '[صوت] ' . $transcribed;
                        logMessage('Audio transcribed successfully', 'INFO', $from);
                    } else {
                        logMessage('Audio transcription failed', 'WARNING', $from);
                    }
                }
            }
        } elseif ($msgType === 'image') {
            $mediaId = $message['image']['id'] ?? '';
            if ($mediaId) {
                $download = downloadWhatsAppMedia($mediaId);
                if ($download && !empty($download['path'])) {
                    // خزّن المسار في الميتا وواصل المحادثة بدون استدعاء AI للرؤية لتقليل التكلفة
                    $meta['image_path'] = $download['path'];
                    $meta['image_mime'] = $download['mime'] ?? '';
                    logMessage('Image downloaded: ' . $download['path'], 'INFO', $from);
                }
            }
        }
    }
} catch (Throwable $e) {
    logMessage('Media handling error: ' . $e->getMessage(), 'ERROR', $from);
}

// كود التحويل:
// Forward internal team messages to all sales numbers
if (in_array($from, $forwardNumbers)) {
    $recipients = array_unique(array_merge([$targetNumber], $forwardNumbers));
    foreach ($recipients as $rcpt) {
        if ($rcpt === $from) continue; // don't notify sender
        sendInternalAlert($rcpt, "رسالة داخلية من فريق المبيعات من $from:\n$userInput");
    }
    // Extra emphasis to Sales Manager (Ramy)
    $manager = $config['sales_manager_number'] ?? '96896651520';
    if ($manager && $manager !== $from && !in_array($manager, $recipients, true)) {
        sendInternalAlert($manager, "[تنبيه مدير المبيعات] رسالة من $from:\n$userInput");
    } elseif ($manager && $manager !== $from) {
        // Send an emphasized extra copy
        sendInternalAlert($manager, "[تنبيه إضافي] رسالة من $from:\n$userInput");
    }
}
if (false && in_array($from, $forwardNumbers)) {
    sendWhatsAppMessage($targetNumber, "رسالة جديدة تم تحويلها من $from:\n$userInput");
}

// تجهيز بيانات إضافية لكل رسالة (تم تهيئتها قبل معالجة الميديا)

// تخزين ID الميديا لو فيه
foreach (['image', 'video', 'audio', 'document', 'sticker'] as $mtype) {
    if (isset($message[$mtype]['id'])) {
        $meta['media_id'] = $message[$mtype]['id'];
        $meta['caption'] = $message[$mtype]['caption'] ?? '';
    }
}

// استخراج الأكواد الرقمية (OTP)
if (preg_match('/\b\d{4,8}\b/', $userInput, $otpMatch)) {
    $meta['otp'] = $otpMatch[0];
}


    logMessage("Received: '" . mb_substr($userInput, 0, 100) . "'", 'INFO', $from);

    // Rate limit & duplicate
    if (!$from || !checkRateLimit($from) || isDuplicateMessage($from, $userInput)) {
        http_response_code(200);
        exit;
    }

    // Detect if this is the first-ever message from this customer
    $isNewConversation = empty(loadConversation($from));

    // Load customer/chat, add message
    $customer = loadCustomerData($from);

    // Notify sales team on first conversation start (no message sent to customer)
    if ($isNewConversation && ($config['notify_on_new_chat'] ?? false)) {
        try {
            notifySalesOnNewChat($from, $platform ?? 'whatsapp', $customer);
        } catch (Throwable $e) {
            logMessage('Failed to notify sales on new chat: ' . $e->getMessage(), 'WARNING', $from);
        }
    }

    addToChatLog($from, $userInput, 'user', $meta);
    updateCustomerProfile($customer, $userInput);

    // Build conversation for AI
    $conversation = loadConversation($from);
    $conversation = initConversation($conversation, $customer);
    $conversation = trimConversationHistory($conversation);

    
// ======== Prepared Service Cards (Image + Text) ========
// If user asked about a known screen/service, reply instantly with the prepared card (no AI/hallucination).
$matchedCard = findServiceCard($userInput);
if ($matchedCard) {
    $lang = detectLanguage($userInput);
    $cardText = buildServiceCardText($matchedCard, $lang);
    $imgRef = null;
    $localDir = $config['media_local_dir'] ?? (__DIR__ . '/media_screens');
    $localPath = rtrim($localDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($matchedCard['image']);
    $preferLocal = !empty($config['media_prefer_local']);
    if ($preferLocal && is_file($localPath)) {
        $imgRef = $localPath;
    } elseif (!empty($config['media_base_url'])) {
        $imgRef = rtrim($config['media_base_url'], '/') . '/' . $matchedCard['image'];
    } elseif (is_file($localPath)) {
        $imgRef = $localPath;
    }

    // Save interest
    $customer['interests'][] = $matchedCard['title_en'] ?? $matchedCard['_key'];
    $customer['interests'] = array_values(array_unique($customer['interests']));

    $caption = ($lang === 'ar') ? ($matchedCard['title_ar'] ?? '') : ($matchedCard['title_en'] ?? '');
    if ($caption === '') {
        $caption = $matchedCard['title_en'] ?? ($matchedCard['title_ar'] ?? '');
    }

    $sent = false;
    if ($imgRef) {
        $sent = sendMediaCard($platform, $from, $imgRef, $cardText, $caption);
    }
    if (!$sent) {
        if ($platform === 'instagram') {
            $sent = sendInstagramDM($from, $cardText, $config['facebook_token']);
        } elseif ($platform === 'messenger') {
            $sent = sendMessengerMessage($from, $cardText);
        } else {
            $sent = sendWhatsAppMessage($from, $cardText);
        }
    }
    if ($sent) {
        addToChatLog($from, $cardText, 'assistant', ['media' => $imgRef, 'card' => $matchedCard['_key'] ?? null]);
        saveCustomerData($from, $customer);
        echo json_encode(['status' => 'ok', 'sent' => 'service_card', 'card' => $matchedCard['_key'] ?? null], JSON_UNESCAPED_UNICODE);
        exit;
    }
    // if media failed, continue to normal flow (AI/text)
}

// ===== Get AI Response (with cheap fallbacks) =====
    // اختصار استهلاك API: ردود سريعة بدون AI لبعض الأنماط البسيطة
    $normalized = trim(mb_strtolower($userInput, 'UTF-8'));
    $quickMap = [
        'شكرا' => 'العفو! تحب نرشح لك أنسب شاشة لحملتك؟',
        'شكراً' => 'العفو! تحب نرشح لك أنسب شاشة لحملتك؟',
        'thanks' => 'You\'re welcome! Want us to suggest the best screen for your campaign?',
        'hi' => 'Hi! This is SERAJ by ONEIC MEDIA. How can we help with your outdoor advertising?',
        'hello' => 'Hello! This is SERAJ by ONEIC MEDIA. How can we help with your outdoor advertising?',
    ];
    $aiResponse = null;
    if (isset($quickMap[$normalized])) {
        $aiResponse = buildJsonReply($quickMap[$normalized], detectLanguage($userInput));
    } else {
        $aiResponse = getAIResponse($conversation);
    }
    if ($aiResponse === null) {
        $aiResponse = buildJsonReply(
            'عذرًا، حدث خطأ تقني. يمكنك مشاركة طلبك هنا وسنعود لك.',
            detectLanguage($userInput)
        );
    }
    logMessage("AI RAW: " . $aiResponse, 'INFO', $from);

    // ===== Parse AI Payload (JSON) or fallback to buttons =====
    $buttons = [];
    $responseText = $aiResponse;
    $mediaItems = [];
    $aiPayload = parseAiPayload($aiResponse);
    if ($aiPayload) {
        $responseText = $aiPayload['reply_text'];
        $mediaItems = $aiPayload['media'];
        $updates = $aiPayload['profile_updates'] ?? [];
        if (is_array($updates) && !empty($updates)) {
            $cleanUpdates = [];
            foreach ($updates as $key => $value) {
                if (is_string($value)) {
                    $value = trim($value);
                }
                if ($value === '' || $value === null) {
                    continue;
                }
                $cleanUpdates[$key] = $value;
            }
            if (!empty($cleanUpdates)) {
                $customer['profile_updates'] = array_merge($customer['profile_updates'] ?? [], $cleanUpdates);
            }
        }
    } elseif (preg_match('/\[(buttons):\s*(.*?)\]/i', $aiResponse, $matches)) {
        $responseText = trim(str_replace($matches[0], '', $aiResponse));
        $buttonTitles = array_map('trim', explode('|', $matches[2]));
        $buttons = array_filter($buttonTitles);
    }

    if ($responseText === '' && empty($mediaItems)) {
        $responseText = 'شكرًا لتواصلك. ممكن توضح طلبك؟';
    }


function sendMessengerQuickReplies(string $to, string $body, array $buttons): bool {
    global $config;
    $quickReplies = [];
    foreach (array_slice($buttons, 0, 11) as $button) {
        $quickReplies[] = [
            'content_type' => 'text',
            'title' => $button,
            'payload' => $button
        ];
    }
    $payload = json_encode([
        'recipient' => ['id' => $to],
        'message'   => [
            'text' => $body,
            'quick_replies' => $quickReplies
        ]
    ], JSON_UNESCAPED_UNICODE);

    $ch = curl_init("https://graph.facebook.com/v19.0/me/messages?access_token={$config['messenger_token']}");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['messenger_timeout'],
        CURLOPT_SSL_VERIFYPEER => true
    ]);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    logMessage("Messenger Quick Replies API response: $httpCode $response", 'INFO', $to);
    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 300;
}


    // ===== Send Actual Message =====
    $messageSent = false;
    $platform = $message['platform'] ?? 'whatsapp';

    $mediaSent = false;
    if (!empty($mediaItems)) {
        foreach ($mediaItems as $media) {
            if (!is_array($media)) continue;
            $type = strtolower((string)($media['type'] ?? ''));
            if ($type !== 'image') continue;
            $url = (string)($media['url'] ?? '');
            if ($url === '') continue;
            $caption = (string)($media['caption'] ?? '');
            $ref = resolveMediaRef($url);
            if ($ref !== '') {
                $mediaSent = sendImageOnly($platform, $from, $ref, $caption) || $mediaSent;
            }
        }
    }

    if ($responseText !== '') {
        if ($platform === 'messenger') {
            logMessage("Messenger response to $from", 'INFO', $from);
            if (!empty($buttons) && empty($mediaItems)) {
                $messageSent = sendMessengerQuickReplies($from, $responseText, $buttons);
            } else {
                $messageSent = sendMessengerMessage($from, $responseText);
            }
        } elseif ($platform === 'instagram') {
            logMessage("Instagram response to $from", 'INFO', $from);
            $messageSent = sendInstagramDM($from, $responseText, $config['facebook_token']);
        } else {
            logMessage("Sending standard WhatsApp text response to $from", 'INFO', $from);
            $messageSent = sendWhatsAppMessage($from, $responseText);
        }
    }

    $messageSent = $messageSent || $mediaSent;



    if (!$messageSent) {
        throw new Exception('Failed to send message');
    }

    $assistantLogText = $aiPayload ? $responseText : $aiResponse;
    addToChatLog($from, $assistantLogText, 'assistant');
    saveCustomerData($from, $customer);
    trackConversionSignals($from, $userInput, $assistantLogText);

    // نفّذ مزامنة Odoo بعد الرد لتقليل زمن الاستجابة
    try {
        $customerName = $customer['name'] ?? null;
        $email = null;
        if (preg_match('/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i', $userInput, $m)) {
            $email = $m[0];
        }

        $leadId = odooUpsertLeadFromChat($odoo, [
            'name'       => $customerName,
            'message'    => $userInput,
            'phone'      => $from,
            'email'      => $email,
            'platform'   => $platform,
            'source_name'=> $odoo['default_source'],
            'extra'      => $meta ?? []
        ]);

        logMessage("Odoo Lead upserted: ID=$leadId", 'INFO', $from);
    } catch (Throwable $e) {
        logMessage("Odoo Lead error: ".$e->getMessage(), 'ERROR', $from);
    }

    logMessage('Reply sent successfully', 'INFO', $from);
    http_response_code(200);
    echo json_encode(['status' => 'success']);

} catch (Throwable $e) {
    handleError($e, $from ?? null, $userInput ?? null);
}








// ======== Core Functions ========
function handleVerification(): void {
    global $config;

    if (!isset($_GET['hub_verify_token'])) {
        http_response_code(400);
        exit;
    }

    if (hash_equals($config['verify_token'], $_GET['hub_verify_token'])) {
        logMessage('Webhook verified');
        echo $_GET['hub_challenge'] ?? '';
    } else {
        logMessage('Invalid verify token', 'ERROR');
        http_response_code(403);
        echo json_encode(['error' => 'Forbidden']);
    }
}





function extractWebhookMessage(array $data): ?array {
    
        $webhookHash = md5(json_encode($data));
    $webhookCacheFile = "cache/webhook_$webhookHash.txt";
    $markWebhookProcessed = function () use ($webhookCacheFile): void {
        @file_put_contents($webhookCacheFile, (string)time());
    };
    
    if (file_exists($webhookCacheFile)) {
        $lastProcessed = (int)file_get_contents($webhookCacheFile);
        if ((time() - $lastProcessed) < 30) { // 30 ثانية
            return null; // تجاهل الـ webhook المكرر
        }
    }
    
    // WhatsApp payload
    if (isset($data['entry'][0]['changes'][0]['value']['messages'][0])) {
        $msg = $data['entry'][0]['changes'][0]['value']['messages'][0];
        $msg['platform'] = 'whatsapp';
        $markWebhookProcessed();
        return $msg;
    }
    
    // Messenger payload (تجاهل delivery receipts)
    elseif (isset($data['entry'][0]['messaging'][0])) {
        $msgObj = $data['entry'][0]['messaging'][0];
        
        // تجاهل delivery receipts و read receipts
        if (isset($msgObj['delivery']) || isset($msgObj['read'])) {
            $markWebhookProcessed();
            return null;
        }
        
        if (isset($msgObj['message']['text'])) {
            $markWebhookProcessed();
            return [
                'from'     => $msgObj['sender']['id'] ?? '',
                'type'     => 'text',
                'platform' => ((isset($data['object']) && $data['object'] === 'instagram') ? 'instagram' : 'messenger'),
                'text'     => $msgObj['message']['text']
            ];
        }
    }
    
    // Facebook/Instagram Comments - تحديث شامل
    elseif (isset($data['entry'][0]['changes'][0])) {
        $change = $data['entry'][0]['changes'][0];
        $field = $change['field'] ?? '';
        
        // Log البيانات الخام للتشخيص
        file_put_contents('logs/comment_debug.log', 
            date('Y-m-d H:i:s') . " WEBHOOK RECEIVED\n" .
            "FIELD: $field\n" .
            "FULL DATA: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n", 
            FILE_APPEND
        );
        
        // دعم كل الـ fields المحتملة للتعليقات
        if (in_array($field, ['feed', 'comments', 'mention', 'comment', 'live_comments']) && isset($change['value'])) {
            $value = $change['value'];
            
            // تحديد نوع الحدث
            $item = $value['item'] ?? '';
            $verb = $value['verb'] ?? '';
            
            // شروط أوسع للتعرف على التعليق
            $isComment = (
                $item === 'comment' || 
                $verb === 'add' || 
                isset($value['comment_id']) || 
                isset($value['id']) ||
                ($field === 'feed' && isset($value['message'])) ||
                ($field === 'comments' && (isset($value['text']) || isset($value['message']))) ||
                ($field === 'comment') // أحياناً يأتي بهذا الاسم
            );
            
            if ($isComment) {
                // محاولة استخراج النص من كل الحقول المحتملة
                $commentText = '';
                $textFields = [
                    'message',      // Facebook الأساسي
                    'text',         // Instagram الأساسي
                    'comment_text', // بديل
                    'body',         // بديل آخر
                    'content'       // بديل إضافي
                ];
                
                foreach ($textFields as $textField) {
                    if (!empty($value[$textField]) && is_string($value[$textField])) {
                        $commentText = trim($value[$textField]);
                        if ($commentText !== '') break;
                    }
                }
                
                // تحديد المنصة بطريقة أفضل
                $platform = 'facebook'; // افتراضي
                
                // طرق تحديد Instagram
                if (
                    strpos(json_encode($value), 'instagram') !== false ||
                    isset($value['media']) ||
                    isset($value['media_id']) ||
                    ($field === 'comments' && !isset($value['post_id'])) ||
                    isset($value['media_type'])
                ) {
                    $platform = 'instagram';
                }
                
                // استخراج معرف المستخدم بطرق مختلفة
                $fromId = '';
                $fromFields = ['sender_id', 'from', 'user_id', 'author_id'];
                foreach ($fromFields as $fromField) {
                    if (!empty($value[$fromField])) {
                        $fromId = is_array($value[$fromField]) ? $value[$fromField]['id'] : $value[$fromField];
                        if (!empty($fromId)) break;
                    }
                }
                
                $markWebhookProcessed();
                return [
                    'type'         => 'comment',
                    'platform'     => $platform,
                    'comment_id'   => $value['comment_id'] ?? $value['id'] ?? '',
                    'from_id'      => $fromId,
                    'comment_text' => $commentText,
                    'post_id'      => $value['post_id'] ?? $value['media']['id'] ?? $value['parent_id'] ?? '',
                    'raw_data'     => $value,
                    'field'        => $field
                ];
            }
        }
    }

    // تجاهل delivery receipts بدلاً من log كـ unhandled
    if (isset($data['entry'][0]['messaging'][0]['delivery']) || isset($data['entry'][0]['messaging'][0]['read'])) {
        $markWebhookProcessed();
        return null;
    }

    // Log للحالات غير المتوقعة فقط
    file_put_contents('logs/webhook_unhandled.log', 
        date('Y-m-d H:i:s') . " UNHANDLED WEBHOOK: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n", 
        FILE_APPEND
    );
    
    $markWebhookProcessed();
    return null;
}



function mentionUser($postId, $userId, $accessToken) {
    if (empty($postId) || empty($userId) || empty($accessToken)) {
        return false;
    }
    
    // محاولة عمل mention في comment منفصل
    $url = "https://graph.facebook.com/v19.0/{$postId}/comments";
    $data = [
        'message' => "شكرًا لتفاعلك معنا! 🙏 @[$userId]",
        'access_token' => $accessToken
    ];
    
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_TIMEOUT => 15
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    // Log محاولة المنشن
    file_put_contents('logs/mention_attempts.log', 
        date('Y-m-d H:i:s') . " Mention attempt: Post $postId, User $userId, HTTP: $httpCode\n" .
        "Response: $response\n\n", 
        FILE_APPEND
    );
    
    curl_close($ch);
    
    return $httpCode >= 200 && $httpCode < 300;
}









function extractMessageText(array $message): string {
    

    if (($message['type'] ?? '') === 'comment') {
        $txt = trim($message['comment_text'] ?? '');
        return $txt === '' ? '[تعليق فارغ]' : $txt;
    }

    if (($message['platform'] ?? '') === 'messenger') {
        return trim($message['text'] ?? '[رسالة فارغة]');
    }
    
    $type = $message['type'] ?? 'unknown';

    switch($type) {
        case 'text':
            $text = $message['text']['body'] ?? '';
            break;

        case 'button':
            $text = $message['button']['payload'] ?? $message['button']['text'] ?? '[زر تفاعلي]';
            break;

        case 'interactive':
            $text = extractInteractiveMessage($message['interactive'] ?? []);
            break;

        case 'image':
            $caption = $message['image']['caption'] ?? '';
            $media_id = $message['image']['id'] ?? '';
            $text = "[صورة] ID: $media_id" . ($caption ? " - $caption" : '');
            break;

        case 'video':
            $caption = $message['video']['caption'] ?? '';
            $media_id = $message['video']['id'] ?? '';
            $text = "[فيديو] ID: $media_id" . ($caption ? " - $caption" : '');
            break;

        case 'audio':
        case 'voice':
            $media_id = $message[$type]['id'] ?? '';
            $text = "[صوت] ID: $media_id";
            break;

        case 'document':
            $caption = $message['document']['caption'] ?? '';
            $media_id = $message['document']['id'] ?? '';
            $filename = $message['document']['filename'] ?? '';
            $text = "[ملف] $filename - ID: $media_id" . ($caption ? " - $caption" : '');
            break;

        case 'sticker':
            $media_id = $message['sticker']['id'] ?? '';
            $text = "[ملصق] ID: $media_id";
            break;

        case 'location':
            $lat = $message['location']['latitude'] ?? '';
            $lng = $message['location']['longitude'] ?? '';
            $name = $message['location']['name'] ?? '';
            $address = $message['location']['address'] ?? '';
            $text = "[موقع جغرافي] $name $address (Lat: $lat, Lng: $lng)";
            break;

        case 'contacts':
            $contacts = $message['contacts'] ?? [];
            $text = "[جهة اتصال] " . json_encode($contacts, JSON_UNESCAPED_UNICODE);
            break;

        case 'order':
            $order = $message['order'] ?? [];
            $text = "[طلب منتج] " . json_encode($order, JSON_UNESCAPED_UNICODE);
            break;

default:
        logMessage('UNSUPPORTED MESSAGE: ' . json_encode($message, JSON_UNESCAPED_UNICODE), 'ERROR');
    // لو الرسالة فيها أي نص مهما كان المفتاح، حتى لو النوع "unsupported" أو غريب
    $fallback = '';
    if (isset($message[$type]) && is_array($message[$type])) {
        foreach (['body', 'caption', 'payload', 'text', 'message', 'value'] as $key) {
            if (!empty($message[$type][$key])) {
                $fallback = $message[$type][$key];
                break;
            }
        }
    }
    // أحيانًا الـ payload نفسه هو نص
    if ($fallback === '' && isset($message[$type]) && is_string($message[$type])) {
        $fallback = $message[$type];
    }
    // لو وجد نص، اعرضه مباشرة (بدون أي قوس أو تعليق)
    if (!empty($fallback)) {
        $text = $fallback;
    } else {
        $details = isset($message[$type]) ? json_encode($message[$type], JSON_UNESCAPED_UNICODE) : '';
        $text = "[نوع رسالة: $type]" . ($details ? ' - ' . $details : '');
    }


    }

    // Handle replies
    if (isset($message['context']['from'])) {
        $text = "رد على رسالة: " . $text;
    }

    $text = trim(strip_tags($text));
    if (empty($text)) $text = "[رسالة فارغة]";

    return mb_substr($text, 0, 1500, 'UTF-8');
}


function sendMessengerMessage(string $to, string $message): bool {
    global $config;
    $payload = json_encode([
        'recipient' => ['id' => $to],
        'message'   => ['text' => $message]
    ], JSON_UNESCAPED_UNICODE);

    $ch = curl_init("https://graph.facebook.com/v19.0/me/messages?access_token={$config['messenger_token']}");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['messenger_timeout'] ?? 8,
        CURLOPT_SSL_VERIFYPEER => true
    ]);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    logMessage("Messenger API response: $httpCode $response", 'INFO', $to);

    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 300;
}


function extractInteractiveMessage(array $interactive): string {
    if ($interactive['button_reply']['title'] ?? false) {
        return $interactive['button_reply']['title'];
    }
    if ($interactive['list_reply']['title'] ?? false) {
        return $interactive['list_reply']['title'];
    }
    if ($interactive['product']['title'] ?? false) {
        return '[استفسار عن منتج: ' . $interactive['product']['title'] . ']';
    }
    return '[رسالة تفاعلية]';
}

function checkRateLimit(string $phone): bool {
    global $config;
    $rateFile = "logs/rate_$phone.txt";
    $now = time();

    if (file_exists($rateFile)) {
        $lastRequest = (int)@file_get_contents($rateFile);
        if ($now - $lastRequest < $config['rate_limit_seconds']) {
            logMessage("Rate limited", 'RATE_LIMIT', $phone);
            addToChatLog($phone, 'تم تجاهل الرسالة بسبب الإرسال السريع', 'system');
            return false;
        }
    }

    @file_put_contents($rateFile, $now);
    return true;
}

function isDuplicateMessage(string $phone, string $message): bool {
    global $config;
    $conversation = loadConversation($phone);
    $now = time();

    foreach (array_slice($conversation, -5) as $msg) {
        if (
            $msg['role'] === 'user' &&
            $msg['content'] === $message &&
            isset($msg['timestamp']) &&
            ($now - $msg['timestamp']) < $config['duplicate_threshold']
        ) {
            logMessage("Duplicate message", 'WARNING', $phone);
            return true;
        }
    }
    return false;
}

function initConversation(array $conversation, array $customer): array {
    global $config;
    if (empty($conversation) || $conversation[0]['role'] !== 'system') {
        $systemPrompt = buildSystemPrompt($customer);
        array_unshift($conversation, ['role' => 'system', 'content' => $systemPrompt]);
    }
    return $conversation;
}

function trimConversationHistory(array $conversation): array {
    global $config;
    if (count($conversation) > $config['max_history']) {
        $systemMsg = array_shift($conversation);
        $conversation = array_slice($conversation, -($config['max_history'] - 1));
        array_unshift($conversation, $systemMsg);
    }
    return $conversation;
}

// ======== Customer Management ========
function loadCustomerData(string $phone): array {
    $file = "customers/" . basename($phone) . ".json";
    if (file_exists($file)) {
        $data = json_decode(file_get_contents($file), true);
        return is_array($data) ? $data : getDefaultCustomerData($phone);
    }
    return getDefaultCustomerData($phone);
}

function getDefaultCustomerData(string $phone): array {
    return [
        'phone' => $phone,
        'business_type' => '',
        'interests' => [],
        'conversation_count' => 0,
        'notes' => [],
        'qualification_status' => 'new',
        'lead_score' => 0,
        'created_at' => time(),
        'last_contact' => time(),
        'conversion_signals' => [],
        'note' => '', // ملاحظة يدوي
        'custom_details' => '', // تفاصيل المشروع
        'followup_date' => null // معاد الفولو اب (يونكس تايم أو null)
    ];
}

function saveCustomerData(string $phone, array $data): void {
    $data['last_contact'] = time();
    $file = "customers/" . basename($phone) . ".json";
    @file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), LOCK_EX);
}

function updateCustomerProfile(array &$customer, string $input): void {
    global $config;
    $input = $input ?? '';
    $customer['conversation_count']++;
    $customer['notes'][] = [
        'msg' => mb_substr($input, 0, 200),
        'ts' => time()
    ];

if (preg_match('/\b\d{4,8}\b/', $input, $otpMatch)) {
    if (!isset($customer['otps'])) $customer['otps'] = [];
    $customer['otps'][] = [
        'code' => $otpMatch[0],
        'ts' => time()
    ];
}

    if (count($customer['notes']) > $config['max_notes']) {
        $customer['notes'] = array_slice($customer['notes'], -$config['max_notes']);
    }

    $lower = mb_strtolower($input, 'UTF-8');

    // Detect business type
    if (empty($customer['business_type'])) {
        $businessPatterns = [
            '/مطعم|كافيه|طعام|restaurant|cafe|food/' => 'مطاعم وكافيهات',
            '/عيادة|طبيب|صيدلية|medical|clinic|pharmacy/' => 'طبي وصحي',
            '/محاماة|محامي|قانوني|law|legal|lawyer/' => 'خدمات قانونية',
            '/متجر|تجارة|بيع|شراء|store|shop|retail/' => 'تجارة إلكترونية',
            '/تعليم|مدرسة|دورات|تدريب|education|training/' => 'تعليمي',
            '/عقارات|شقق|فيلا|أراضي|real estate|property/' => 'عقاري',
            '/تصميم|جرافيك|إعلان|design|advertising/' => 'تصميم وإعلان',
            '/استشارات|خدمات|consulting|services/' => 'استشارات',
            '/تكنولوجيا|برمجة|تطبيقات|tech|programming/' => 'تكنولوجيا',
            '/مصنع|تصنيع|manufacturing|factory/' => 'تصنيع وإنتاج'
        ];

        foreach ($businessPatterns as $regex => $type) {
            if (preg_match($regex . 'u', $lower ?? '')) {
                $customer['business_type'] = $type;
                break;
            }
        }
    }

    // Update qualification status
    if (preg_match('/زائر|visitor|visit/iu', $input ?? '')) {
        $customer['qualification_status'] = 'visitor';
    } elseif (preg_match('/عارض|exhibitor|exhibit|مشارك/iu', $input ?? '')) {
        $customer['qualification_status'] = 'exhibitor';
        $customer['lead_score'] += 10;
    }

    // Detect interests
    $interestPatterns = [
        '/معرض|exhibition|expo|fair/' => 'معارض دولية',
        '/تصدير|export|international/' => 'التصدير والاستيراد',
        '/منتج|product|manufacturing/' => 'عرض المنتجات',
        '/شركة|company|business/' => 'تطوير الأعمال',
        '/تسويق|marketing|promotion/' => 'التسويق الدولي'
    ];

    foreach ($interestPatterns as $regex => $interest) {
        if (preg_match($regex . 'u', $lower ?? '') && !in_array($interest, $customer['interests'])) {
            $customer['interests'][] = $interest;
            $customer['lead_score'] += 2;
        }
    }

    if (count($customer['interests']) > 10) {
        $customer['interests'] = array_slice($customer['interests'], -10);
    }
}

function trackConversionSignals(string $phone, string $userInput, string $aiResponse): void {
    $customer = loadCustomerData($phone);
    $input = mb_strtolower($userInput ?? '', 'UTF-8');
    $signals = [];
    $newlyQualified = false;

    if (preg_match('/مهتم|interested|أريد|want|محتاج|need/u', $input)) {
        $signals['interest_expressed'] = time();
        $customer['lead_score'] += 5;
    }

    if (preg_match('/سعر|price|cost|تكلفة|كام|كم/u', $input)) {
        $signals['price_inquiry'] = time();
        $customer['lead_score'] += 8;
    }

    if (preg_match('/متى|when|موعد|date|تاريخ/u', $input)) {
        $signals['timeline_inquiry'] = time();
        $customer['lead_score'] += 6;
    }

    if (preg_match('/تسجيل|register|اشتراك|booking/u', $input)) {
        $signals['registration_intent'] = time();
        $customer['lead_score'] += 15;
        if ($customer['qualification_status'] !== 'qualified') {
            $customer['qualification_status'] = 'qualified';
            $newlyQualified = true;
        }
    }

    if (preg_match('/اتصال|call|تواصل|contact|رقم|number/u', $input)) {
        $signals['contact_request'] = time();
        $customer['lead_score'] += 12;
        logMessage('Contact requested', 'CONVERSION', $phone);
        $newlyQualified = true; // إشارة قوية تستدعي الإشعار
    }

    if (!empty($signals)) {
        $customer['conversion_signals'] = array_merge($customer['conversion_signals'] ?? [], $signals);
        saveCustomerData($phone, $customer);

        // إشعار فريق المبيعات إذا كانت هناك إشارة مهمة
        if ($newlyQualified) {
            $signalType = isset($signals['registration_intent']) ? 'نية تسجيل' : 'طلب اتصال';
            notifySalesTeam($phone, $customer, $signalType);
        }
    }
}

// ======== Conversation Management ========
function loadConversation(string $phone): array {
    $file = "chats/" . basename($phone) . ".json";
    return file_exists($file) ?
        (json_decode(file_get_contents($file), true) ?? []) :
        [];
}

function saveConversation(string $phone, array $conversation): void {
    $file = "chats/" . basename($phone) . ".json";
    @file_put_contents($file, json_encode($conversation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), LOCK_EX);
}

function addToChatLog(string $phone, string $content, string $role, array $meta = []): void {
    $conversation = loadConversation($phone);
    $conversation[] = [
        'role' => $role,
        'content' => $content,
        'timestamp' => time(),
        'meta' => $meta // بيانات إضافية مثل نوع الرسالة أو ID الميديا أو الكود
    ];
    saveConversation($phone, $conversation);
}


// ======== AI Response Generation ========
function getAIResponse(array $conversation): ?string {
    global $config;

    // 1) قلّل التاريخ المستخدم فعليًا لتقليل التكلفة
    $maxHist = (int)($config['ai_max_history'] ?? 16);
    if ($maxHist > 0 && count($conversation) > $maxHist) {
        // احتفظ بأول رسالة system ثم آخر ($maxHist-1)
        $system = $conversation[0]['role'] === 'system' ? array_shift($conversation) : null;
        $conversation = array_slice($conversation, -($maxHist - 1));
        if ($system) array_unshift($conversation, $system);
    }

    // 2) كاش مبني على محتوى الرسائل
    $cacheKey = md5(json_encode($conversation, JSON_UNESCAPED_UNICODE));
    $cacheFile = "cache/ai_{$cacheKey}.json";
    $ttl = (int)($config['ai_cache_ttl'] ?? 1800);
    if (is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttl)) {
        $cached = json_decode(@file_get_contents($cacheFile), true);
        if (!empty($cached['content'])) {
            return (string)$cached['content'];
        }
    }

    // 3) إعدادات موديل أخف
    $model = $config['ai_model'] ?? 'gpt-4o-mini';
    $temperature = (float)($config['ai_temperature'] ?? 0.3);
    $maxTokens = (int)($config['ai_max_tokens'] ?? 400);

    $payload = json_encode([
        'model' => $model,
        'messages' => $conversation,
        'temperature' => $temperature,
        'max_tokens' => $maxTokens,
        'presence_penalty' => 0.1,
        'frequency_penalty' => 0.1,
    ], JSON_UNESCAPED_UNICODE);

    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . getOpenAIToken(),
        ],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['api_timeout'],
        CURLOPT_SSL_VERIFYPEER => true
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if (curl_errno($ch)) {
        logMessage('cURL error: ' . curl_error($ch), 'API');
        curl_close($ch);
        return null;
    }

    curl_close($ch);

    if ($httpCode !== 200) {
        logMessage("API error $httpCode: $response", 'API');
        return null;
    }

    $data = json_decode($response, true);
    $content = $data['choices'][0]['message']['content'] ?? null;
    if ($content !== null) {
        @file_put_contents($cacheFile, json_encode(['content' => $content, 'ts' => time()], JSON_UNESCAPED_UNICODE));
    }
    return $content;
}

function extractJsonBlock(string $text): ?string {
    $trimmed = trim($text);
    if ($trimmed === '') return null;
    if (strpos($trimmed, '{') === 0) return $trimmed;
    if (preg_match('/```(?:json)?\s*(\{.*\})\s*```/s', $trimmed, $match)) {
        return trim($match[1]);
    }
    $first = strpos($trimmed, '{');
    $last = strrpos($trimmed, '}');
    if ($first === false || $last === false || $last <= $first) return null;
    return trim(substr($trimmed, $first, $last - $first + 1));
}

function normalizeAiPayload(array $payload): array {
    return [
        'reply_text' => trim((string)($payload['reply_text'] ?? '')),
        'media' => is_array($payload['media'] ?? null) ? $payload['media'] : [],
        'language' => trim((string)($payload['language'] ?? '')),
        'intent' => trim((string)($payload['intent'] ?? '')),
        'profile_updates' => is_array($payload['profile_updates'] ?? null) ? $payload['profile_updates'] : [],
        'handover' => (bool)($payload['handover'] ?? false),
        'handover_reason' => trim((string)($payload['handover_reason'] ?? '')),
    ];
}

function parseAiPayload(string $aiResponse): ?array {
    $json = extractJsonBlock($aiResponse);
    if ($json === null) return null;
    $decoded = json_decode($json, true);
    if (!is_array($decoded) || json_last_error() !== JSON_ERROR_NONE) return null;
    return normalizeAiPayload($decoded);
}

function buildJsonReply(string $replyText, string $language = 'ar', array $overrides = []): string {
    $payload = array_merge([
        'reply_text' => $replyText,
        'media' => [],
        'language' => $language,
        'intent' => 'general_inquiry',
        'profile_updates' => [
            'customer_name' => '',
            'company_or_activity' => '',
            'service_interest' => '',
            'screen_interest' => '',
            'budget_range' => '',
            'start_time' => '',
            'city_country' => '',
            'preferred_contact' => '',
            'preferred_time' => ''
        ],
        'handover' => false,
        'handover_reason' => ''
    ], $overrides);
    return json_encode($payload, JSON_UNESCAPED_UNICODE);
}

// ======== WhatsApp Media Helpers ========
function getWhatsAppMediaUrl(string $mediaId): ?array {
    global $config;
    if (!$mediaId) return null;
    $url = "https://graph.facebook.com/v19.0/{$mediaId}";
    $qs = http_build_query(['access_token' => $config['whatsapp_token']]);
    $ch = curl_init("{$url}?{$qs}");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['whatsapp_timeout'] ?? 25,
        CURLOPT_SSL_VERIFYPEER => true,
    ]);
    $res = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($code !== 200) return null;
    $json = json_decode($res, true);
    if (empty($json['url'])) return null;
    return ['url' => $json['url'], 'mime' => $json['mime_type'] ?? 'application/octet-stream'];
}

function downloadWhatsAppMedia(string $mediaId): ?array {
    global $config;
    $info = getWhatsAppMediaUrl($mediaId);
    if (!$info) return null;
    $headers = [
        'Authorization: Bearer ' . $config['whatsapp_token']
    ];
    $ext = 'bin';
    if (!empty($info['mime']) && strpos($info['mime'], '/') !== false) {
        $parts = explode('/', $info['mime']);
        $ext = end($parts);
        $ext = preg_replace('/[^a-z0-9]/i', '', $ext) ?: 'bin';
    }
    if (!is_dir('imports')) @mkdir('imports', 0755, true);
    $dest = 'imports/' . $mediaId . '.' . $ext;

    $fp = fopen($dest, 'wb');
    if (!$fp) return null;

    $ch = curl_init($info['url']);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_TIMEOUT => $config['whatsapp_timeout'] ?? 25,
        CURLOPT_HTTPHEADER => $headers,
    ]);
    $data = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($code >= 200 && $code < 300 && $data !== false) {
        fwrite($fp, $data);
        fclose($fp);
        return ['path' => $dest, 'mime' => $info['mime'] ?? ''];
    }
    fclose($fp);
    @unlink($dest);
    return null;
}

function transcribeAudioOpenAI(string $filePath): ?string {
    global $config;
    if (!is_file($filePath)) return null;
    $model = $config['ai_transcribe_model'] ?? 'whisper-1';

    $ch = curl_init('https://api.openai.com/v1/audio/transcriptions');

    $fields = [
        'model' => $model,
        'file' => new CURLFile($filePath)
    ];

    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getOpenAIToken()
        ],
        CURLOPT_POSTFIELDS => $fields,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['api_timeout'] ?? 30,
        CURLOPT_SSL_VERIFYPEER => true,
    ]);
    $res = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($code !== 200) return null;
    $json = json_decode($res, true);
    return $json['text'] ?? null;
}
function buildSystemPrompt(array $customer): string {
    global $config;
    $businessType = $customer['business_type'] ?: 'غير محدد';
    $interests = $customer['interests'] ? implode(', ', $customer['interests']) : 'غير محدد';
    $status = $customer['qualification_status'] ?? 'new';
    $leadScore = $customer['lead_score'] ?? 0;
    $instagram = trim((string)($config['instagram_url'] ?? ''));
    $website = trim((string)($config['website_url'] ?? ''));
    $hours = trim((string)($config['business_hours'] ?? ''));
    $instagramLabel = $instagram !== '' ? $instagram : 'غير متاحة في البيانات الحالية';
    $websiteLabel = $website !== '' ? $website : 'غير متاحة في البيانات الحالية';
    $hoursLabel = $hours !== '' ? $hours : 'غير متاحة في البيانات الحالية';
    $contactPhone = trim((string)($config['contact_phone'] ?? ''));
    $contactEmail = trim((string)($config['contact_email'] ?? ''));
    $contactAddress = trim((string)($config['contact_address'] ?? ''));
    $contactPhoneLabel = $contactPhone !== '' ? $contactPhone : 'غير متاح';
    $contactEmailLabel = $contactEmail !== '' ? $contactEmail : 'غير متاح';
    $contactAddressLabel = $contactAddress !== '' ? $contactAddress : 'غير متاح';
    $mediaBase = trim((string)($config['media_base_url'] ?? ''));
    if ($mediaBase === '') {
        $mediaBase = 'MEDIA_BASE_URL_NOT_SET';
    }

    return <<<PROMPT
🔸 *بيانات العميل:*
- *نوع النشاط التجاري:* $businessType
- *الاهتمامات:* $interests
- *حالة العميل:* $status
- *درجة التأهيل:* $leadScore نقطة
---
0) تعريف الدور (Role)
أنت مساعد مبيعات وخدمة عملاء لشركة سراج بإدارة اونك ميديا (SERAJ by ONEIC MEDIA).
هدفك: الرد بسرعة وبشكل طبيعي "كأنك شخص" + تجميع بيانات Lead كاملة + الالتزام بمصدر البيانات فقط (بدون اختلاق).

1) قواعد صارمة لمنع الافتاء (No-Hallucination Guardrails)
- ممنوع تذكر أي معلومة غير موجودة داخل Knowledge Base المرفقة في هذا البرومبت.
- إذا سأل العميل عن شيء غير مذكور (سعر نهائي/أماكن غير موجودة/قياسات غير متاحة/روابط غير مؤكدة):
  قل بوضوح: "لا توجد لدي معلومة مؤكدة من بيانات الشركة"
  ثم اطلب البيانات اللازمة وحوّل لفريق المبيعات (handover).
- الأسعار: لا تعطي سعر ثابت نهائي. قل: "السعر يعتمد على (الموقع/المدة/عدد مرات العرض/الفترة)" واجمع التفاصيل.
- لا تذكر أنك "بوت/AI".
- حافظ على الخصوصية: اجمع أقل قدر من البيانات اللازمة، واطلب موافقة مختصرة عند جمع البيانات.

2) أسلوب الرد (Tone & Style)
- سريع، طبيعي، مختصر (1-3 جمل) + سؤال واحد فقط في نهاية الرد.
- إذا كانت الرسالة Instagram Comment: رد مختصر واطلب DM (لأن الكومنت لا يدعم إرسال صور عادة).
- إذا كانت الرسالة DM/WhatsApp: يمكن إرسال صورة + نص عند السؤال عن شاشة/موقع.
- اللغة: حسب العميل (لو كتب عربي → عربي، لو كتب إنجليزي → English).

3) بيانات الشركة (Company Profile) - لا تغيّرها
الاسم التجاري: سراج بإدارة اونك ميديا (SERAJ by ONEIC MEDIA)
الموقع: مسقط, سلطنة عمان

روابط السوشيال:
Instagram: $instagramLabel
Website: $websiteLabel

نبذة قصيرة (سطرين):
نحن شركة إعلانات خارجية بقيادة شابة وطموحة، ننمو بخطى متسارعة لنصبح الأسرع تطورًا في سلطنة عُمان، مع شبكة تغطية قوية تشمل مسقط وتمتد عبر سبع محافظات إقليمية.

نبذة تفصيلية (5-7 سطور):
بالاعتماد على تحليلات سراج ميديا الموثوقة وخبرتها العميقة في قطاع الإعلان، نقوم باختيار وتطوير أصول مميزة في مجال الإعلانات الخارجية (OOH) والإعلانات الرقمية الخارجية (DOOH) بشكل استراتيجي، وذلك في الطرق السريعة والمواقع ذات الكثافة المرورية والجماهيرية العالية على امتداد السلطنة. وبصفتنا بيتًا متخصصًا في الإعلان الخارجي والرقمي، نوفر منصات مؤثرة لحملات عملائنا، بما يضمن وصول رسائلهم إلى الجمهور المستهدف بفاعلية واستمرارية.

نقاط القوة (الميزة التنافسية):
- نطاق تغطية واسع
- نهج مُخصص
- شروط مرنة وتنافسية
- تنوع إبداعي (Static + Digital)

القطاعات التي نخدمها:
وزارات حكومية، شركات حكومية، شركات خاصة

ساعات العمل: $hoursLabel

طرق التواصل الأخرى:
هاتف: $contactPhoneLabel
بريد: $contactEmailLabel
عنوان: $contactAddressLabel

4) About Us (نبذة الشركة من الديك)
- Leading & fastest-growing OOH advertising company in Oman.
- Comprehensive coverage across seven key governorates.
- Founded in 2013 in Muscat.
- Sole Proprietor Company.
- رؤية: تحويل الأفكار لواقع مع الحفاظ على الهوية العُمانية.
- طريقة العمل: استخدام trusted analytics وخبرة الصناعة لاختيار/تطوير أصول OOH + DOOH على طرق سريعة ومواقع high-traffic/high-captive audience.
- منصة قوية لحملات العملاء لضمان وصول الرسائل بشكل فعال ومستمر.
- Trusted by all major brands لتشغيل الحملات (بدون ذكر أسماء عملاء).
- شبكة DOOH تعكس الثقة والقبول والقيادة.
- مواقع الشبكة: top retail & entertainment hubs.
- النتيجة: measurable & lasting impact.
- هوية الشبكة: fusion of heritage and innovation.
- شراكة استراتيجية مع ONEIC وتأسيس ONEIC Media LLC كخطوة نحو قيادة سوق OOH.
- الهدف: إعادة تعريف مشهد الإعلان في عمان وما بعدها عبر creativity + technology + purpose.

5) Why Partner With Us؟
- Extensive Coverage
- Personalized Approach
- Flexible & Competitive Terms
- Creative Variety (Static + Digital)

6) The Largest OOH Advertising Network in Oman
- Largest & most comprehensive OOH network built for impact + reach + real results.
- Exclusive contracts across key governorates.
- Digital screens & billboards عبر الطرق السريعة والمراكز الحضرية.
- Mega digital screens في مناطق high-traffic/high-visibility.
- Satisfied clients عبر الحجوزات السنوية والحملات التكتيكية.
- Over 7,000 SQM total advertising coverage.

7) Exclusive Coverage - Regional Governorates
- صفحة عنوان/خريطة (لا يوجد نص تفصيلي).

8) Regional Network (Governorates & Wilayats)
Al Batinah South: Barka, Musannah, Wadi Al Mawail, Nakhal, Al Awabi, Rustaq, Dema Wa Thaieen.
A'Shargiyah South: Sur, Al Kamil Wafi, Jalan B B Hassan, Jalan B B Ali, Masirah, Wadi Bani Khalid.
A'Shargiyah North: Mudhaibi, Sinaw, Ibra, Al Qabil, Bediya.
Al Batinah North: Suwaiq, Khabourah, Saham, Sohar, Liwa, Shinas.
Al Buraimi: Buraimi, Madhah, Al Sunaynah, Madhah (مكررة).
Musandam: Bukha, Khasab, Dibba Al-Bay'ah.
A'Dhahirah: Ibri, Dhank, Yanqul.

9) Our Mega Digital Screens
عنوان فقط (لا تفاصيل نصية).

10) Mega Screens List
Qurum Rooftop, Qurum Digital Wall, Amerat Digital Wall, Ruwi Digital Wall, Azaiba 3D Wall, Al Hail Rooftop, Mabeelah Rooftop, Nizwa Rooftop, Ghala Heights Rooftop, Al Hail 2 Wall, Seeb Souq Wall.

11) Screen Profiles (الأرقام من أدوات AI متقدمة لقياس التعرض)
ملاحظة ثابتة: These figures are generated using our Advance AI tools that provide accurate measurement of audience exposure.

MEDIA_BASE_URL = $mediaBase

A) Qurum Rooftop
Size: 32M x 7M | Resolution: 3360 x 768 | Pixel Pitch: P10
Description AR: تقع هذه الشاشة الرقمية الخارجية على شارع السلطان قابوس المزدحم في القرم… أكبر وأول شاشة رقمية منحنية في سلطنة عُمان…
Visibility: Daily 70K-80K | Monthly 2.1M-2.4M | Per Annum 25M-29M
Landmarks: Oman Arab banks, Muscat Expressway, ROP HQ, Bank Muscat, Hilton Double Tree, Mercedes Benz Showroom
Google Coordinates: غير متاحة في البيانات الحالية

B) Qurum Wall
Size: 5M x 15M | Resolution: 480 x 1440 | Pixel Pitch: P10
Description AR: تقع هذه الشاشة الرقمية في موقع استراتيجي على شارع السلطان قابوس…
Visibility: Daily 70K-80K | Monthly 2.1M-2.4M | Per Annum 25M-29M
Landmarks: نفس قائمة Qurum Rooftop
Coordinates: غير متاحة في البيانات الحالية

C) Amerat Digital Wall
Size: 20M x 10M | Resolution: 1920 x 960 | Pixel Pitch: P10
Description AR: تقع عند مدخل العامرات بالقرب من الدوار الأول… الأكبر والأولى…
Visibility: Daily 50K-60K | Monthly 1.5M-1.9M | Per Annum 18M-22M
Landmarks: Oman Arab banks, LuLu Amerat, Toyota Parts Center, Way to Quriyath/Sur, Way to Amerat Park, Mal Mart
Coordinates: غير متاحة في البيانات الحالية

D) Ruwi Digital Wall
Size: 5M x 10M | Resolution: 480 x 1056 | Pixel Pitch: P10
Description AR: تقع عند إشارات روي الرئيسية… مرئية من إشارات فندق شيراتون…
Visibility: Daily 50K-60K | Monthly 1.5M-1.9M | Per Annum 18M-22M
Landmarks: Ruwi Main Signals, Nesto Ruwi, Badr Sama, Sultan Qaboos Mosque Ruwi, Main Mawasalat Bus Stop, Ruwi R/A
Coordinates: غير متاحة في البيانات الحالية

E) Azaiba 3D Wall
Type: 3D Screen
Size: 11.52M (3.84M + 7.68M) x 6.72M | Resolution: 1152 x 672 | Pixel Pitch: P10
Description AR: مشهد بصري ديناميكي بتقنية 3D متقدمة… يترك انطباعًا لا يُنسى.
Visibility: Daily 50K-60K | Monthly 1.5M-1.9M | Per Annum 18M-22M
Landmarks: NBO Head Office, Enza Home, Bank Muscat, Bank Dhofar
Coordinates: غير متاحة في البيانات الحالية

F) Al Hail Rooftop
Size: 30M x 6.5M | Resolution: 2896 x 576 | Pixel Pitch: P10
Description AR: على طريق السلطان قابوس… رؤية واضحة طوال اليوم وتفاعل كبير.
Visibility: Daily 80K-90K | Monthly 2.4M-2.7M | Per Annum 29M-33M
Landmarks: Shah Nagardas, Sultan Qaboos Road, Nesto, Towell Auto Center
Coordinates: غير متاحة في البيانات الحالية

G) Mabeelah Rooftop
Size: 25M x 6M | Resolution: 2496 x 576 | Pixel Pitch: P10
Description AR: أكبر شاشة في مابيلة… رؤية لا مثيل لها وحضور قوي للعلامة التجارية…
Visibility: Daily 50K-60K | Monthly 1.5M-1.9M | Per Annum 18M-22M
Landmarks: Oman Oil, Sultan Qaboos Road, Al Maha Fuel Station
Coordinates: غير متاحة في البيانات الحالية

H) Nizwa Rooftop
Size: 8M x 4M | Resolution: 768 x 384 | Pixel Pitch: P10
Description AR: تستهدف المتجهين إلى سوق نزوى عند تقاطع مزدحم على طريق تنوف.
Visibility: Daily 9K-10K | Monthly 1.5M-1.9M | Per Annum 270K-300K
Note: الأرقام كما وردت وقد تكون غير متسقة.
Landmarks: Nizwa Souk, Nizwa Fort, MOB, Bank Dhofar, Bank Muscat
Coordinates: غير متاحة في البيانات الحالية

I) Ghala Heights Rooftop
Size: 40M x 7M | Pixel Pitch: P10 | Resolution: غير متاحة
Description AR: على طريق المطار باتجاه المدينة عند موفنبيك…
Visibility: Daily 80K-90K | Monthly 2.4M-2.7M | Per Annum 29M-33M
Landmarks: Muscat International Airport, Qatar Airways, Movenpick, Al Fardan, Premium Motors/Audi
Status: Expected launch soon…
Coordinates: غير متاحة في البيانات الحالية

J) Al Hail 2 Wall
Size: 25M x 6M | Resolution: 2496 x 576 | Pixel Pitch: P10
Visibility: Daily 80K-90K | Monthly 2.4M-2.7M | Per Annum 29M-33M
Status: Expected launch soon…
Details AR/EN: غير متاحة إضافيًا

K) Seeb Souq Wall
Size: 5M x 7M | Pixel Pitch: P10 | Resolution: غير متاحة
Description AR: طريق شرياني مزدحم في قلب السيب قرب منطقة سوق/تجزئة كبيرة لزيادة مدة التعرض.
Visibility: Daily 30K-40K | Monthly 0.9M-1.2M | Per Annum 10.8M-14.4M
Landmarks: Souq Al Seeb, Seeb Mall, Jewelry Market, Seeb Central Market, Bank Muscat, Omantel
Status: Expected launch soon…
Coordinates: غير متاحة في البيانات الحالية

12) ما نجمعه ولماذا (Lead Qualification هدفه Odoo)
هدف البوت ليس فقط الرد، بل إنشاء Lead "مؤهل" داخل Odoo ببيانات تساعد فريق المبيعات:
- نوع الخدمة المطلوبة/الاهتمام ✅
- رقم واتساب ✅ (تلقائي) + اسم العميل (إن توفر)
- اسم الشركة/النشاط (B2B)
- الميزانية التقريبية (اختياري لكنه مهم)
- الجدول الزمني/موعد البدء
- المدينة/الدولة
- أفضل طريقة تواصل: مكالمة/واتساب/إيميل + الوقت المناسب
- تفاصيل مختصرة + روابط/مرفقات إن وجدت
موافقة مختصرة: "بإرسال بياناتك أنت توافق على استخدامها للتواصل بخصوص طلبك."

13) مسارات المحادثة (Flows)
ترحيب + تعريف + اختيار اهتمام:
- ترحيب باسم الشركة + نبذة سطرين
- سؤال اختيار: ما الخدمة/الشاشة اللي مهتم بيها؟
- لو غير محدد: اسأل عن الهدف (مبيعات/براند/إطلاق/حملة)

تأهيل العميل (أسئلة ثابتة قدر الإمكان):
- ما المجال/النشاط؟
- الميزانية التقريبية؟ (اختياري لكن مهم)
- موعد البدء؟
- أسئلة إضافية حسب الخدمة/الشاشة: المدينة/الموقع المستهدف، مدة الحملة، هل العميل يريد شاشة معينة أم اقتراح

عرض قيمة + دليل اجتماعي (Proof):
- اقترح 1-2 خيار مناسب بناءً على إجابات العميل
- اذكر نقاط القوة فقط (Coverage/Personalized/Flexible/Variety)
- لا تذكر أسماء عملاء؛ قل: نخدم جهات حكومية وشركات خاصة.

إغلاق + تحويل:
- أكّد حفظ البيانات
- اسأل عن طريقة التواصل المفضلة/الوقت
- لو خارج ساعات العمل: رسالة تلقائية

14) قواعد التصعيد لموظف (Human Handover)
- إذا طلب العميل: مكالمة الآن / عرض سعر فوري / مقابلة
- إذا لم تفهم بعد محاولتين
- إذا محتوى حساس/شكوى/طلب استرجاع/نزاع
رسالة التحويل: "تم ✅ هحوّل طلبك لفريقنا وهنرجع لك في أقرب وقت. ممكن تكتب اسمك ووقت مناسب للتواصل؟"

15) إخراج البوت (Output Format)
أخرج JSON فقط بالشكل التالي:
{
  "reply_text": "نص الرد للعميل",
  "media": [
    {
      "type": "image",
      "url": "MEDIA_BASE_URL/qurum_rooftop.jpg",
      "caption": "اختياري: وصف قصير"
    }
  ],
  "language": "ar|en",
  "intent": "screen_inquiry|general_inquiry|pricing|handover|qualification",
  "profile_updates": {
    "customer_name": "",
    "company_or_activity": "",
    "service_interest": "",
    "screen_interest": "",
    "budget_range": "",
    "start_time": "",
    "city_country": "",
    "preferred_contact": "",
    "preferred_time": ""
  },
  "handover": false,
  "handover_reason": ""
}

قواعد الـmedia:
- لو العميل سأل عن شاشة محددة → media فيها صورة الشاشة + النص الجاهز.
- لو Instagram Comment → media فاضية + اطلب DM.
PROMPT;
}




/**
 * Sends an interactive message with up to 3 buttons.

 */
function sendInteractiveMessage(string $to, string $body, array $buttons): bool {
    global $config;

    $buttonPayloads = [];
    foreach (array_slice($buttons, 0, 3) as $i => $buttonTitle) {
        $buttonPayloads[] = [
            'type' => 'reply',
            'reply' => [
                'id' => 'btn' . ($i+1), // لازم id بسيط جدًا
                'title' => $buttonTitle
            ]
        ];
    }

    $payload = json_encode([
        'messaging_product' => 'whatsapp',
        'to' => $to,
        'type' => 'interactive',
        'interactive' => [
            'type' => 'button',
            'body' => ['text' => $body],
            'action' => ['buttons' => $buttonPayloads]
        ]
    ], JSON_UNESCAPED_UNICODE);

    $ch = curl_init("https://graph.facebook.com/v19.0/{$config['phone_number_id']}/messages");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['whatsapp_token'],
        ],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['whatsapp_timeout'],
        CURLOPT_SSL_VERIFYPEER => true
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    logMessage("WhatsApp API response: $httpCode $response", 'INFO', $to);

    if (curl_errno($ch)) {
        logMessage('WhatsApp Interactive error: ' . curl_error($ch), 'ERROR', $to);
        curl_close($ch);
        return false;
    }
    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 300;
}



function notifySalesTeam(string $phone, array $customer, string $signalType): void {
    // Broadcast to all configured sales numbers (new behavior)
    global $config;
    $msg = "إشعار مبيعات ($signalType): عميل مهتم $phone\n" .
           "الحالة: " . ($customer['qualification_status'] ?? 'new') . " | النقاط: " . ($customer['lead_score'] ?? 0);
    $numbers = $config['sales_notify_numbers'] ?? [];
    if (is_string($numbers)) { $numbers = [$numbers]; }
    foreach ($numbers as $n) { @sendInternalAlert($n, $msg); }
    $manager = $config['sales_manager_number'] ?? '96896651520';
    if ($manager) { @sendInternalAlert($manager, "[تنبيه مدير المبيعات] $msg"); }
    logMessage("Sales Team notified for $signalType signal from $phone", 'CONVERSION', $phone);
    return;
    $msg = "عميل مؤهل ($signalType): رقم الهاتف $phone، حالة العميل: {$customer['qualification_status']}، نقاط: {$customer['lead_score']}";

    // إرسال تنبيه لـ WhatsApp الخاص بفريق المبيعات
    sendWhatsAppMessage("96896651520", $msg);

    // حفظ السجل
    logMessage("Sales Team notified for $signalType signal from $phone", 'CONVERSION', $phone);
}


// Send a sales notification when a new chat starts
function notifySalesOnNewChat(string $phone, string $platform, array $customer): void {
    global $config;

    // Avoid duplicate notifications if already sent
    if (!empty($customer['first_chat_notified'])) {
        return;
    }

    $numbers = $config['sales_notify_numbers'] ?? [];
    if (is_string($numbers)) { $numbers = [$numbers]; }

    $leadScore = (string)($customer['lead_score'] ?? 0);
    $qStatus = (string)($customer['qualification_status'] ?? 'new');
    $ts = date('Y-m-d H:i');

    $msg = "إشعار مبيعات: بدأ عميل محادثة جديدة\n" .
           "الهاتف: +$phone\n" .
           "المنصة: $platform\n" .
           "الحالة: $qStatus | النقاط: $leadScore\n" .
           "الوقت: $ts";

    foreach ($numbers as $n) {
        @sendInternalAlert($n, $msg);
    }
    // Extra emphasized copy to Sales Manager
    $manager = $config['sales_manager_number'] ?? '96896651520';
    if ($manager && !in_array($manager, $numbers, true)) {
        @sendInternalAlert($manager, "[تنبيه مدير المبيعات] $msg");
    } else if ($manager) {
        @sendInternalAlert($manager, "[تنبيه إضافي] $msg");
    }

    // Mark as notified and persist
    $customer['first_chat_notified'] = time();
    saveCustomerData($phone, $customer);

    logMessage("Sales notified for new chat", 'CONVERSION', $phone);
}





// ======== Media Sending (WhatsApp + Messenger + Instagram) ========
function isHttpUrl(string $value): bool {
    if ($value === '') return false;
    $filtered = filter_var($value, FILTER_VALIDATE_URL);
    if ($filtered === false) return false;
    $scheme = strtolower((string)parse_url($filtered, PHP_URL_SCHEME));
    return $scheme === 'http' || $scheme === 'https';
}

function resolveMediaRef(string $ref): string {
    global $config;
    $ref = trim($ref);
    if ($ref === '') return '';
    if (stripos($ref, 'MEDIA_BASE_URL') === 0) {
        $base = rtrim((string)($config['media_base_url'] ?? ''), '/');
        $path = ltrim(substr($ref, strlen('MEDIA_BASE_URL')), '/');
        return $base === '' ? $path : $base . '/' . $path;
    }
    if (isHttpUrl($ref) || is_file($ref)) return $ref;
    $localDir = $config['media_local_dir'] ?? (__DIR__ . '/media_screens');
    $localPath = rtrim($localDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($ref);
    if (is_file($localPath)) return $localPath;
    if (!empty($config['media_base_url'])) {
        return rtrim($config['media_base_url'], '/') . '/' . ltrim($ref, '/');
    }
    return $ref;
}

function detectMimeType(string $filePath): string {
    $mime = '';
    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        if ($finfo) {
            $mime = (string)finfo_file($finfo, $filePath);
            finfo_close($finfo);
        }
    }
    if ($mime === '') {
        $ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if (in_array($ext, ['jpg', 'jpeg'], true)) {
            $mime = 'image/jpeg';
        } elseif ($ext === 'png') {
            $mime = 'image/png';
        } elseif ($ext === 'gif') {
            $mime = 'image/gif';
        } else {
            $mime = 'application/octet-stream';
        }
    }
    return $mime;
}

function uploadWhatsAppMedia(string $filePath): ?string {
    global $config;
    if (!is_file($filePath)) return null;
    $mime = detectMimeType($filePath);
    $fields = [
        'messaging_product' => 'whatsapp',
        'type' => $mime,
        'file' => new CURLFile($filePath, $mime, basename($filePath)),
    ];

    $ch = curl_init("https://graph.facebook.com/v19.0/{$config['phone_number_id']}/media");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $config['whatsapp_token'],
        ],
        CURLOPT_POSTFIELDS => $fields,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['whatsapp_timeout'] ?? 25,
        CURLOPT_SSL_VERIFYPEER => true
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    logMessage("WhatsApp media upload response: $httpCode $response", 'API');
    if (curl_errno($ch)) {
        logMessage('WhatsApp media upload error: ' . curl_error($ch), 'ERROR');
    }
    curl_close($ch);

    if ($httpCode < 200 || $httpCode >= 300) return null;
    $data = json_decode($response, true);
    return $data['id'] ?? null;
}

function sendWhatsAppImageById(string $to, string $mediaId, string $caption = ''): bool {
    global $config;

    if ($caption !== '' && mb_strlen($caption, 'UTF-8') > 1000) {
        $caption = mb_substr($caption, 0, 1000, 'UTF-8') . '...';
    }

    $payload = json_encode([
        'messaging_product' => 'whatsapp',
        'to' => $to,
        'type' => 'image',
        'image' => [
            'id' => $mediaId,
            'caption' => $caption
        ]
    ], JSON_UNESCAPED_UNICODE);

    $ch = curl_init("https://graph.facebook.com/v19.0/{$config['phone_number_id']}/messages");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['whatsapp_token']
        ],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => true
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return $httpCode >= 200 && $httpCode < 300;
}

function sendWhatsAppImage(string $to, string $imageRef, string $caption = ''): bool {
    global $config;

    if ($caption !== '' && mb_strlen($caption, 'UTF-8') > 1000) {
        $caption = mb_substr($caption, 0, 1000, 'UTF-8') . '...';
    }

    if (isHttpUrl($imageRef)) {
        $payload = json_encode([
            'messaging_product' => 'whatsapp',
            'to' => $to,
            'type' => 'image',
            'image' => [
                'link' => $imageRef,
                'caption' => $caption
            ]
        ], JSON_UNESCAPED_UNICODE);

        $ch = curl_init("https://graph.facebook.com/v19.0/{$config['phone_number_id']}/messages");
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $config['whatsapp_token']
            ],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 15,
            CURLOPT_SSL_VERIFYPEER => true
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode >= 200 && $httpCode < 300;
    }

    if (is_file($imageRef)) {
        $mediaId = uploadWhatsAppMedia($imageRef);
        if ($mediaId) {
            return sendWhatsAppImageById($to, $mediaId, $caption);
        }
    }

    return false;
}

function uploadMessengerAttachment(string $accessToken, string $filePath): ?string {
    global $config;
    if (!is_file($filePath)) return null;
    $mime = detectMimeType($filePath);
    $fields = [
        'message' => json_encode([
            'attachment' => [
                'type' => 'image',
                'payload' => ['is_reusable' => true]
            ]
        ], JSON_UNESCAPED_UNICODE),
        'filedata' => new CURLFile($filePath, $mime, basename($filePath))
    ];

    $ch = curl_init("https://graph.facebook.com/v19.0/me/message_attachments?access_token={$accessToken}");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $fields,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['messenger_timeout'] ?? 8,
        CURLOPT_SSL_VERIFYPEER => true
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    logMessage("Messenger attachment upload response: $httpCode $response", 'API');
    if (curl_errno($ch)) {
        logMessage('Messenger attachment upload error: ' . curl_error($ch), 'ERROR');
    }
    curl_close($ch);

    if ($httpCode < 200 || $httpCode >= 300) return null;
    $data = json_decode($response, true);
    return $data['attachment_id'] ?? null;
}

function sendMessengerImage(string $to, string $imageRef): bool {
    global $config;

    if (isHttpUrl($imageRef)) {
        $payload = json_encode([
            'recipient' => ['id' => $to],
            'message' => [
                'attachment' => [
                    'type' => 'image',
                    'payload' => [
                        'url' => $imageRef,
                        'is_reusable' => true
                    ]
                ]
            ]
        ], JSON_UNESCAPED_UNICODE);

        $ch = curl_init("https://graph.facebook.com/v19.0/me/messages?access_token={$config['messenger_token']}");
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => $config['messenger_timeout'] ?? 8,
            CURLOPT_SSL_VERIFYPEER => true
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode >= 200 && $httpCode < 300;
    }

    if (is_file($imageRef)) {
        $attachmentId = uploadMessengerAttachment($config['messenger_token'], $imageRef);
        if (!$attachmentId) return false;
        $payload = json_encode([
            'recipient' => ['id' => $to],
            'message' => [
                'attachment' => [
                    'type' => 'image',
                    'payload' => [
                        'attachment_id' => $attachmentId
                    ]
                ]
            ]
        ], JSON_UNESCAPED_UNICODE);

        $ch = curl_init("https://graph.facebook.com/v19.0/me/messages?access_token={$config['messenger_token']}");
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => $config['messenger_timeout'] ?? 8,
            CURLOPT_SSL_VERIFYPEER => true
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode >= 200 && $httpCode < 300;
    }

    return false;
}

function sendInstagramImage(string $userId, string $imageRef, string $accessToken): bool {
    $url = "https://graph.facebook.com/v19.0/me/messages";

    if (isHttpUrl($imageRef)) {
        $payload = json_encode([
            'recipient' => ['id' => $userId],
            'message' => [
                'attachment' => [
                    'type' => 'image',
                    'payload' => [
                        'url' => $imageRef,
                        'is_reusable' => true
                    ]
                ]
            ],
            'messaging_type' => 'RESPONSE'
        ], JSON_UNESCAPED_UNICODE);

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $accessToken
            ],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_TIMEOUT => 15
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode >= 200 && $httpCode < 300;
    }

    if (is_file($imageRef)) {
        $attachmentId = uploadMessengerAttachment($accessToken, $imageRef);
        if (!$attachmentId) return false;
        $payload = json_encode([
            'recipient' => ['id' => $userId],
            'message' => [
                'attachment' => [
                    'type' => 'image',
                    'payload' => [
                        'attachment_id' => $attachmentId
                    ]
                ]
            ],
            'messaging_type' => 'RESPONSE'
        ], JSON_UNESCAPED_UNICODE);

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $accessToken
            ],
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_TIMEOUT => 15
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode >= 200 && $httpCode < 300;
    }

    return false;
}

function sendImageOnly(string $platform, string $to, string $imageRef, string $caption = ''): bool {
    global $config;

    if ($platform === 'whatsapp') {
        return sendWhatsAppImage($to, $imageRef, $caption);
    }
    if ($platform === 'instagram') {
        return sendInstagramImage($to, $imageRef, $config['facebook_token']);
    }
    return sendMessengerImage($to, $imageRef);
}

/**
 * Send an image + text in the best way per platform:
 * - WhatsApp: image then text (caption optional)
 * - Messenger: image then text
 * - Instagram: image then text (via Instagram DM API)
 */
function sendMediaCard(string $platform, string $to, string $imageRef, string $text, string $caption = ''): bool {
    global $config;

    $okImg = false;
    if ($imageRef !== '') {
        $okImg = sendImageOnly($platform, $to, $imageRef, $caption);
    }

    $okTxt = false;
    if ($text !== '') {
        if ($platform === 'instagram') {
            $okTxt = sendInstagramDM($to, $text, $config['facebook_token']);
        } elseif ($platform === 'messenger') {
            $okTxt = sendMessengerMessage($to, $text);
        } else {
            $okTxt = sendWhatsAppMessage($to, $text);
        }
    }
    return $okImg || $okTxt;
}


// ======== WhatsApp Integration ========
function sendWhatsAppMessage(string $to, string $message): bool {
    global $config;
    
    $maxLen = (int)($config['whatsapp_text_limit'] ?? 3500);
    if ($maxLen > 0 && mb_strlen($message, 'UTF-8') > $maxLen) {
        $message = mb_substr($message, 0, $maxLen, 'UTF-8') . '...';
    }
    
    $payload = json_encode([
        'messaging_product' => 'whatsapp',
        'to' => $to,
        'type' => 'text',
        'text' => ['body' => $message]
    ], JSON_UNESCAPED_UNICODE);
    
    $ch = curl_init("https://graph.facebook.com/v19.0/{$config['phone_number_id']}/messages");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['whatsapp_token'],
        ],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['whatsapp_timeout'],
        CURLOPT_SSL_VERIFYPEER => true
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    // Log API response for diagnostics
    logMessage("WhatsApp API response (text): $httpCode $response", 'API', $to);

    if (curl_errno($ch)) {
        logMessage('WhatsApp error: ' . curl_error($ch), 'ERROR', $to);
        curl_close($ch);
        return false;
    }
    
    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 300;
}

// Sends a WhatsApp template message (fallback for outside 24h window)
function sendWhatsAppTemplate(string $to, string $templateName, array $components = [], string $lang = 'ar'): bool {
    global $config;
    $payload = [
        'messaging_product' => 'whatsapp',
        'to' => $to,
        'type' => 'template',
        'template' => [
            'name' => $templateName,
            'language' => ['code' => $lang],
        ]
    ];
    if (!empty($components)) {
        $payload['template']['components'] = $components;
    }
    $json = json_encode($payload, JSON_UNESCAPED_UNICODE);
    $ch = curl_init("https://graph.facebook.com/v19.0/{$config['phone_number_id']}/messages");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['whatsapp_token'],
        ],
        CURLOPT_POSTFIELDS => $json,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['whatsapp_timeout'],
        CURLOPT_SSL_VERIFYPEER => true
    ]);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    logMessage("WhatsApp API response (template): $httpCode $response", 'API', $to);
    if (curl_errno($ch)) {
        logMessage('WhatsApp template error: ' . curl_error($ch), 'ERROR', $to);
        curl_close($ch);
        return false;
    }
    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 300;
}

// Helper to send alerts to internal team with template fallback
function sendInternalAlert(string $to, string $message): bool {
    global $config;
    $ok = sendWhatsAppMessage($to, $message);
    if ($ok) return true;
    $tpl = trim((string)($config['whatsapp_alert_template'] ?? ''));
    if ($tpl === '') return false;
    $lang = (string)($config['template_language'] ?? 'ar');
    // Single body parameter with full alert text
    $components = [
        [
            'type' => 'body',
            'parameters' => [ ['type' => 'text', 'text' => $message] ]
        ]
    ];
    return sendWhatsAppTemplate($to, $tpl, $components, $lang);
}

// ======== Error Handling ========
function handleError(Throwable $e, ?string $from, ?string $userInput): void {
    $errorMsg = $e->getMessage();
    $traceId = uniqid('err_');
    
    logMessage("Error [$traceId]: $errorMsg", 'ERROR', $from);
    
    if ($from && preg_match('/^\d{10,15}$/', $from)) {
        $errorResponse = 'شكرًا لاهتمامك! حدث خطأ تقني وسنعود لك قريبًا. يمكنك مشاركة طلبك هنا.' . buildContactSnippet('ar');
        sendWhatsAppMessage($from, $errorResponse);
        
        if ($userInput) {
            $meta = [
                'source' => 'error_handler',
                'trace_id' => $traceId,
            ];
            addToChatLog($from, $userInput, 'user', $meta);
            addToChatLog($from, $errorResponse, 'assistant');
        }
        
        $customer = loadCustomerData($from);
        $customer['last_error'] = [
            'message' => $errorMsg,
            'trace_id' => $traceId,
            'timestamp' => time()
        ];
        saveCustomerData($from, $customer);
    }
    
    http_response_code(500);
    echo json_encode(['error' => 'Internal error', 'trace_id' => $traceId]);
}

// ======== File Maintenance ========
function cleanupOldFiles(): void {
    $thirtyDaysAgo = time() - (30 * 86400);
    
    // تنظيف ملفات الـ rate limit
    foreach (glob('logs/rate_*.txt') as $file) {
        if (@filemtime($file) < $thirtyDaysAgo) @unlink($file);
    }
    
    // تنظيف ملفات الـ cache (بعد ساعة واحدة)
    $oneHourAgo = time() - 3600;
    foreach (glob('cache/comment_processed_*.txt') as $file) {
        if (@filemtime($file) < $oneHourAgo) @unlink($file);
    }
}



function replyToComment($commentId, $replyText, $accessToken, $platform = 'facebook') {
    if (empty($commentId) || empty($replyText) || empty($accessToken)) {
        logMessage("Reply failed: Missing parameters", 'ERROR');
        return false;
    }
    
    // جرب طرق مختلفة للرد
    $urls = [];
    
    if ($platform === 'instagram') {
        $urls[] = "https://graph.facebook.com/v19.0/{$commentId}/replies";
        $urls[] = "https://graph.facebook.com/v19.0/{$commentId}/comments";
    } else {
        $urls[] = "https://graph.facebook.com/v19.0/{$commentId}/comments";
        
        // إذا كان المعرف مُركب، جرب الجزء الثاني
        if (strpos($commentId, '_') !== false) {
            $parts = explode('_', $commentId);
            $simpleId = end($parts);
            $urls[] = "https://graph.facebook.com/v19.0/{$simpleId}/comments";
        }
    }
    
    foreach ($urls as $url) {
        $success = attemptCommentReply($url, $replyText, $accessToken);
        if ($success) {
            logMessage("Comment reply successful with URL: $url", 'INFO');
            return true;
        }
    }
    
    logMessage("All reply attempts failed for comment: $commentId", 'ERROR');
    return false;
}

function attemptCommentReply($url, $replyText, $accessToken) {
    $data = [
        'message' => $replyText,
        'access_token' => $accessToken
    ];
    
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/x-www-form-urlencoded',
            'User-Agent: SmartLogicBot/1.0'
        ]
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    // Log محاولة الرد
    file_put_contents('logs/comment_reply_debug.log', 
        date('Y-m-d H:i:s') . " Reply attempt\n" .
        "URL: $url\n" .
        "HTTP: $httpCode\n" .
        "Response: $response\n\n", 
        FILE_APPEND
    );
    
    curl_close($ch);
    
    return $httpCode >= 200 && $httpCode < 300;
}






function likeComment($commentId, $accessToken) {
    if (empty($commentId) || empty($accessToken)) {
        return false;
    }
    
    // محاولة عمل لايك مع طرق مختلفة
    $attempts = [
        $commentId,  // المعرف الكامل
        explode('_', $commentId)[1] ?? $commentId  // الجزء الثاني إذا كان مُركب
    ];
    
    foreach ($attempts as $id) {
        if (empty($id)) continue;
        
        $success = attemptCommentLike($id, $accessToken);
        if ($success) {
            logMessage("Comment liked successfully with ID: $id", 'INFO');
            return true;
        }
    }
    
    logMessage("All like attempts failed for comment: $commentId", 'WARNING');
    return false;
}

function attemptCommentLike($commentId, $accessToken) {
    $url = "https://graph.facebook.com/v19.0/{$commentId}/likes";
    
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/x-www-form-urlencoded',
            'User-Agent: SmartLogicBot/1.0'
        ],
        CURLOPT_POSTFIELDS => "access_token=" . urlencode($accessToken),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_TIMEOUT => 10
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    // Log محاولة اللايك
    file_put_contents('logs/like_attempts.log', 
        date('Y-m-d H:i:s') . " Like attempt: $commentId, HTTP: $httpCode\n" .
        "URL: $url\n" .
        "Response: $response\n\n", 
        FILE_APPEND
    );
    
    curl_close($ch);
    
    return $httpCode >= 200 && $httpCode < 300;
}









function sendInstagramDM($userId, $message, $accessToken) {
    // Instagram DMs تستخدم نفس API الـ Messenger
    $url = "https://graph.facebook.com/v19.0/me/messages";
    
    $payload = json_encode([
        'recipient' => ['id' => $userId],
        'message'   => ['text' => $message],
        'messaging_type' => 'RESPONSE' // مهم للـ Instagram
    ], JSON_UNESCAPED_UNICODE);
    
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $accessToken
        ],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_USERAGENT => 'SmartLogicBot/1.0'
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    logMessage("Instagram DM API response: $httpCode $response", 'INFO', $userId);
    
    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 300;
}




function fetchCommentText($commentId, $accessToken) {
    if (empty($commentId) || empty($accessToken)) {
        return '';
    }
    
    // جرب fields مختلفة للحصول على النص
    $fields = ['message', 'text', 'from', 'created_time'];
    $url = "https://graph.facebook.com/v19.0/$commentId?" . 
           "fields=" . implode(',', $fields) . 
           "&access_token=$accessToken";
    
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_USERAGENT => 'SmartLogicBot/1.0'
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    // Log الاستجابة للتشخيص
    file_put_contents('logs/fetch_comment.log', 
        date('Y-m-d H:i:s') . " Comment ID: $commentId, HTTP: $httpCode\n" .
        "Response: $response\n\n", 
        FILE_APPEND
    );
    
    curl_close($ch);
    
    // إذا فشل الـ API، ارجع نص فارغ بدلاً من خطأ
    if ($httpCode !== 200) {
        logMessage("Failed to fetch comment $commentId: HTTP $httpCode - trying to proceed without API text", 'WARNING');
        return '';
    }
    
    $json = json_decode($response, true);
    return $json['message'] ?? $json['text'] ?? '';
}




function postReplyToPost($postId, $replyText, $accessToken) {
    if (empty($postId) || empty($replyText) || empty($accessToken)) {
        return false;
    }
    
    // إذا فشل الرد على التعليق، جرب إنشاء comment جديد على الـ post
    $url = "https://graph.facebook.com/v19.0/{$postId}/comments";
    
    $data = [
        'message' => $replyText,
        'access_token' => $accessToken
    ];
    
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_TIMEOUT => 15
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    // Log محاولة الرد على الـ post
    file_put_contents('logs/post_reply_attempts.log', 
        date('Y-m-d H:i:s') . " Attempting post reply to: $postId, HTTP: $httpCode\n" .
        "Response: $response\n\n", 
        FILE_APPEND
    );
    
    curl_close($ch);
    
    return $httpCode >= 200 && $httpCode < 300;
}



function createReplyWithMention($replyText, $userId, $platform) {
    if ($platform === 'instagram') {
        // Instagram: محاولة منشن بسيط
        return "شكرًا لتعليقك! 🙏 @" . $userId . "\n\n" . $replyText;
    } else {
        // Facebook: منشن متقدم
        return "شكرًا لتعليقك! 🙏 @[$userId]\n\n" . $replyText;
    }
}





// ===== Odoo JSON-RPC Helpers =====
function odooRpc($url, $service, $method, $args) {
    $payload = json_encode([
        'jsonrpc' => '2.0',
        'method'  => 'call',
        'params'  => [
            'service' => $service,
            'method'  => $method,
            'args'    => $args
        ],
        'id' => rand(1, 999999)
    ], JSON_UNESCAPED_UNICODE);

    $ch = curl_init(rtrim($url,'/').'/jsonrpc');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => true
    ]);
    $resp = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($code !== 200 || !$resp) throw new Exception("Odoo RPC HTTP $code");
    $json = json_decode($resp, true);
    if (isset($json['error'])) throw new Exception("Odoo RPC Error: ".json_encode($json['error'], JSON_UNESCAPED_UNICODE));
    return $json['result'];
}

function odooAuthUid($odoo) {
    return odooRpc($odoo['url'], 'common', 'authenticate', [
        $odoo['db'], $odoo['user'], $odoo['pass'], []
    ]);
}

function odooSearchRead($odoo, $uid, $model, $domain, $fields=['id'], $limit=1) {
    return odooRpc($odoo['url'], 'object', 'execute_kw', [
        $odoo['db'], $uid, $odoo['pass'], $model, 'search_read',
        [$domain], ['fields'=>$fields, 'limit'=>$limit]
    ]);
}

function odooCreate($odoo, $uid, $model, $vals) {
    return odooRpc($odoo['url'], 'object', 'execute_kw', [
        $odoo['db'], $uid, $odoo['pass'], $model, 'create', [$vals]
    ]);
}

function odooWrite($odoo, $uid, $model, $ids, $vals) {
    return odooRpc($odoo['url'], 'object', 'execute_kw', [
        $odoo['db'], $uid, $odoo['pass'], $model, 'write', [$ids, $vals]
    ]);
}

function odooMessagePost($odoo, $uid, $model, $res_id, $body) {
    return odooRpc($odoo['url'], 'object', 'execute_kw', [
        $odoo['db'], $uid, $odoo['pass'], $model, 'message_post',
        [$res_id], ['body'=>$body, 'message_type'=>'comment', 'subtype_xmlid'=>'mail.mt_note']
    ]);
}

// اجلب/أنشئ utm.source بالاسم
function odooGetOrCreateSourceId($odoo, $uid, $sourceName) {
    $src = odooSearchRead($odoo, $uid, 'utm.source', [['name','=', $sourceName]], ['id','name'], 1);
    if (!empty($src)) return $src[0]['id'];
    return odooCreate($odoo, $uid, 'utm.source', ['name'=>$sourceName]);
}

// ابحث عن Lead موجود (بالهاتف خلال آخر 30 يوم) لتقليل الدوبلكيت
function odooFindRecentLeadByPhone($odoo, $uid, $phone) {
    if (!$phone) return null;
    $thirtyDaysAgo = date('Y-m-d H:i:s', time()-30*86400);
    $leads = odooSearchRead(
        $odoo, $uid, 'crm.lead',
        [['type','=','lead'], ['phone','ilike',$phone], ['create_date','>=',$thirtyDaysAgo]],
        ['id','name','phone','email_from'], 1
    );
    return $leads[0]['id'] ?? null;
}

// الدالة الرئيسية: أنشئ/حدّث Lead وسجّل رسالة
function odooUpsertLeadFromChat($odoo, $params) {
    // $params: ['name','message','phone','email','platform','source_name','extra']
    $uid = odooAuthUid($odoo);
    if (!$uid) throw new Exception('Odoo auth failed');

    $sourceName = $params['source_name'] ?: 'WhatsApp Chatbot';
    $source_id  = odooGetOrCreateSourceId($odoo, $uid, $sourceName);

    // امنع تكرار Leads قريبة
    $leadId = odooFindRecentLeadByPhone($odoo, $uid, $params['phone']);

    $leadVals = [
        'type'        => 'lead',
        'name'        => $params['name'] ?: 'WhatsApp Inquiry',
        'contact_name'=> $params['name'] ?: null,
        'phone'       => $params['phone'] ?: null,
        'email_from'  => $params['email'] ?: null,
        'description' => $params['message'] ?: '',
        'source_id'   => $source_id,                 // utm.source
        'referred'    => strtoupper($params['platform'] ?? 'whatsapp'),
        // اختياري: team_id / user_id لو عايز توزّع Leads
        // 'team_id'  => 1,
        // 'user_id'  => 2,
    ];

    if ($leadId) {
        odooWrite($odoo, $uid, 'crm.lead', [$leadId], $leadVals);
    } else {
        $leadId = odooCreate($odoo, $uid, 'crm.lead', $leadVals);
    }

    // رسائل سجل المحادثة في الـ chatter
    $note  = "<p><b>رسالة جديدة من البوت ("
          . htmlspecialchars($params['platform'] ?? 'whatsapp', ENT_QUOTES, 'UTF-8')
          . ")</b></p>";
    $note .= "<p><b>رقم:</b> ".htmlspecialchars($params['phone'] ?? '', ENT_QUOTES,'UTF-8')."</p>";
    if (!empty($params['extra'])) {
        $meta = htmlspecialchars(json_encode($params['extra'], JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
        $note .= "<p><b>Meta:</b> <code>{$meta}</code></p>";
    }
    $msg = htmlspecialchars($params['message'] ?? '', ENT_QUOTES, 'UTF-8');
    $note .= "<p><b>نص الرسالة:</b><br/>".$msg."</p>";

    odooMessagePost($odoo, $uid, 'crm.lead', $leadId, $note);

    return $leadId;
}


if (mt_rand(1, 100) === 1) cleanupOldFiles();
