<?php
/**
 * Minimal Telegram + DB utilities
 * - PDO connection via .env.php
 * - Telegram API helper
 * - Message template helpers
 * Note: strict_types declared in main file
 */

function env_cfg(): array {
    static $cfg = null;
    if ($cfg === null) {
        $cfg = require __DIR__ . '/../.env.php';
    }
    return $cfg;
}

function pdo(): PDO {
    static $pdo = null;
    if ($pdo === null) {
        $c = env_cfg();
        $dsn = "mysql:host={$c['DB_HOST']};dbname={$c['DB_NAME']};charset=utf8mb4";
        $pdo = new PDO($dsn, $c['DB_USER'], $c['DB_PASS'], [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    }
    return $pdo;
}

function tg_call(string $token, string $method, array $params = []): array {
    $url = "https://api.telegram.org/bot{$token}/{$method}";
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $params,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 30,
    ]);
    $res = curl_exec($ch);
    if ($res === false) {
        return ['ok' => false, 'error' => curl_error($ch)];
    }
    curl_close($ch);
    $json = json_decode($res, true);
    if (!is_array($json)) { $json = ['ok'=>false, 'error'=>'invalid_json', 'raw'=>$res]; }
    return $json;
}

function tg_send(string $token, $chat_id, string $text, array $extra = []): array {
    $params = array_merge(['chat_id' => $chat_id, 'text' => $text, 'disable_web_page_preview' => true], $extra);
    if (!array_key_exists('parse_mode', $params)) {
        $params['parse_mode'] = 'HTML';
    } elseif ($params['parse_mode'] === null) {
        unset($params['parse_mode']);
    }
    $result = tg_call($token, 'sendMessage', $params);
    
    // تسجيل الأخطاء
    if (!($result['ok'] ?? false)) {
        error_log("Telegram API Error: " . json_encode($result));
        error_log("Message length: " . strlen($text));
        error_log("First 200 chars: " . substr($text, 0, 200));
    }
    
    return $result;
}

function tg_get_member(string $token, $chat_id, $user_id): ?array {
    $res = tg_call($token, 'getChatMember', ['chat_id' => $chat_id, 'user_id' => $user_id]);
    if (!empty($res['ok'])) return $res['result'];
    return null;
}

function is_subscribed(string $token, $channel_id, $user_id): bool {
    $m = tg_get_member($token, $channel_id, $user_id);
    if (!$m) return false;
    $status = $m['status'] ?? 'left';
    return in_array($status, ['member', 'creator', 'administrator'], true);
}

// -------- message templates --------
function template_get(string $key): string {
    $db = pdo();
    $stmt = $db->prepare("SELECT text FROM message_templates WHERE `key` = ? LIMIT 1");
    $stmt->execute([$key]);
    $row = $stmt->fetch();
    return $row['text'] ?? '';
}

function template_set(string $key, string $text): void {
    $db = pdo();
    $stmt = $db->prepare("INSERT INTO message_templates(`key`,`text`) VALUES(?,?) ON DUPLICATE KEY UPDATE text=VALUES(text)");
    $stmt->execute([$key, $text]);
}

function interpolate(string $text, array $vars): string {
    foreach ($vars as $k => $v) {
        $text = str_replace('{'.$k.'}', (string)$v, $text);
    }
    return $text;
}

// ============================================
// نظام المدراء الفرعيين
// ============================================

/**
 * التحقق من وجود مدير في النظام
 * @param int $user_id معرف المدير
 * @param string|null $bot_token توكن البوت أو NULL للتحقق من كل البوتات
 * @return array|null بيانات المدير أو null
 */
function get_manager(int $user_id, ?string $bot_token = null): ?array {
    $db = pdo();
    if ($bot_token === null) {
        // مدير عام (لكل البوتات)
        $stmt = $db->prepare("SELECT * FROM bot_managers WHERE user_id=? AND bot_token IS NULL AND is_active=1 LIMIT 1");
        $stmt->execute([$user_id]);
    } else {
        // مدير محدد لبوت معين
        $stmt = $db->prepare("SELECT * FROM bot_managers WHERE user_id=? AND (bot_token=? OR bot_token IS NULL) AND is_active=1 ORDER BY bot_token DESC LIMIT 1");
        $stmt->execute([$user_id, $bot_token]);
    }
    $result = $stmt->fetch();
    return $result ?: null;
}

/**
 * التحقق من صلاحية مدير
 * @param int $user_id معرف المدير
 * @param int $permission_id رقم الصلاحية (1-6)
 * @param string|null $bot_token توكن البوت أو NULL
 * @return bool هل لديه الصلاحية
 */
function has_permission(int $user_id, int $permission_id, ?string $bot_token = null): bool {
    $manager = get_manager($user_id, $bot_token);
    if (!$manager) return false;
    
    $perms = $manager['permissions'] ?? '';
    
    // صلاحيات كاملة
    if (strtolower(trim($perms)) === 'all') {
        return true;
    }
    
    // التحقق من الصلاحية المحددة
    $perm_array = array_map('trim', explode(':', $perms));
    return in_array((string)$permission_id, $perm_array, true);
}

/**
 * إضافة مدير جديد
 * @param int $user_id معرف المدير
 * @param string|null $bot_token توكن البوت أو NULL للكل
 * @param string $permissions الصلاحيات (1:2:3 أو all)
 * @param int $added_by المالك الذي أضافه
 * @param string|null $username اسم المستخدم
 * @return bool
 */
function add_manager(int $user_id, ?string $bot_token, string $permissions, int $added_by, ?string $username = null): bool {
    try {
        $db = pdo();
        $stmt = $db->prepare("INSERT INTO bot_managers(user_id, bot_token, permissions, username, added_by) VALUES(?,?,?,?,?) ON DUPLICATE KEY UPDATE permissions=VALUES(permissions), is_active=1, updated_at=NOW()");
        $stmt->execute([$user_id, $bot_token, $permissions, $username, $added_by]);
        return true;
    } catch (Exception $e) {
        return false;
    }
}

/**
 * إزالة مدير
 * @param int $user_id معرف المدير
 * @param string|null $bot_token توكن البوت أو NULL للكل
 * @return bool
 */
function remove_manager(int $user_id, ?string $bot_token = null): bool {
    try {
        $db = pdo();
        if ($bot_token === null) {
            $stmt = $db->prepare("DELETE FROM bot_managers WHERE user_id=? AND bot_token IS NULL");
            $stmt->execute([$user_id]);
        } else {
            $stmt = $db->prepare("DELETE FROM bot_managers WHERE user_id=? AND bot_token=?");
            $stmt->execute([$user_id, $bot_token]);
        }
        return true;
    } catch (Exception $e) {
        return false;
    }
}

/**
 * تحويل رقم الصلاحية إلى نص عربي
 */
function permission_to_text(int $perm_id): string {
    $map = [
        1 => 'بث',
        2 => 'حظر',
        3 => 'تعبئة قسائم',
        4 => 'عرض المستخدمين',
        5 => 'البحث عن مستخدم',
        6 => 'تعديل حدود المستخدم'
    ];
    return $map[$perm_id] ?? 'غير معروف';
}

// ============================================
// نظام تقسيم الرسائل الطويلة
// ============================================

/**
 * إرسال رسالة مع تقسيم تلقائي إذا تجاوزت الحد
 * @param string $token توكن البوت
 * @param mixed $chat_id معرف الدردشة
 * @param string $text النص المراد إرساله
 * @param array $extra معاملات إضافية
 * @param int $max_length الحد الأقصى لطول الرسالة (افتراضي 3800)
 * @return bool نجح الإرسال أم لا
 */
function tg_send_long(string $token, $chat_id, string $text, array $extra = [], int $max_length = 3800): bool {
    // إذا كان النص قصيراً، أرسله مباشرة
    if (mb_strlen($text) <= $max_length) {
        $result = tg_send($token, $chat_id, $text, $extra);
        return $result['ok'] ?? false;
    }
    
    // تقسيم النص إلى أجزاء
    $parts = split_long_message($text, $max_length);
    
    $success = true;
    foreach ($parts as $i => $part) {
        // إضافة رقم الصفحة إذا كان هناك أكثر من جزء
        if (count($parts) > 1) {
            $page_info = "📄 صفحة " . ($i + 1) . " من " . count($parts) . "\n\n";
            $part = $page_info . $part;
        }
        
        $result = tg_send($token, $chat_id, $part, $extra);
        if (!($result['ok'] ?? false)) {
            $success = false;
        }
        
        // تأخير بين الرسائل لتجنب Rate Limiting
        if ($i < count($parts) - 1) {
            usleep(300000); // 300ms
        }
    }
    
    return $success;
}

/**
 * تقسيم رسالة طويلة إلى أجزاء
 * @param string $text النص المراد تقسيمه
 * @param int $max_length الحد الأقصى لطول كل جزء
 * @return array مصفوفة من الأجزاء
 */
function split_long_message(string $text, int $max_length = 3800): array {
    $parts = [];
    $lines = explode("\n", $text);
    $current_part = '';
    
    foreach ($lines as $line) {
        // إذا كان السطر وحده أطول من الحد، قسّمه
        if (mb_strlen($line) > $max_length) {
            // حفظ الجزء الحالي إذا كان غير فارغ
            if (!empty($current_part)) {
                $parts[] = trim($current_part);
                $current_part = '';
            }
            
            // تقسيم السطر الطويل
            $chunks = mb_str_split($line, $max_length);
            foreach ($chunks as $chunk) {
                $parts[] = $chunk;
            }
            continue;
        }
        
        // إضافة السطر للجزء الحالي
        $test = $current_part . "\n" . $line;
        
        if (mb_strlen($test) > $max_length) {
            // الجزء الحالي امتلأ، احفظه وابدأ جزءاً جديداً
            $parts[] = trim($current_part);
            $current_part = $line;
        } else {
            $current_part = empty($current_part) ? $line : $test;
        }
    }
    
    // إضافة الجزء الأخير
    if (!empty($current_part)) {
        $parts[] = trim($current_part);
    }
    
    return empty($parts) ? [$text] : $parts;
}
