<?php
// functions.php
require_once 'config.php';

function bot($method, $datas = []) {
    $url = "https://api.telegram.org/bot" . API_KEY . "/" . $method;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $datas);
    $res = curl_exec($ch);
    if (curl_error($ch)) {
        var_dump(curl_error($ch));
    } else {
        return json_decode($res);
    }
}

function saveFile($file_id, $subfolder = '') {
    $file_info = bot('getFile', ['file_id' => $file_id]);
    if(isset($file_info->result->file_path)){
        $src = "https://api.telegram.org/file/bot" . API_KEY . "/" . $file_info->result->file_path;
        $extension = pathinfo($file_info->result->file_path, PATHINFO_EXTENSION);
        $filename = uniqid() . '.' . $extension;
        
        $path = UPLOAD_DIR . $subfolder;
        if (!is_dir($path)) mkdir($path, 0777, true);
        
        $dest = $path . '/' . $filename;
        file_put_contents($dest, file_get_contents($src));
        return $subfolder . '/' . $filename; // مسیر نسبی برای ذخیره در دیتابیس
    }
    return false;
}


// تابع دقیق تبدیل شمسی به میلادی
// --- تابع دقیق تبدیل شمسی به میلادی ---
function jalali_to_gregorian($jy, $jm, $jd, $mod = '') {
    $jy = (int)$jy; $jm = (int)$jm; $jd = (int)$jd;
    $jy += 1595;
    $days = -355668 + (365 * $jy) + ((int)($jy / 33) * 8) + ((int)((($jy % 33) + 3) / 4)) + $jd + (($jm < 7) ? ($jm - 1) * 31 : (($jm - 7) * 30) + 186);
    $gy = 400 * ((int)($days / 146097));
    $days %= 146097;
    if ($days > 36524) {
        $gy += 100 * ((int)(--$days / 36524));
        $days %= 36524;
        if ($days >= 365) $days++;
    }
    $gy += 4 * ((int)($days / 1461));
    $days %= 1461;
    if ($days > 365) {
        $gy += (int)(($days - 1) / 365);
        $days = ($days - 1) % 365;
    }
    $gd = $days + 1;
    $gm_days = [0, 31, (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    $gm = 0;
    while ($gm < 13 && $gd > $gm_days[$gm]) {
        $gd -= $gm_days[$gm];
        $gm++;
        $gm_days[2] = (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)) ? 29 : 28;
    }
    return ($mod == '') ? [$gy, $gm, $gd] : $gy . $mod . $gm . $mod . $gd;
}


// اگر می‌خواهید مطمئن‌ترین روش را داشته باشید، از این تابع جایگزین استفاده کنید که ورودی آرایه می‌دهد:
function shamsi_to_miladi($jy, $jm, $jd) {
    $jy += 1595;
    $days = -355668 + (365 * $jy) + ((int)($jy / 33) * 8) + ((int)((($jy % 33) + 3) / 4)) + $jd + (($jm < 7) ? ($jm - 1) * 31 : (($jm - 7) * 30) + 186);
    $gy = 400 * ((int)($days / 146097));
    $days %= 146097;
    if ($days > 36524) {
        $gy += 100 * ((int)(--$days / 36524));
        $days %= 36524;
        if ($days >= 365) $days++;
    }
    $gy += 4 * ((int)($days / 1461));
    $days %= 1461;
    if ($days > 365) {
        $gy += (int)(($days - 1) / 365);
        $days = ($days - 1) % 365;
    }
    $gd = $days + 1;
    $gm = 0;
    $gm_days = [0, 31, (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    
    while ($gd > $gm_days[$gm + 1]) {
        $gm++;
        $gd -= $gm_days[$gm];
    }
    return [$gy, $gm + 1, $gd];
}


// تابع کمکی برای کیبورد اصلی (ویرایش شده برای کنترل دکمه تیکت)
function mainMenu($user_id) {
    // بررسی وضعیت فعال بودن ارسال تیکت از تنظیمات
    $ticket_active = getSetting('ticket_submission_active');
    
    // ردیف دکمه‌های پشتیبانی
    $support_row = [];
    if ($ticket_active == 'on') {
        $support_row[] = ['text' => '📩 ارسال تیکت'];
    }
    $support_row[] = ['text' => '📞 ارتباط با پشتیبانی'];
// بررسی ادمین بودن (هم کانفیگ و هم دیتابیس)
    if (isAdmin($user_id)) {
      return json_encode([
            'keyboard' => [
                [['text' => '🛍 فروشگاه'], ['text' => '👤 حساب کاربری']],
                [['text' => '📂 محصولات من'], ['text' => '🧾 تراکنش‌های من']],
                $support_row, // این خط دینامیک شد
                [['text' => '🔍 جستجوی محصول'], ['text' => '⚙️ مدیریت ربات']] 
            ],
            'resize_keyboard' => true
        ]);
    } else {
        return json_encode([
            'keyboard' => [
                [['text' => '🛍 فروشگاه'], ['text' => '👤 حساب کاربری']],
                [['text' => '📂 محصولات من'], ['text' => '🧾 تراکنش‌های من']],
                $support_row, // این خط دینامیک شد
                [['text' => '🔍 جستجوی محصول']]
            ],
            'resize_keyboard' => true
        ]);
    }
}




function adminMenu() {
    return json_encode([
        'keyboard' => [
            [['text' => '➕ افزودن محصول'], ['text' => '📦 لیست محصولات']],
            [['text' => '📂 دسته‌بندی‌ها'], ['text' => '📊 آمار فروشگاه']],
            [['text' => '⚙️ تنظیمات فروشگاه'], ['text' => '📢 ارسال پیام همگانی']], 
            [['text' => '🔙 بازگشت به منوی اصلی']]
        ],
        'resize_keyboard' => true
    ]);
}


// دریافت تنظیمات
function getSetting($key) {
    global $db;
    $stmt = $db->pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = ?");
    $stmt->execute([$key]);
    return $stmt->fetchColumn();
}

// ذخیره تنظیمات
// ذخیره تنظیمات (اصلاح شده برای رفع ارور Duplicate entry)
function setSetting($key, $value) {
    global $db;
    // ابتدا بررسی می‌کنیم که آیا این تنظیم وجود دارد یا خیر
    $stmt = $db->pdo->prepare("SELECT setting_key FROM settings WHERE setting_key = ?");
    $stmt->execute([$key]);
    
    if ($stmt->rowCount() > 0) {
        // اگر وجود داشت، فقط آپدیت می‌کنیم
        $update = $db->pdo->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = ?");
        $update->execute([$value, $key]);
    } else {
        // اگر وجود نداشت، اینسرت می‌کنیم
        $insert = $db->pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?)");
        $insert->execute([$key, $value]);
    }
}

// منوی تنظیمات فروشگاه (ویرایش شده: افزودن مدیریت ادمین‌ها برای مدیر اصلی)
function storeSettingsMenu($user_id = null) {
    // --- اصلاح: دریافت خودکار آیدی اگر پاس داده نشده باشد ---
    if ($user_id === null) {
        global $chat_id;
        $user_id = $chat_id;
    }
    // -------------------------------------------------------

    $keyboard = [

        [
            ['text' => '💳 روش‌های پرداخت'],
            ['text' => '📱 تایید شماره موبایل']
        ],
        [
            ['text' => '🎁 مدیریت تخفیف‌ها'],
            ['text' => '🔒 عضویت اجباری']
        ],
        [['text' => '🔎 جستجوی کاربر'], ['text' => '🎫 مدیریت ارسال تیکت']]
    ];

    // اگر یوزر آیدی پاس داده شد و مدیر اصلی بود، دکمه مدیریت ادمین‌ها اضافه شود
    if ($user_id && isConfigAdmin($user_id)) {
        $keyboard[] = [['text' => '👤 مدیریت ادمین‌ها']];
    }

    $keyboard[] = [['text' => '🔙 بازگشت به منوی اصلی']];

    return json_encode([
        'keyboard' => $keyboard,
        'resize_keyboard' => true
    ]);
}


// منوی تایید شماره موبایل (اصلاح شده: تبدیل به دکمه شیشه‌ای برای عملکرد صحیح)
function phoneVerificationMenu() {
    // 1. دریافت وضعیت اجبار
    $status = getSetting('force_phone_share');
    $st_text = ($status == 'on') ? "وضعیت اجبار: ✅ فعال" : "وضعیت اجبار: ❌ غیرفعال";

    // 2. دریافت وضعیت محدودیت کشور
    $mode = getSetting('phone_restriction_mode');
    
    // تعیین تیک برای دکمه انتخاب شده
    $tick_ir = ($mode == 'ir') ? '✅ ' : ''; 
    $tick_all = ($mode == 'all' || empty($mode)) ? '✅ ' : ''; // اگر خالی بود پیش‌فرض همه کشورهاست

    return json_encode([
        'inline_keyboard' => [
            // ردیف اول: دکمه روشن/خاموش کردن اجبار
            [
                ['text' => $st_text, 'callback_data' => 'toggle_phone_req']
            ],
            // ردیف دوم: تیتر انتخاب کشور (تزیینی)
            [
                ['text' => "👇 محدوده شماره‌های مجاز 👇", 'callback_data' => 'ignore']
            ],
            // ردیف سوم: دکمه‌های انتخاب کشور
            [
                ['text' => $tick_ir . "فقط ایران 🇮🇷", 'callback_data' => 'set_phone_mode_ir'],
                ['text' => $tick_all . "همه کشورها 🌍", 'callback_data' => 'set_phone_mode_all']
            ]
        ]
    ]);
}


// منوی روش‌های پرداخت
function paymentMethodsMenu() {
    $c2c_status = getSetting('card_to_card_active') == 'on' ? '✅' : '❌';
    $stars_status = getSetting('stars_payment_active') == 'on' ? '✅' : '❌';
    $online_status = getSetting('online_payment_active') == 'off' ? '❌' : '✅'; // پیشفرض فعال

    return json_encode([
        'keyboard' => [
            [['text' => '🌐 پرداخت آنلاین'], ['text' => "وضعیت: $online_status"]],
            [['text' => '💳 کارت به کارت'], ['text' => "وضعیت: $c2c_status"]],
            [['text' => '⭐️ خرید با استارز'], ['text' => "وضعیت: $stars_status"]],
            [['text' => '🔙 بازگشت به تنظیمات فروشگاه']]
        ],
        'resize_keyboard' => true
    ]);
}

// منوی تنظیمات پرداخت آنلاین
function onlinePaymentSettingsMenu() {
    $status = getSetting('online_payment_active') == 'off' ? '❌ غیرفعال' : '✅ فعال';
    return json_encode([
        'keyboard' => [
            [['text' => '🔑 مدیریت کد مرچنت'], ['text' => "وضعیت پرداخت آنلاین: $status"]],
            [['text' => '🔙 بازگشت به روش‌های پرداخت']]
        ],
        'resize_keyboard' => true
    ]);
}

// منوی مدیریت کد مرچنت
function merchantManageMenu() {
    $current_merchant = getSetting('zarinpal_merchant');
    $display = empty($current_merchant) ? "پیش‌فرض (Config)" : "اختصاصی (تنظیم شده)";
    
    return json_encode([
        'keyboard' => [
            [['text' => '📝 ثبت مرچنت جدید'], ['text' => "فعلی: $display"]],
            [['text' => '🗑 حذف مرچنت اختصاصی']],
            [['text' => '🔙 بازگشت به تنظیمات پرداخت آنلاین']]
        ],
        'resize_keyboard' => true
    ]);
}



// منوی مدیریت کارت به کارت
// منوی مدیریت کارت به کارت
function cardToCardMenu() {
    $status = getSetting('card_to_card_active') == 'on' ? '✅ فعال' : '❌ غیرفعال';
    return json_encode([
        'keyboard' => [
            [['text' => '📝 ثبت کارت جدید'], ['text' => "وضعیت کارت به کارت: $status"]],
            [['text' => '✏️ ویرایش کارت'], ['text' => '🗑 حذف کارت']],
            [['text' => '🔙 بازگشت به روش‌های پرداخت']]
        ],
        'resize_keyboard' => true
    ]);
}

// تابع تبدیل میلادی به شمسی (اصلاح شده و دقیق)
function gregorian_to_jalali($gy, $gm, $gd, $mod = '') {
    $gy = (int)$gy; $gm = (int)$gm; $gd = (int)$gd;
    $g_d_m = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)) $g_d_m[2] = 29;
    $jy = ($gy <= 1600) ? 0 : 979;
    $gy -= ($gy <= 1600) ? 621 : 1600;
    $gy2 = ($gm > 2) ? ($gy + 1) : $gy;
    $days = (365 * $gy) + ((int)(($gy2 + 3) / 4)) - ((int)(($gy2 + 99) / 100)) + ((int)(($gy2 + 399) / 400)) - 80 + $gd;
    for ($i = 0; $i < ($gm - 1); $i++) {
        $days += $g_d_m[$i + 1];
    }
    $jy += 33 * ((int)($days / 12053));
    $days %= 12053;
    $jy += 4 * ((int)($days / 1461));
    $days %= 1461;
    $jy += (int)(($days - 1) / 365);
    if ($days > 365) $days = ($days - 1) % 365;
    if ($days < 186) {
        $jm = 1 + (int)($days / 31);
        $jd = 1 + ($days % 31);
    } else {
        $jm = 7 + (int)(($days - 186) / 30);
        $jd = 1 + (($days - 186) % 30);
    }
    return ($mod == '') ? [$jy, $jm, $jd] : $jy . $mod . $jm . $mod . $jd;
}

// منوی مدیریت تخفیف‌ها
// منوی مدیریت تخفیف‌ها
function discountManagementMenu() {
    return json_encode([
        'keyboard' => [
            [['text' => '🌐 تخفیف سراسری'], ['text' => '🎟 مدیریت کدهای تخفیف']],
            [['text' => '🔙 بازگشت به تنظیمات فروشگاه']]
        ],
        'resize_keyboard' => true
    ]);
}

// منوی تنظیمات تخفیف سراسری
function globalDiscountMenu() {
    $status = getSetting('global_discount_active') == 'on' ? '✅ فعال' : '❌ غیرفعال';
    $val = getSetting('global_discount_value');
    $type = getSetting('global_discount_type') == 'percent' ? '%' : 'تومان';
    
    // نمایش مقدار فعلی
    $display_val = ($type == '%') ? "$val درصد" : number_format($val) . " تومان";
    
    // نمایش تاریخ انقضا شمسی
    $expiry = getSetting('global_discount_expiry');
    $jalali_exp = "تعیین نشده";
    if($expiry) {
        $ex_parts = explode('-', $expiry);
        if(count($ex_parts) == 3) {
            $j_date = gregorian_to_jalali($ex_parts[0], $ex_parts[1], $ex_parts[2]);
            $jalali_exp = implode('/', $j_date);
        }
    }

    return json_encode([
        'keyboard' => [
            [['text' => "وضعیت: $status"]], // دکمه تغییر وضعیت
            [['text' => '💲 تعیین مقدار تخفیف'], ['text' => "مقدار فعلی: $display_val"]],
            [['text' => '📅 تعیین تاریخ انقضا'], ['text' => "انقضا: $jalali_exp"]],
            [['text' => '🔙 بازگشت به مدیریت تخفیف‌ها']]
        ],
        'resize_keyboard' => true
    ]);
}

// --- تابع بررسی دقیق انقضای تخفیف (روش تایم‌استمپ) ---
function checkAndDisableExpiredDiscount() {
    // تنظیم منطقه زمانی ایران
    date_default_timezone_set('Asia/Tehran');

    $active = getSetting('global_discount_active');
    $expiry = getSetting('global_discount_expiry'); // فرمت در دیتابیس: YYYY-MM-DD

    // فقط اگر تخفیف روشن است و تاریخ انقضا دارد بررسی کن
    if ($active == 'on' && !empty($expiry)) {
        
        $today_timestamp = strtotime(date("Y-m-d")); // تبدیل امروز به عدد ثانیه
        $expiry_timestamp = strtotime($expiry);      // تبدیل تاریخ انقضا به عدد ثانیه
        
        // اگر امروز بزرگتر از تاریخ انقضا باشد (یعنی فردا صبحِ روز انقضا)
        if ($today_timestamp > $expiry_timestamp) {
            setSetting('global_discount_active', 'off'); // غیرفعال کردن در دیتابیس
            return true;
        }
    }
    return false;
}

// منوی اصلی انتخاب نوع کد تخفیف
function couponTypeMenu() {
    return json_encode([
        'keyboard' => [
            [['text' => '💰 تخفیف در قیمت اصلی'], ['text' => '⭐️ تخفیف در قیمت استارز']],
            [['text' => '🔙 بازگشت به مدیریت تخفیف‌ها']]
        ],
        'resize_keyboard' => true
    ]);
}

// منوی مدیریت کدهای تخفیف تومانی
function couponTomanMenu() {
    return json_encode([
        'keyboard' => [
            [['text' => '➕ ایجاد کد تخفیف (تومان)'], ['text' => '📋 لیست کدهای تخفیف (تومان)']],
            [['text' => '🔙 بازگشت به انتخاب نوع کد']]
        ],
        'resize_keyboard' => true
    ]);
}

// منوی مدیریت کدهای تخفیف استارز
function couponStarsMenu() {
    return json_encode([
        'keyboard' => [
            [['text' => '➕ ایجاد کد تخفیف (استارز)'], ['text' => '📋 لیست کدهای تخفیف (استارز)']],
            [['text' => '🔙 بازگشت به انتخاب نوع کد']]
        ],
        'resize_keyboard' => true
    ]);
}

// --- توابع مربوط به ارسال پیام همگانی (اضافه شده جدید) ---

// دریافت لیست آیدی تمام کاربران
function getAllUsersID() {
    global $db;
    // فقط آیدی‌ها را می‌گیریم تا حافظه کمتری اشغال شود
    $stmt = $db->pdo->query("SELECT id FROM users");
    return $stmt->fetchAll(PDO::FETCH_COLUMN);
}

// ثبت شروع عملیات ارسال همگانی در دیتابیس
function startBroadcastLog($admin_id, $type, $total_receivers) {
    global $db;
    $stmt = $db->pdo->prepare("INSERT INTO broadcast_history (admin_id, message_type, total_receivers, start_time) VALUES (?, ?, ?, NOW())");
    $stmt->execute([$admin_id, $type, $total_receivers]);
    return $db->pdo->lastInsertId(); // شناسه این عملیات را برمی‌گرداند
}

// بروزرسانی آمار پس از پایان ارسال
function endBroadcastLog($history_id, $success, $failed) {
    global $db;
    $stmt = $db->pdo->prepare("UPDATE broadcast_history SET success_count = ?, failed_count = ?, end_time = NOW() WHERE id = ?");
    $stmt->execute([$success, $failed, $history_id]);
}


// --- توابع مدیریت زمان و امنیت ارسال همگانی (جدید) ---

/**
 * محاسبه زمان تأخیر هوشمند برای جلوگیری از مسدودیت
 * @param int $total_users تعداد کل کاربران
 * @return int زمان توقف به میکروثانیه (برای تابع usleep)
 */
function getSafeBroadcastDelay($total_users) {
    // اگر تعداد کاربران کم است (زیر 1000)، سرعت متوسط (0.1 ثانیه)
    if ($total_users < 1000) {
        return 100000; // 0.1 ثانیه
    } 
    // اگر تعداد کاربران متوسط است (بین 1000 تا 5000)، سرعت مطمئن (0.2 ثانیه)
    elseif ($total_users < 5000) {
        return 200000; // 0.2 ثانیه
    } 
    // برای تعداد بالا، سرعت آهسته و امن (0.5 ثانیه)
    else {
        return 500000; // 0.5 ثانیه
    }
}

/**
 * تخمین زمان لازم برای ارسال پیام
 * @param int $total_users تعداد کاربران
 * @return string متن فارسی زمان تقریبی
 */
function estimateBroadcastTime($total_users) {
    $delay_micro = getSafeBroadcastDelay($total_users);
    $delay_sec = $delay_micro / 1000000;
    
    // محاسبه کل ثانیه‌ها
    $total_seconds = $total_users * $delay_sec;
    
    if ($total_seconds < 60) {
        return ceil($total_seconds) . " ثانیه";
    } elseif ($total_seconds < 3600) {
        return ceil($total_seconds / 60) . " دقیقه";
    } else {
        $hours = floor($total_seconds / 3600);
        $minutes = ceil(($total_seconds % 3600) / 60);
        return "$hours ساعت و $minutes دقیقه";
    }
}


// --- منوی مدیریت عضویت اجباری ---
function forceJoinMenu() {
    $status = getSetting('force_join_active') == 'on' ? '✅ فعال' : '❌ غیرفعال';
    return json_encode([
        'keyboard' => [
            [['text' => '➕ افزودن کانال/گروه'], ['text' => '📋 مشاهده لیست']],
            [['text' => "وضعیت قفل: $status"]],
            [['text' => '🔙 بازگشت به تنظیمات فروشگاه']]
        ],
        'resize_keyboard' => true
    ]);
}

// --- منوی مدیریت ارسال تیکت (جدید) ---
function ticketSettingsMenu() {
    $status = getSetting('ticket_submission_active') == 'on' ? '✅ فعال' : '❌ غیرفعال';
    return json_encode([
        'keyboard' => [
            [['text' => "وضعیت ارسال تیکت: $status"]], // دکمه تغییر وضعیت
            [['text' => '⏳ تمدید تیکت']], // دکمه تمدید دستی
            [['text' => '🔙 بازگشت به تنظیمات فروشگاه']]
        ],
        'resize_keyboard' => true
    ]);
}


// --- تابع تمدید دستی پشتیبانی (اصلاح شده طبق دستور جدید) ---
function extendOrderSupport($order_id, $days_to_add) {
    global $db;
    date_default_timezone_set('Asia/Tehran');
    
    // 1. دریافت اطلاعات سفارش + تایتل محصول + آیدی کاربر
    // (تغییر مهم: اضافه شدن JOIN برای گرفتن user_id و title که برای رفع خطای پنل ادمین ضروری است)
    $stmt = $db->pdo->prepare("
        SELECT o.created_at, o.support_expiry, o.product_id, o.user_id, p.title, p.support_days 
        FROM orders o 
        JOIN products p ON o.product_id = p.id 
        WHERE o.id = ?
    ");
    $stmt->execute([$order_id]);
    $order = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$order) return false;

    // 2. محاسبه تاریخ انقضای فعلی (همان منطق خودتان)
    if (!empty($order['support_expiry'])) {
        $current_expiry = new DateTime($order['support_expiry']);
    } else {
        $default_days = (int)$order['support_days'];
        $current_expiry = new DateTime($order['created_at']);
        if ($default_days > 0) {
            $current_expiry->modify("+$default_days days");
        }
    }

    // 3. بررسی وضعیت انقضا نسبت به امروز (همان منطق خودتان)
    $today = new DateTime();
    $today->setTime(0, 0, 0);
    $current_expiry->setTime(0, 0, 0);

    if ($today > $current_expiry) {
        // چون منقضی شده، مبنای تمدید می‌شود "همین امروز"
        $new_base_date = new DateTime(); 
    } else {
        // چون هنوز وقت دارد، مبنا می‌شود "همان تاریخ انقضای قبلی"
        $new_base_date = clone $current_expiry;
    }

    // 4. افزودن روزهای جدید به مبنای محاسبه شده
    $new_base_date->modify("+$days_to_add days");
    $new_expiry_str = $new_base_date->format('Y-m-d');

    // 5. آپدیت دیتابیس
    $up = $db->pdo->prepare("UPDATE orders SET support_expiry = ? WHERE id = ?");
    $up->execute([$new_expiry_str, $order_id]);
    
    // ==========================================
    // بخش تغییر یافته برای رفع خطای پنل ادمین:
    // ==========================================
    
    // الف) تبدیل تاریخ میلادی جدید به شمسی برای نمایش در پیام‌ها
    $ex_parts = explode('-', $new_expiry_str);
    $j_date = gregorian_to_jalali($ex_parts[0], $ex_parts[1], $ex_parts[2]);
    $j_date_str = implode('/', $j_date);

    // ب) بازگرداندن آرایه کامل به جای true
    // پنل ادمین از این کلیدها استفاده می‌کند: new_expiry, user_id, product_title
    return [
        'new_expiry'    => $j_date_str,      
        'user_id'       => $order['user_id'], 
        'product_title' => $order['title']    
    ];
}




// --- تابع بررسی عضویت کاربر در یک کانال/گروه خاص ---
function isMember($user_id, $chat_id) {
    $res = bot('getChatMember', [
        'chat_id' => $chat_id,
        'user_id' => $user_id
    ]);
    
    if (isset($res->ok) && $res->ok) {
        $status = $res->result->status;
        // وضعیت‌های مجاز: سازنده، ادمین، عضو
        if (in_array($status, ['creator', 'administrator', 'member'])) {
            return true;
        }
        // برای گروه‌ها گاهی وضعیت restricted است اما عضو هستند (باید بررسی دقیق‌تر شود ولی فعلا این‌ها کافیست)
    }
    return false;
}

// --- دریافت لیست کانال‌های قفل ---
function getForceJoinChannels() {
    global $db;
    $stmt = $db->pdo->query("SELECT * FROM force_join_channels");
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// ==========================================
//        توابع مدیریت کاربران (اصلاح شده)
// ==========================================


// 1. جستجوی کاربر (بهینه شده برای کاراکترهای خاص)
function searchUser($input) {
    global $db;
    $input = trim($input); 
    $clean_input = str_replace('@', '', $input); // حذف @ از یوزرنیم

    // جستجو بر اساس آیدی عددی، شماره موبایل، یوزرنیم و یا نام نمایشی
    // نکته: برای نام نمایشی هم از LIKE استفاده کردیم
    $sql = "SELECT * FROM users WHERE id = ? OR phone = ? OR username LIKE ? OR name LIKE ? LIMIT 1";
    
    $stmt = $db->pdo->prepare($sql);
    
    $stmt->execute([
        $input,             // تطابق کامل id
        $input,             // تطابق کامل phone
        "%$clean_input%",   // جستجوی جزئی username
        "%$input%"          // جستجوی جزئی name (اضافه شده)
    ]);
    
    return $stmt->fetch(PDO::FETCH_ASSOC);
}


// 2. دریافت لیست خریدهای موفق یک کاربر
function getUserOrders($user_id) {
    global $db;
    // اتصال جدول سفارشات به محصولات برای گرفتن نام محصول
    $sql = "SELECT o.*, p.title, p.price FROM orders o 
            JOIN products p ON o.product_id = p.id 
            WHERE o.user_id = ? AND o.status = 'paid' 
            ORDER BY o.created_at DESC LIMIT 20";
    $stmt = $db->pdo->prepare($sql);
    $stmt->execute([$user_id]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// 3. جستجوی محصول توسط مدیر (برای افزودن دستی به کاربر)
function findProductsForAdmin($partial_name) {
    global $db;
    $sql = "SELECT id, title, price FROM products WHERE title LIKE ? LIMIT 10";
    $stmt = $db->pdo->prepare($sql);
    $stmt->execute(["%$partial_name%"]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// 3.5. تابع جدید: جستجوی محصول توسط کاربر
function searchProductsForUser($query) {
    global $db;
    
    // برای جلوگیری از جستجوهای بی‌مورد، حداقل طول عبارت را ۲ کاراکتر در نظر می‌گیریم
    if (mb_strlen($query, 'UTF-8') < 2) {
        return 'TOO_SHORT';
    }

    // جستجو هم در عنوان و هم در توضیحات محصول برای نتایج بهتر
    // محدود کردن نتایج به ۱۵ مورد برای جلوگیری از پیام‌های طولانی
    $sql = "SELECT id, title, price FROM products WHERE title LIKE ? OR description LIKE ? LIMIT 15";
    
    $stmt = $db->pdo->prepare($sql);
    $stmt->execute(["%$query%", "%$query%"]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}


// 4. افزودن محصول به لیست خریدهای کاربر (توسط مدیر)
function addManualOrder($user_id, $product_id) {
    global $db;
    
    // دریافت قیمت محصول جهت ثبت دقیق‌تر در دیتابیس
    $stmt = $db->pdo->prepare("SELECT price FROM products WHERE id = ?");
    $stmt->execute([$product_id]);
    $price = $stmt->fetchColumn() ?: 0;

    // ثبت سفارش با متد gift_by_admin
    $stmt = $db->pdo->prepare("INSERT INTO orders (user_id, product_id, amount, status, payment_method, created_at) VALUES (?, ?, ?, 'paid', 'gift_by_admin', NOW())");
    return $stmt->execute([$user_id, $product_id, $price]);
}

// 5. دریافت نام محصول با آیدی
function getProductName($product_id) {
    global $db;
    $stmt = $db->pdo->prepare("SELECT title FROM products WHERE id = ?");
    $stmt->execute([$product_id]);
    return $stmt->fetchColumn();
}


// 6. دریافت تمام تراکنش‌های کاربر (موفق و ناموفق) برای مدیریت
// دریافت تمام تراکنش‌های کاربر (موفق، ناموفق، رد شده) همراه با نام محصول
function getUserAllTransactions($user_id) {
    global $db;
    // اتصال (JOIN) به جدول محصولات برای گرفتن نام محصول
    // استفاده از LEFT JOIN: اگر محصول حذف شده باشد، تراکنش همچنان نمایش داده می‌شود
    $sql = "SELECT o.*, p.title as product_title 
            FROM orders o
            LEFT JOIN products p ON o.product_id = p.id
            WHERE o.user_id = ? 
            ORDER BY o.created_at DESC LIMIT 50";
            
    $stmt = $db->pdo->prepare($sql);
    $stmt->execute([$user_id]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}


// 7. ترجمه وضعیت تراکنش به فارسی و ایموجی
function getStatusText($status) {
    switch ($status) {
        case 'paid': return '✅ موفق';
        case 'pending': return '⏳ در انتظار بررسی';
        case 'rejected': return '❌ رد شده توسط مدیر';
        case 'failed': return '🚫 ناموفق/لغو شده';
        default: return '❓ نامشخص';
    }
}


// 8. ترجمه روش پرداخت به فارسی (اصلاح شده برای تشخیص دقیق)
function getPaymentMethodText($method) {
    switch ($method) {
        // هم online و هم zarinpal را به عنوان درگاه آنلاین نشان می‌دهیم
        case 'online': 
        case 'zarinpal': 
            return '🌐 درگاه آنلاین';
            
        case 'card': 
            return '💳 کارت به کارت';
            
        case 'stars': 
            return '⭐️ تلگرام استارز';
            
        case 'gift_by_admin': 
            return '🎁 هدیه مدیر';
            
        default: 
            return 'سایر روش‌ها';
    }
}


// ==========================================
//        توابع اختصاصی سیستم ارسال تیکت (جدید)
// ==========================================

// 1. دریافت لیست محصولات خریداری شده توسط کاربر (برای منوی ارسال تیکت)
function getUserPurchasedProductsList($user_id) {
    global $db;
    
    // اصلاح شده: دریافت ستون‌های بیشتر برای محاسبه تاریخ انقضا
    $sql = "SELECT p.id as product_id, p.title, o.id as order_id, o.created_at, o.support_expiry, p.support_days
            FROM orders o
            JOIN products p ON o.product_id = p.id
            WHERE o.user_id = ? AND o.status = 'paid'
            ORDER BY o.created_at DESC";
            
    $stmt = $db->pdo->prepare($sql);
    $stmt->execute([$user_id]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}


// 2. ذخیره نگاشت پیام تیکت (برای اینکه وقتی ادمین ریپلای می‌کند، ربات بداند به چه کسی بفرستد)
// 2. ذخیره نگاشت پیام تیکت (نسخه اصلاح شده با شناسه پیام کاربر)
function saveTicketMessageMapping($user_id, $admin_msg_id, $user_msg_id, $product_id) {
    global $db;
    $stmt = $db->pdo->prepare("INSERT INTO product_ticket_messages (user_id, admin_msg_id, user_msg_id, product_id) VALUES (?, ?, ?, ?)");
    $stmt->execute([$user_id, $admin_msg_id, $user_msg_id, $product_id]);
}


// 3. پیدا کردن اطلاعات تیکت از روی پیامی که ادمین روی آن ریپلای کرده
function getTicketOwnerByAdminMsgId($reply_to_msg_id) {
    global $db;
    // اتصال جداول برای دریافت اطلاعات کامل کاربر و محصول در لحظه پاسخگویی
    $sql = "SELECT tm.*, p.title as product_title, u.name, u.username, u.phone 
            FROM product_ticket_messages tm
            JOIN products p ON tm.product_id = p.id
            JOIN users u ON tm.user_id = u.id
            WHERE tm.admin_msg_id = ? LIMIT 1";
            
    $stmt = $db->pdo->prepare($sql);
    $stmt->execute([$reply_to_msg_id]);
    return $stmt->fetch(PDO::FETCH_ASSOC);
}

// 4. دریافت تاریخ خرید یک محصول خاص توسط کاربر (برای نمایش در گزارش به مدیر)
function getProductPurchaseDate($user_id, $product_id) {
    global $db;
    $stmt = $db->pdo->prepare("SELECT created_at FROM orders WHERE user_id = ? AND product_id = ? AND status = 'paid' ORDER BY created_at DESC LIMIT 1");
    $stmt->execute([$user_id, $product_id]);
    $date = $stmt->fetchColumn();
    
    if ($date) {
        // تبدیل تاریخ میلادی دیتابیس به آرایه برای تابع جلالی
        $timestamp = strtotime($date);
        $g_y = date('Y', $timestamp);
        $g_m = date('m', $timestamp);
        $g_d = date('d', $timestamp);
        // استفاده از تابع موجود در فایل functions.php
        $j_date = gregorian_to_jalali($g_y, $g_m, $g_d);
        return implode('/', $j_date); // خروجی: 1403/10/11
    }
    return 'نامشخص';
}

// تابع بررسی اعتبار زمانی پشتیبانی (نسخه اصلاح شده: بر اساس شناسه سفارش)
function checkSupportExpiry($order_id) {
    global $db;
    date_default_timezone_set('Asia/Tehran');

    // دریافت اطلاعات دقیق سفارش
    $stmt = $db->pdo->prepare("
        SELECT o.created_at, o.support_expiry, p.support_days, p.title
        FROM orders o
        JOIN products p ON o.product_id = p.id
        WHERE o.id = ?
    ");
    $stmt->execute([$order_id]);
    $data = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$data) {
        return ['allowed' => false, 'msg' => 'سفارش یافت نشد.', 'expiry_date' => '---'];
    }

    // تعیین تاریخ انقضای نهایی
    $expiry_date_obj = null;
    $purchase_date = new DateTime($data['created_at']);

    // حالت 1: اگر مدیر دستی تاریخ انقضا ست کرده باشد (تمدید شده)
    if (!empty($data['support_expiry'])) {
        $expiry_date_obj = new DateTime($data['support_expiry']);
    }
    // حالت 2: محاسبه خودکار بر اساس روزهای پشتیبانی محصول
    else {
        $support_days = (int)$data['support_days'];
        if ($support_days <= 0) {
            // اگر روز پشتیبانی 0 باشد، یعنی پشتیبانی ندارد
            return [
                'allowed' => false,
                'msg' => "⛔️ این محصول شامل پشتیبانی نمی‌باشد.",
                'expiry_date' => '---'
            ];
        }
        $expiry_date_obj = clone $purchase_date;
        $expiry_date_obj->modify("+$support_days days");
    }

    // محاسبه تاریخ شمسی برای نمایش
    $j_expiry = gregorian_to_jalali(
        $expiry_date_obj->format('Y'),
        $expiry_date_obj->format('m'),
        $expiry_date_obj->format('d')
    );
    $expiry_str = implode('/', $j_expiry);

    // مقایسه با امروز
    $now = new DateTime();
    if ($now > $expiry_date_obj) {
        return [
            'allowed' => false,
            'msg' => "⛔️ مهلت پشتیبانی محصول **{$data['title']}** در تاریخ ($expiry_str) به پایان رسیده است.",
            'expiry_date' => $expiry_str
        ];
    } else {
        return [
            'allowed' => true,
            'product_title' => $data['title'],
            'expiry_date' => $expiry_str
        ];
    }
}


// ==========================================
//        توابع آماری پیشرفته (مدیریت)
// ==========================================

function getStoreStatistics() {
    global $db;
    $stats = [];

    // --- 1. آمار کاربران ---
    $stats['users_online'] = $db->pdo->query("SELECT COUNT(*) FROM users WHERE last_activity >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)")->fetchColumn();
    $stats['users_active_24h'] = $db->pdo->query("SELECT COUNT(*) FROM users WHERE last_activity >= DATE_SUB(NOW(), INTERVAL 24 HOUR)")->fetchColumn();
    $stats['users_joined_week'] = $db->pdo->query("SELECT COUNT(*) FROM users WHERE joined_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchColumn();
    $stats['users_joined_month'] = $db->pdo->query("SELECT COUNT(*) FROM users WHERE joined_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)")->fetchColumn();
    $stats['users_total'] = $db->pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();

    // --- 2. آمار تعداد فروش (موفق) ---
    $stats['sales_today'] = $db->pdo->query("SELECT COUNT(*) FROM orders WHERE status = 'paid' AND DATE(created_at) = CURDATE()")->fetchColumn();
    $stats['sales_24h'] = $db->pdo->query("SELECT COUNT(*) FROM orders WHERE status = 'paid' AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)")->fetchColumn();
    $stats['sales_week'] = $db->pdo->query("SELECT COUNT(*) FROM orders WHERE status = 'paid' AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchColumn();
    $stats['sales_month'] = $db->pdo->query("SELECT COUNT(*) FROM orders WHERE status = 'paid' AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)")->fetchColumn();
    $stats['sales_total'] = $db->pdo->query("SELECT COUNT(*) FROM orders WHERE status = 'paid'")->fetchColumn();

    // --- 3. آمار درآمد تومانی (اصلاح شده) ---
    // منطق جدید: هر چیزی که "استارز" یا "هدیه مدیر" نباشد، درآمد تومانی حساب می‌شود
    // این کار باعث می‌شود سفارش‌های قدیمی که متد پرداختشان ثبت نشده هم محاسبه شوند
    $exclude_methods = "'stars', 'gift_by_admin'";
    
    $stats['income_toman_today'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND (payment_method NOT IN ($exclude_methods) OR payment_method IS NULL) AND DATE(created_at) = CURDATE()")->fetchColumn() ?: 0;
    $stats['income_toman_24h'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND (payment_method NOT IN ($exclude_methods) OR payment_method IS NULL) AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)")->fetchColumn() ?: 0;
    $stats['income_toman_week'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND (payment_method NOT IN ($exclude_methods) OR payment_method IS NULL) AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchColumn() ?: 0;
    $stats['income_toman_month'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND (payment_method NOT IN ($exclude_methods) OR payment_method IS NULL) AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)")->fetchColumn() ?: 0;
    $stats['income_toman_total'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND (payment_method NOT IN ($exclude_methods) OR payment_method IS NULL)")->fetchColumn() ?: 0;

    // --- 4. آمار درآمد استارز ---
    $stats['income_stars_today'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND payment_method = 'stars' AND DATE(created_at) = CURDATE()")->fetchColumn() ?: 0;
    $stats['income_stars_24h'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND payment_method = 'stars' AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)")->fetchColumn() ?: 0;
    $stats['income_stars_week'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND payment_method = 'stars' AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchColumn() ?: 0;
    $stats['income_stars_month'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND payment_method = 'stars' AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)")->fetchColumn() ?: 0;
    $stats['income_stars_total'] = $db->pdo->query("SELECT SUM(amount) FROM orders WHERE status = 'paid' AND payment_method = 'stars'")->fetchColumn() ?: 0;

    // --- 5. آمار محصولات ---
    // تعداد کل محصولات
    $stats['products_total'] = $db->pdo->query("SELECT COUNT(*) FROM products")->fetchColumn();

    // آمار محصولات بر اساس دسته‌بندی (اصلاح نهایی برای رفع باگ حذف محصول)
    // تغییر: اضافه کردن JOIN به جدول products. 
    // این کار باعث می‌شود اگر محصولی حذف شده باشد اما رکوردش در جدول واسط مانده باشد، در آمار شمرده نشود.
    $stats['products_by_cat'] = $db->pdo->query("
        SELECT c.name, COUNT(pc.product_id) as count 
        FROM categories c 
        JOIN product_categories pc ON c.id = pc.category_id 
        JOIN products p ON pc.product_id = p.id
        GROUP BY c.id
    ")->fetchAll(PDO::FETCH_ASSOC);

    return $stats;
}


// این تابع را به انتهای functions.php اضافه کنید
function generateStatsMessage($s) {
    $msg = "📊 **گزارش جامع فروشگاه**\n" . str_repeat("➖", 15) . "\n\n";

    // 1. کاربران
    $msg .= "👥 **آمار کاربران:**\n";
    $msg .= "• آنلاین (۱۵ دقیقه): `{$s['users_online']}`\n";
    $msg .= "• فعال (۲۴ ساعت): `{$s['users_active_24h']}`\n";
    $msg .= "• عضویت هفته: `{$s['users_joined_week']}`\n";
    $msg .= "• عضویت ماه: `{$s['users_joined_month']}`\n";
    $msg .= "• کل کاربران: `{$s['users_total']}`\n\n";

    // 2. فروش
    $msg .= "🛒 **تعداد فروش موفق:**\n";
    $msg .= "• امروز: `{$s['sales_today']}`\n";
    $msg .= "• دیروز تا حالا: `{$s['sales_24h']}`\n";
    $msg .= "• این هفته: `{$s['sales_week']}`\n";
    $msg .= "• این ماه: `{$s['sales_month']}`\n";
    $msg .= "• کل فروش‌ها: `{$s['sales_total']}`\n\n";

    // 3. درآمد تومانی
    $msg .= "💰 **درآمد خالص (تومان):**\n";
    $msg .= "• امروز: `" . number_format($s['income_toman_today']) . "`\n";
    $msg .= "• دیروز تا حالا: `" . number_format($s['income_toman_24h']) . "`\n";
    $msg .= "• این هفته: `" . number_format($s['income_toman_week']) . "`\n";
    $msg .= "• این ماه: `" . number_format($s['income_toman_month']) . "`\n";
    $msg .= "• کل درآمد: `" . number_format($s['income_toman_total']) . "`\n\n";

    // 4. درآمد استارز
    if ($s['income_stars_total'] > 0) {
        $msg .= "⭐️ **درآمد استارز:**\n";
        $msg .= "• امروز: `{$s['income_stars_today']}`\n";
        $msg .= "• دیروز تا حالا: `{$s['income_stars_24h']}`\n";
        $msg .= "• این هفته: `{$s['income_stars_week']}`\n";
        $msg .= "• این ماه: `{$s['income_stars_month']}`\n";
        $msg .= "• کل استارز: `{$s['income_stars_total']}`\n\n";
    }

    // 5. محصولات
    $msg .= "📦 **محصولات:**\n";
    $msg .= "• تعداد کل: `{$s['products_total']}`\n";
    if (!empty($s['products_by_cat'])) {
        foreach ($s['products_by_cat'] as $cat) {
            $cat_name = $cat['name'] ?: 'بدون دسته';
            $msg .= "▫️ $cat_name: `{$cat['count']}`\n";
        }
    }
    
    return $msg;
}

// --- تابع جدید: ایمن‌سازی متن برای جلوگیری از ارور مارک‌داون (حل مشکل جستجو) ---
function escapeMarkdown($text) {
    if (!$text) return '';
    $text = str_replace('_', '\\_', $text);
    $text = str_replace('*', '\\*', $text);
    $text = str_replace('`', '\\`', $text);
    $text = str_replace('[', '\\[', $text);
    return $text;
}

// --- تابع جدید: فرمت‌دهی هوشمند قیمت بر اساس روش پرداخت ---
function formatPrice($amount, $method) {
    // اگر روش پرداخت "استارز" باشد
    if ($method == 'stars') {
        return number_format($amount) . ' ⭐️'; // نمایش ستاره
    }
    // در غیر این صورت (تومان، درگاه آنلاین، کارت به کارت و...)
    return number_format($amount) . ' تومان';
}

// ==========================================
//        سیستم مدیریت ادمین‌های پیشرفته
// ==========================================

// 1. بررسی آیا کاربر مدیر اصلی (داخل فایل کانفیگ) است؟
function isConfigAdmin($user_id) {
    // بررسی همزمان لیست مدیران و مدیر اصلی تکی برای جلوگیری از تداخل
    $is_in_array = (defined('CONFIG_ADMINS') && is_array(CONFIG_ADMINS) && in_array($user_id, CONFIG_ADMINS));
    $is_single = (defined('ADMIN_ID') && $user_id == ADMIN_ID);
    
    return $is_in_array || $is_single;
}


// 2. بررسی آیا کاربر مدیر ثبت شده در دیتابیس است؟
function isDBAdmin($user_id) {
    global $db;
    $stmt = $db->pdo->prepare("SELECT id FROM admins WHERE user_id = ?");
    $stmt->execute([$user_id]);
    return $stmt->rowCount() > 0;
}

// 3. بررسی کلی آیا کاربر مدیر است؟ (چه در کانفیگ، چه در دیتابیس)
function isAdmin($user_id) {
    return isConfigAdmin($user_id) || isDBAdmin($user_id);
}

// 4. افزودن ادمین جدید به دیتابیس
function addAdminToDB($user_id, $name) {
    global $db;
    if (isAdmin($user_id)) {
        return false; // قبلاً مدیر است
    }
    $stmt = $db->pdo->prepare("INSERT INTO admins (user_id, name) VALUES (?, ?)");
    return $stmt->execute([$user_id, $name]);
}

// 5. دریافت لیست ادمین‌های دیتابیس
function getDBAdminsList() {
    global $db;
    $stmt = $db->pdo->query("SELECT * FROM admins ORDER BY id DESC");
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// 6. حذف ادمین از دیتابیس
function deleteAdminFromDB($admin_id_db) {
    global $db;
    $stmt = $db->pdo->prepare("DELETE FROM admins WHERE id = ?");
    return $stmt->execute([$admin_id_db]);
}

// 7. دریافت لیست آیدی‌هایی که باید اعلان دریافت کنند (بر اساس تنظیمات)
function getAdminsForNotification() {
    global $db;
    // دریافت تنظیمات فعلی (پیش‌فرض: all)
    $mode = getSetting('admin_notification_mode');
    if (!$mode) $mode = 'all';

    $recipients = [];

    // گروه 1: مدیران کانفیگ (اصلاح شده: افزودن حالت creator که در پنل ادمین ست می‌شود)
    if ($mode == 'all' || $mode == 'config_only' || $mode == 'creator') {
        if (defined('CONFIG_ADMINS') && is_array(CONFIG_ADMINS)) {
            $recipients = array_merge($recipients, CONFIG_ADMINS);
        } else {
            // اگر آرایه نبود، فقط ادمین اصلی
            if (defined('ADMIN_ID')) {
                $recipients[] = ADMIN_ID;
            }
        }
    }

    // گروه 2: مدیران دیتابیس (ادمین‌های ادد شده از پنل)
    if ($mode == 'all' || $mode == 'db_only') {
        $stmt = $db->pdo->query("SELECT user_id FROM admins");
        $db_ids = $stmt->fetchAll(PDO::FETCH_COLUMN);
        if ($db_ids) {
            $recipients = array_merge($recipients, $db_ids);
        }
    }

    // حذف تکراری‌ها و بازگرداندن آرایه (مثلا اگر ادمین اصلی در دیتابیس هم ادد شده باشد)
    return array_unique($recipients);
}

// 8. منوی مدیریت ادمین‌ها (فقط برای مدیران کانفیگ)
function adminManagementMenu() {
    return json_encode([
        'keyboard' => [
            [['text' => '➕ افزودن ادمین'], ['text' => '👤 لیست ادمین‌ها']],
            [['text' => '🔔 مدیریت نمایش اعلان و پیام‌ها']],
            [['text' => '🔙 بازگشت به تنظیمات فروشگاه']]
        ],
        'resize_keyboard' => true
    ]);
}

// 9. منوی تنظیمات اعلان‌ها
function adminNotificationSettingsMenu() {
    $mode = getSetting('admin_notification_mode');
    if (!$mode) $mode = 'all'; // پیش‌فرض

    $txt_all = ($mode == 'all') ? '✅ همه مدیران' : 'همه مدیران';
    $txt_config = ($mode == 'config_only') ? '✅ فقط مدیران اصلی (Config)' : 'فقط مدیران اصلی (Config)';
    $txt_db = ($mode == 'db_only') ? '✅ فقط مدیران افزوده شده' : 'فقط مدیران افزوده شده';

    return json_encode([
        'keyboard' => [
            [['text' => $txt_all]],
            [['text' => $txt_config], ['text' => $txt_db]],
            [['text' => '🔙 بازگشت به مدیریت ادمین‌ها']]
        ],
        'resize_keyboard' => true
    ]);
}

// 10. دریافت اطلاعات کامل سفارش با آیدی (برای بررسی وضعیت تایید فیش)
function getOrderById($order_id) {
    global $db;
    $stmt = $db->pdo->prepare("SELECT * FROM orders WHERE id = ?");
    $stmt->execute([$order_id]);
    return $stmt->fetch(PDO::FETCH_ASSOC);
}

// --- دریافت نام ادمین (برای نمایش در اعلان‌ها) ---
function getAdminName($user_id) {
    global $db;
    // 1. ابتدا در جدول ادمین‌ها جستجو می‌کنیم
    $stmt = $db->pdo->prepare("SELECT name FROM admins WHERE user_id = ?");
    $stmt->execute([$user_id]);
    $name = $stmt->fetchColumn();
    
    if ($name) {
        return $name;
    }

    // 2. اگر در دیتابیس نبود، چک میکنیم آیا مدیر اصلی است
    if (isConfigAdmin($user_id)) {
        return "مدیر اصلی (Owner)";
    }

    // 3. اگر هیچکدام نبود
    return "ادمین ($user_id)";
}

// --- تابع ارسال اعلان پاسخگویی به سایر مدیران (ویرایش شده: نمایش شناسه عددی) ---
function notifyAdminsOfReply($replier_id, $target_user_id, $response_text, $context_type = 'support') {
    // دریافت لیست تمام مدیرانی که باید اعلان بگیرند
    $admins = getAdminsForNotification();
    
    // نکته: دریافت نام حذف شد چون قرار است شناسه عددی نمایش داده شود
    
    // خلاصه کردن متن پاسخ اگر طولانی باشد
    $short_text = mb_substr($response_text, 0, 100) . (mb_strlen($response_text) > 100 ? '...' : '');
    
    // تعیین عنوان بخش
    $section_title = ($context_type == 'ticket') ? "🎫 تیکت محصول" : "📞 پشتیبانی عمومی";

    $msg = "🔔 **گزارش پاسخگویی همکاران**\n\n";
    // در خط زیر شناسه عددی جایگزین نام شد
    $msg .= "👤 همکار گرامی با شناسه **{$replier_id}** به پیام کاربر پاسخ داد.\n\n";
    $msg .= "🆔 آیدی کاربر: `$target_user_id`\n";
    $msg .= "📂 بخش: $section_title\n";
    $msg .= "💬 **متن پاسخ:**\n$short_text";

    foreach ($admins as $admin_id) {
        // به خود شخصی که پاسخ داده اعلان نمیفرستیم
        if ($admin_id == $replier_id) continue;

        bot('sendMessage', [
            'chat_id' => $admin_id,
            'text' => $msg,
            'parse_mode' => 'Markdown'
        ]);
    }
}


// ==========================================
//   توابع مدیریت چند دسته‌بندی (افزوده شده جدید)
// ==========================================

// 1. دریافت لیست آیدی دسته‌بندی‌های یک محصول
function getProductCategoryIds($product_id) {
    global $db;
    $stmt = $db->pdo->prepare("SELECT category_id FROM product_categories WHERE product_id = ?");
    $stmt->execute([$product_id]);
    return $stmt->fetchAll(PDO::FETCH_COLUMN);
}

// 2. بروزرسانی دسته‌بندی‌های محصول (حذف قدیمی‌ها و ثبت جدید)
function updateProductCategories($product_id, $category_ids) {
    global $db;
    // ابتدا تمام دسته‌بندی‌های قبلی این محصول را از جدول واسط پاک می‌کنیم
    $stmt = $db->pdo->prepare("DELETE FROM product_categories WHERE product_id = ?");
    $stmt->execute([$product_id]);

    // اگر لیست جدید خالی نبود، دسته‌بندی‌های جدید را ثبت می‌کنیم
    if (!empty($category_ids) && is_array($category_ids)) {
        $sql = "INSERT INTO product_categories (product_id, category_id) VALUES ";
        $values = [];
        $placeholders = [];
        
        foreach ($category_ids as $cat_id) {
            $placeholders[] = "(?, ?)";
            $values[] = $product_id;
            $values[] = $cat_id;
        }
        
        // ساخت کوئری یکجا برای سرعت بیشتر
        $sql .= implode(", ", $placeholders);
        $stmt = $db->pdo->prepare($sql);
        $stmt->execute($values);
    }
}

// 3. دریافت نام دسته‌بندی‌های محصول به صورت متنی (برای نمایش در لیست محصولات و پیام‌ها)
function getCategoryNamesStr($product_id) {
    global $db;
    // اتصال جدول دسته‌بندی‌ها به جدول واسط
    $stmt = $db->pdo->prepare("
        SELECT c.name 
        FROM categories c
        JOIN product_categories pc ON c.id = pc.category_id
        WHERE pc.product_id = ?
    ");
    $stmt->execute([$product_id]);
    $names = $stmt->fetchAll(PDO::FETCH_COLUMN);
    
    // اگر دسته‌بندی نداشت
    if (empty($names)) return 'بدون دسته‌بندی';
    
    // اتصال نام‌ها با ویرگول (مثال: موبایل، سامسونگ)
    return implode('، ', $names);
}

// 4. دریافت محصولات بر اساس آیدی دسته‌بندی (جایگزین کوئری قدیمی در پنل کاربر)
function getProductsByCatId($cat_id) {
    global $db;
    // انتخاب محصولاتی که در جدول واسط دارای این کتگوری آیدی هستند
    $stmt = $db->pdo->prepare("
        SELECT p.* 
        FROM products p
        JOIN product_categories pc ON p.id = pc.product_id
        WHERE pc.category_id = ?
        ORDER BY p.id DESC
    ");
    $stmt->execute([$cat_id]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}


// 5. دریافت لیست فایل‌های محصول (همراه با کپشن) - مورد نیاز برای پنل کاربر و ادمین
function getProductFiles($product_id) {
    global $db;
    // انتخاب همه ستون‌ها شامل caption که در دیتابیس اضافه کردیم
    $stmt = $db->pdo->prepare("SELECT * FROM product_files WHERE product_id = ?");
    $stmt->execute([$product_id]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// ==========================================
//   تابع ارسال پیام‌های طولانی (توضیحات بیشتر)
// ==========================================

function sendLongMessage($chat_id, $text) {
    if (empty($text)) return;
    
    // حد مجاز تلگرام 4096 کاراکتر است، ما برای اطمینان روی 4000 تنظیم می‌کنیم
    $max_length = 4000;
    
    // اگر متن کوتاه بود، عادی ارسال کن
    if (mb_strlen($text) <= $max_length) {
        bot('sendMessage', [
            'chat_id' => $chat_id,
            'text' => $text,
            // از آنجا که ممکن است متن طولانی حاوی کاراکترهای خاص باشد، parse_mode را خاموش یا روی HTML می‌گذاریم اگر نیاز بود
            // فعلا بدون parse_mode می‌فرستیم تا تداخل ایموجی و کاراکتر پیش نیاید
        ]);
    } else {
        // اگر متن طولانی بود، آن را تکه‌تکه کن و پشت سر هم بفرست
        while (mb_strlen($text) > $max_length) {
            $chunk = mb_substr($text, 0, $max_length);
            $text = mb_substr($text, $max_length);
            
            bot('sendMessage', [
                'chat_id' => $chat_id,
                'text' => $chunk
            ]);
            
            // وقفه کوتاه 0.1 ثانیه‌ای برای اینکه ترتیب پیام‌ها در تلگرام به هم نریزد
            usleep(100000); 
        }
        
        // ارسال باقیمانده متن (بخش آخر)
        if (!empty($text)) {
            bot('sendMessage', [
                'chat_id' => $chat_id,
                'text' => $text
            ]);
        }
    }
}


?>
