<?php
/**
 * الدوال الأساسية - بوابة واتساب
 * تتعامل مع: التخزين، API واتساب (wifi2fm.com)، التحقق من الأرقام
 */

// ============================================================
// دوال التخزين
// ============================================================

function ensureStorageDirs(): void {
    $dirs = [STORAGE_PATH, STORAGE_PATH . 'chats/', LOG_PATH];
    foreach ($dirs as $dir) {
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
    }
}

function getChatFile(string $phone): string {
    ensureStorageDirs();
    $safe = preg_replace('/[^0-9]/', '', $phone);
    return STORAGE_PATH . 'chats/' . $safe . '.json';
}

function loadMessages(string $phone): array {
    $file = getChatFile($phone);
    if (!file_exists($file)) {
        return [];
    }
    $data = json_decode(file_get_contents($file), true);
    return is_array($data) ? $data : [];
}

function saveMessage(string $phone, array $message): bool {
    $file = getChatFile($phone);
    $messages = loadMessages($phone);
    $messages[] = $message;
    return file_put_contents($file, json_encode($messages, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX) !== false;
}

function getNewMessages(string $phone, int $afterTimestamp): array {
    $messages = loadMessages($phone);
    return array_values(array_filter($messages, function($msg) use ($afterTimestamp) {
        return $msg['timestamp'] > $afterTimestamp;
    }));
}

function createMessage(string $direction, string $body, string $phone, string $type = 'text'): array {
    return [
        'id'        => uniqid('msg_', true),
        'direction' => $direction,  // 'outgoing' (مستخدم→بوت) أو 'incoming' (بوت→مستخدم)
        'body'      => $body,
        'phone'     => $phone,
        'type'      => $type,
        'timestamp' => time(),
        'status'    => 'delivered',
    ];
}


// ============================================================
// دوال WhatsApp API (wifi2fm.com / WA Client)
// ============================================================

/**
 * استدعاء API عام
 * يرسل طلب POST إلى wifi2fm.com مع instance_id و access_token
 */
function waApiCall(string $endpoint, array $params = []): array|false {
    // إضافة بيانات المصادقة دائماً
    $params['instance_id']  = WA_INSTANCE_ID;
    $params['access_token'] = WA_ACCESS_TOKEN;

    // wifi2fm.com API يتطلب المعاملات في URL query string أيضاً
    $queryString = http_build_query($params);
    $url = WA_API_BASE_URL . $endpoint . '?' . $queryString;

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($params),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Accept: application/json',
        ],
        CURLOPT_SSL_VERIFYPEER => true,
    ]);

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

    if ($error) {
        logEvent('api_curl_error', ['endpoint' => $endpoint, 'error' => $error]);
        return false;
    }

    $data = json_decode($response, true);
    
    if (!$data) {
        logEvent('api_invalid_response', [
            'endpoint' => $endpoint, 'http_code' => $httpCode,
            'response' => substr($response, 0, 500)
        ]);
        return false;
    }

    logEvent('api_call', [
        'endpoint' => $endpoint, 'http_code' => $httpCode,
        'status' => $data['status'] ?? 'unknown'
    ]);

    return $data;
}

/**
 * التحقق من صحة رقم واتساب
 * 
 * يحاول عدة endpoints للتحقق:
 * 1. /api/check_number (WA Client standard)
 * 2. /api/checkPhone
 * 3. /api/check-number
 * 
 * إذا لم يعمل أي منها (route not found) → يتخطى التحقق ويسمح بالدخول
 * (الرسالة ستفشل لاحقاً إذا كان الرقم غير صالح)
 */
function checkWhatsAppNumber(string $phone): array {
    // قائمة الـ endpoints المحتملة للتحقق من الرقم
    $endpoints = [
        WA_ENDPOINT_CHECK_NUMBER,       // /api/check_number
        '/api/checkPhone',              // بديل محتمل
        '/api/check-number',            // بديل محتمل
    ];

    foreach ($endpoints as $endpoint) {
        $result = waApiCall($endpoint, [
            'number' => $phone,
        ]);

        if ($result === false) {
            continue; // خطأ في الاتصال، جرب البديل
        }

        // إذا كان الرد "route not found" أو خطأ مشابه → جرب البديل
        $message = strtolower($result['message'] ?? '');
        if (
            strpos($message, 'route not found') !== false ||
            strpos($message, 'not found') !== false ||
            strpos($message, '404') !== false ||
            strpos($message, 'invalid endpoint') !== false
        ) {
            logEvent('check_number_endpoint_not_found', ['endpoint' => $endpoint]);
            continue;
        }

        // وصلنا لـ endpoint يعمل
        if (($result['status'] ?? '') === 'success') {
            $isValid = $result['data']['valid'] ?? true; // افتراض صالح إذا ما فيه data.valid
            return [
                'valid'   => (bool) $isValid,
                'error'   => $isValid ? null : 'هذا الرقم غير مسجل في واتساب.',
                'details' => $result['data'] ?? null,
            ];
        }

        // خطأ من API (مثل رقم غير صالح)
        if (($result['status'] ?? '') === 'error') {
            // إذا كان الخطأ متعلق بالرقم وليس بالـ endpoint
            if (
                strpos($message, 'route') === false &&
                strpos($message, 'not found') === false
            ) {
                return [
                    'valid'   => false,
                    'error'   => $result['message'] ?? 'خطأ في التحقق من الرقم.',
                    'details' => $result,
                ];
            }
            continue;
        }
    }

    // لم يعمل أي endpoint → نتخطى التحقق ونسمح بالدخول
    // (البوت لن يرد إذا كان الرقم غير صالح فعلاً)
    logEvent('check_number_skipped', [
        'phone' => $phone,
        'reason' => 'no_working_endpoint',
    ]);

    return [
        'valid'   => true,
        'error'   => null,
        'details' => ['note' => 'verification_skipped'],
    ];
}

/**
 * إرسال رسالة نصية عبر واتساب
 * يستدعي /api/send
 * 
 * الاستجابة المتوقعة:
 * {"status":"success","message":{"key":{"remoteJid":"...","fromMe":true,"id":"..."},...}}
 */
function sendWhatsAppMessage(string $to, string $body): array|false {
    $result = waApiCall(WA_ENDPOINT_SEND, [
        'number'  => $to,
        'type'    => 'text',
        'message' => $body,
    ]);

    if ($result === false) {
        logEvent('send_failed', ['to' => $to, 'reason' => 'curl_error']);
        return false;
    }

    if (($result['status'] ?? '') === 'success') {
        logEvent('send_success', ['to' => $to]);
        return $result;
    }

    logEvent('send_failed', [
        'to' => $to,
        'api_status' => $result['status'] ?? 'unknown',
        'api_message' => $result['message'] ?? '',
    ]);
    return false;
}


// ============================================================
// حد الرسائل (Rate Limiting)
// ============================================================

function isRateLimited(string $phone): bool {
    $key  = 'rate_' . preg_replace('/[^0-9]/', '', $phone);
    $file = STORAGE_PATH . $key . '.json';

    if (!file_exists($file)) return false;

    $data = json_decode(file_get_contents($file), true);
    if (!$data) return false;

    $cutoff = time() - RATE_LIMIT_WINDOW;
    $data['timestamps'] = array_values(array_filter($data['timestamps'] ?? [], fn($t) => $t > $cutoff));
    file_put_contents($file, json_encode($data), LOCK_EX);

    return count($data['timestamps']) >= RATE_LIMIT_MESSAGES;
}

function recordRateLimit(string $phone): void {
    $key  = 'rate_' . preg_replace('/[^0-9]/', '', $phone);
    $file = STORAGE_PATH . $key . '.json';

    $data = file_exists($file) ? (json_decode(file_get_contents($file), true) ?? []) : [];
    $data['timestamps'][] = time();
    file_put_contents($file, json_encode($data), LOCK_EX);
}


// ============================================================
// التحقق والأمان
// ============================================================

function isValidPhone(string $phone): bool {
    $clean = preg_replace('/[^0-9]/', '', $phone);
    return strlen($clean) >= 10 && strlen($clean) <= 15;
}

function sanitizeMessage(string $body): string {
    $body = trim($body);
    $body = mb_substr($body, 0, MAX_MESSAGE_LENGTH);
    $body = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F]/', '', $body);
    return $body;
}


// ============================================================
// Webhook Proxy - تمرير الرسائل للبوت الأصلي
// ============================================================

/**
 * تمرير بيانات الـ webhook للرابط الأصلي (البوت على الهواتف)
 * يرسل نفس البيانات بالضبط كما وصلت، مع نفس الـ headers
 * يعمل بشكل غير متزامن (لا ينتظر الرد) لتسريع الاستجابة
 */
function forwardToOriginalWebhook(string $rawBody): void {
    $url = defined('WA_ORIGINAL_WEBHOOK_URL') ? WA_ORIGINAL_WEBHOOK_URL : '';
    
    if (empty($url)) {
        logEvent('proxy_skip', ['reason' => 'no_original_webhook_url']);
        return;
    }

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $rawBody,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Accept: application/json',
            'X-Forwarded-By: whatsapp-walled-garden',
        ],
        CURLOPT_SSL_VERIFYPEER => true,
    ]);

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

    if ($error) {
        logEvent('proxy_forward_error', [
            'url'   => $url,
            'error' => $error,
        ]);
    } else {
        logEvent('proxy_forward_success', [
            'url'       => $url,
            'http_code' => $httpCode,
            'response'  => substr($response, 0, 200),
        ]);
    }
}


// ============================================================
// السجلات
// ============================================================

function logEvent(string $event, array $data = []): void {
    if (!LOG_ENABLED) return;
    ensureStorageDirs();
    
    $entry = [
        'time'  => date('Y-m-d H:i:s'),
        'event' => $event,
        'data'  => $data,
        'ip'    => $_SERVER['REMOTE_ADDR'] ?? 'cli',
    ];

    $logFile = LOG_PATH . date('Y-m-d') . '.log';
    file_put_contents($logFile, json_encode($entry, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND | LOCK_EX);
}


// ============================================================
// استجابة JSON
// ============================================================

function jsonResponse(array $data, int $code = 200): never {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-cache, no-store, must-revalidate');
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}
