<?php
/**
 * ماژول «خدمات شبکه‌های اجتماعی» (Telegram / Instagram) — کاملا مستقل، namespace: smm*
 * ------------------------------------------------------------------------------------
 * این ماژول دقیقا طبق مستندات واقعی apiaddress.com (که در پرامپت اولیه داده شده) پیاده‌سازی
 * شده و هیچ Endpoint/پارامتر/Service ID فرضی در آن وجود ندارد (کلاینت در smm_client.php).
 *
 * اتصال به بقیه‌ی پروژه (طبق همان الگوی ماژول‌های virtual_number.php / virtual_services.php):
 *   - index.php : require_once 'smm_services.php' (کنار سایر require_once ها)
 *                 و در زنجیره‌ی دیسپچ: } elseif (smmShouldHandle()) { smmDispatch(); }
 *   - admin.php : در همان if/elseif انتهای فایل: elseif (smmAdminShouldHandle()) { smmAdminDispatch(); }
 *   - virtual_services.php → vsMenuKeyboard(): یک ردیف چهارم («📱 خدمات تلگرام» راست /
 *     «📸 خدمات اینستاگرام» چپ) اضافه شده که به smmplat_telegram / smmplat_instagram وصل می‌شود.
 *   (این‌ها به‌صورت خودکار در همین تحویل اعمال شده‌اند.)
 *
 * ⚠️ نکته‌ی مهم درباره‌ی تشخیص Telegram/Instagram (طبق درخواست صریح کاربر):
 * چون در این محیط امکان فراخوانی واقعی apiaddress.com وجود ندارد (دامنه در فهرست
 * دامنه‌های مجاز شبکه نیست) و در دستورالعمل هم صراحتا آمده «Service ID ها را حدس
 * نزن»، این ماژول به‌جای حدس زدن ساختار category، یک سیستم Mapping کاملا
 * داده‌محور و قابل مدیریت ساخته:
 *   ۱) smmSyncServices() تمام سرویس‌های واقعی را از endpoint «services» می‌خواند و در
 *      جدول smm_services کش می‌کند (بدون فیلتر کردن چیزی).
 *   ۲) به‌صورت خودکار فقط بر اساس محتوای واقعیِ فیلد category/name همان سرویس (نه یک
 *      Service ID حدسی) با جستجوی کلیدواژه‌ی "telegram"/"تلگرام" یا
 *      "instagram"/"اینستاگرام" پلتفرم را حدس اولیه می‌زند؛ اگر با هیچ‌کدام مچ نشود،
 *      platform=NULL می‌ماند و به کاربران نشان داده نمی‌شود.
 *   ۳) از پنل ادمین («📡 خدمات تلگرام/اینستاگرام → 🗂 مدیریت سرویس‌ها») ادمین می‌تواند با
 *      دیدن نام/دسته‌ی واقعیِ هر سرویس، پلتفرم را دستی عوض/تایید و enabled/disabled کند؛
 *      این override همیشه روی حدس خودکار اولویت دارد و با Sync دوباره از بین نمی‌رود.
 *   فقط سرویس‌هایی که platform IN ('telegram','instagram') AND enabled=1 باشند به
 *   کاربر نشان داده می‌شوند؛ همه‌ی سرویس‌های دیگر (TikTok/YouTube/...) هرگز دیده نمی‌شوند.
 *
 * ⚠️ واحد Rate (طبق تایید صریح کاربر: مستقیم از apiaddress.com، بدون تبدیل دلار):
 * «rate» قیمت به ازای هر ۱۰۰۰ واحد است و از قبل به تومان است (نه دلار)؛ بر خلاف
 * Stars/Premium/Gift که قیمت پایه‌شان دلاری است و از موتور نرخ دلار پروژه
 * (vsGetUsdIrtRate در virtual_pricing.php) عبور می‌کند، قیمت خدمات SMM اصلا به آن
 * موتور کاری ندارد: apiCostToman = quantity/1000 × rate. فقط درصد سود (Markup) که
 * از پنل ادمین («📈 درصد سود تلگرام/اینستاگرام») تنظیم می‌شود روی همین عدد اعمال
 * می‌شود. نسخه‌ی قبلی این عدد تومانی را دوباره در نرخ دلار ضرب می‌کرد که باعث
 * می‌شد قیمت نهایی چند برابر واقعی و «فضایی» نمایش داده شود؛ همان باگ بود.
 */

require_once __DIR__ . '/smm_client.php';

define('SMM_ADMIN_BUTTON_TEXT', '📡 خدمات تلگرام/اینستاگرام');
define('SMM_PER_PAGE', 8);

#-----------------[ جداول ]-------------------#
function smmEnsureTables()
{
    global $pdo;
    static $done = false;
    if ($done) return;
    $done = true;

    $pdo->exec("CREATE TABLE IF NOT EXISTS smm_services (
        service_id VARCHAR(64) NOT NULL PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        category VARCHAR(255) NULL,
        platform VARCHAR(20) NULL,
        platform_source VARCHAR(10) NOT NULL DEFAULT 'auto',
        rate DECIMAL(18,6) NOT NULL DEFAULT 0,
        min_amount INT NOT NULL DEFAULT 0,
        max_amount INT NOT NULL DEFAULT 0,
        refill TINYINT(1) NOT NULL DEFAULT 0,
        cancel TINYINT(1) NOT NULL DEFAULT 0,
        enabled TINYINT(1) NOT NULL DEFAULT 0,
        markup_percent DECIMAL(6,2) NULL,
        last_seen_at DATETIME NULL,
        updated_at DATETIME NULL,
        INDEX(platform), INDEX(enabled)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");

    $pdo->exec("CREATE TABLE IF NOT EXISTS smm_orders (
        id INT AUTO_INCREMENT PRIMARY KEY,
        user_id BIGINT NOT NULL,
        username VARCHAR(255) NULL,
        platform VARCHAR(20) NOT NULL,
        service_id VARCHAR(64) NOT NULL,
        service_name VARCHAR(255) NULL,
        link VARCHAR(500) NOT NULL,
        quantity INT NOT NULL,
        api_order_id VARCHAR(64) NULL,
        amount_paid BIGINT NOT NULL DEFAULT 0,
        api_cost BIGINT NOT NULL DEFAULT 0,
        profit BIGINT NOT NULL DEFAULT 0,
        status VARCHAR(30) NOT NULL DEFAULT 'pending',
        start_count VARCHAR(32) NULL,
        remains VARCHAR(32) NULL,
        refill_id VARCHAR(64) NULL,
        refill_status VARCHAR(30) NULL,
        admin_note VARCHAR(255) NULL,
        created_at DATETIME NOT NULL,
        updated_at DATETIME NULL,
        INDEX(user_id), INDEX(status), INDEX(service_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
}

#-----------------[ تنظیمات (روی همان جدول virtual_settings ماژول خدمات مجازی) ]-------------------#
function smmDefaultSettings()
{
    return [
        'smm_enabled_telegram'  => '1',
        'smm_enabled_instagram' => '1',
        'smm_profit_telegram'   => '20',   // درصد سود پیش‌فرض روی هزینه‌ی API برای سرویس‌های تلگرام
        'smm_profit_instagram'  => '20',   // درصد سود پیش‌فرض روی هزینه‌ی API برای سرویس‌های اینستاگرام
        'smm_api_url'           => '',     // اگر خالی باشد، از config.php ($smm_api_url) استفاده می‌شود
        'smm_api_key'           => '',     // اگر خالی باشد، از config.php ($smm_api_key) استفاده می‌شود
        'smm_style_telegram'    => 'primary',
        'smm_style_instagram'   => 'danger',
        'smm_last_sync_at'      => '0',
        'smm_last_sync_count'   => '0',
    ];
}

function smmSetting($name, $default = null)
{
    // از همان انبار کلید/مقدار ماژول خدمات مجازی استفاده می‌شود (virtual_settings) تا
    // یک جدول تنظیمات موازی و ناسازگار ساخته نشود.
    $val = function_exists('vsSetting') ? vsSetting($name, null) : null;
    if ($val !== null) return $val;
    $defaults = smmDefaultSettings();
    return $defaults[$name] ?? $default;
}

function smmSetSetting($name, $value)
{
    if (function_exists('vsSetSetting')) {
        vsSetSetting($name, $value);
    }
}

function smmApiUrl()
{
    global $smm_api_url;
    $override = trim((string) smmSetting('smm_api_url', ''));
    if ($override !== '') return $override;
    return isset($smm_api_url) ? $smm_api_url : '';
}

function smmApiKey()
{
    global $smm_api_key;
    $override = trim((string) smmSetting('smm_api_key', ''));
    if ($override !== '') return $override;
    return isset($smm_api_key) ? $smm_api_key : '';
}

function smmClient()
{
    return new SmmApiClient(smmApiUrl(), smmApiKey());
}

#-----------------[ برچسب‌های فارسی پلتفرم ]-------------------#
function smmPlatformLabel($platform)
{
    if ($platform === 'telegram') return '📱 تلگرام';
    if ($platform === 'instagram') return '📸 اینستاگرام';
    return '❔ نامشخص';
}

#-----------------[ تشخیص خودکار پلتفرم از روی متن واقعیِ category/name (بدون حدس Service ID) ]-------------------#
function smmDetectPlatform($category, $name)
{
    $hay = mb_strtolower(($category ?? '') . ' ' . ($name ?? ''), 'UTF-8');
    if ($hay === '') return null;
    if (strpos($hay, 'telegram') !== false || mb_strpos($hay, 'تلگرام') !== false) return 'telegram';
    if (strpos($hay, 'instagram') !== false || mb_strpos($hay, 'اینستاگرام') !== false || mb_strpos($hay, 'اینستا') !== false) return 'instagram';
    return null;
}

#-----------------[ دریافت/به‌روزرسانیِ کش سرویس‌ها از API واقعی ]-------------------#
function smmSyncServices()
{
    global $pdo;
    smmEnsureTables();

    $res = smmClient()->services();
    if (!$res['ok']) {
        return ['ok' => false, 'error_type' => $res['error_type'] ?? 'unknown', 'error_detail' => $res['error_detail'] ?? null];
    }
    $list = $res['data'];
    if (!is_array($list)) {
        return ['ok' => false, 'error_type' => 'invalid_response'];
    }

    $seenIds = [];
    $count = 0;
    $stmtExisting = $pdo->prepare("SELECT platform, platform_source, enabled FROM smm_services WHERE service_id = ?");
    $stmtUpsert = $pdo->prepare("INSERT INTO smm_services
        (service_id, name, category, platform, platform_source, rate, min_amount, max_amount, refill, cancel, enabled, last_seen_at, updated_at)
        VALUES (:id,:name,:cat,:plat,:src,:rate,:min,:max,:refill,:cancel,:enabled, NOW(), NOW())
        ON DUPLICATE KEY UPDATE
            name = VALUES(name),
            category = VALUES(category),
            rate = VALUES(rate),
            min_amount = VALUES(min_amount),
            max_amount = VALUES(max_amount),
            refill = VALUES(refill),
            cancel = VALUES(cancel),
            last_seen_at = NOW(),
            updated_at = NOW()");

    foreach ($list as $item) {
        if (!is_array($item) || !isset($item['service'])) continue;
        $serviceId = (string) $item['service'];
        $seenIds[] = $serviceId;
        $count++;

        $stmtExisting->execute([$serviceId]);
        $existing = $stmtExisting->fetch();

        // اگر ادمین قبلا دستی پلتفرم را تعیین کرده (platform_source='manual')، آن حفظ
        // می‌شود و Sync دوباره رویش نمی‌نویسد. فقط برای سرویس‌های جدید یا سرویس‌هایی که
        // هنوز تشخیص خودکار داشته‌اند، حدس خودکار (دوباره) محاسبه می‌شود.
        if ($existing && $existing['platform_source'] === 'manual') {
            $platform = $existing['platform'];
            $source = 'manual';
            $enabled = $existing['enabled'];
        } else {
            $platform = smmDetectPlatform($item['category'] ?? '', $item['name'] ?? '');
            $source = 'auto';
            // پیش‌فرض: حتی سرویس‌های تشخیص‌داده‌شده هم غیرفعال شروع می‌شوند تا ادمین
            // آگاهانه هرکدام را که می‌خواهد فعال کند (طبق درخواست: «ادمین باید بتواند
            // سرویس‌هایی که API ارائه می‌دهد را انتخاب کند»).
            $enabled = $existing ? $existing['enabled'] : 0;
        }

        $stmtUpsert->execute([
            'id' => $serviceId,
            'name' => (string) ($item['name'] ?? ''),
            'cat' => (string) ($item['category'] ?? ''),
            'plat' => $platform,
            'src' => $source,
            'rate' => floatval($item['rate'] ?? 0),
            'min' => intval($item['min'] ?? 0),
            'max' => intval($item['max'] ?? 0),
            'refill' => !empty($item['refill']) ? 1 : 0,
            'cancel' => !empty($item['cancel']) ? 1 : 0,
            'enabled' => $enabled,
        ]);
        // چون ON DUPLICATE KEY UPDATE بالا platform/platform_source/enabled را دست‌نخورده
        // نگه می‌دارد (عمدا در لیست VALUES(...) نیامده‌اند)، برای سرویس‌های جدید هم باید
        // این سه فیلد در INSERT اولیه درست ست شوند که شدند (پارامترهای plat/src/enabled).
    }

    smmSetSetting('smm_last_sync_at', (string) time());
    smmSetSetting('smm_last_sync_count', (string) $count);

    return ['ok' => true, 'count' => $count, 'seen_ids' => $seenIds];
}

function smmListServices($platform, $onlyEnabled = true)
{
    global $pdo;
    smmEnsureTables();
    $sql = "SELECT * FROM smm_services WHERE platform = ?";
    if ($onlyEnabled) $sql .= " AND enabled = 1";
    $sql .= " ORDER BY name ASC";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$platform]);
    return $stmt->fetchAll();
}

function smmGetService($serviceId)
{
    global $pdo;
    smmEnsureTables();
    $stmt = $pdo->prepare("SELECT * FROM smm_services WHERE service_id = ?");
    $stmt->execute([$serviceId]);
    $row = $stmt->fetch();
    return $row ?: null;
}

#-----------------[ قیمت‌گذاری: هزینه API (مستقیم به تومان، بدون تبدیل دلار) → + سود ]-------------------#
// rate همان چیزی است که مستقیم از API مرجع (apiaddress.com) برای هر ۱۰۰۰ واحد
// می‌آید و از قبل به تومان است؛ هیچ تبدیل نرخ دلاری روی آن اعمال نمی‌شود (بر خلاف
// Premium/Stars/Gift که قیمت پایه‌شان دلاری است). قبلا اشتباهاً همین rate تومانی
// دوباره در نرخ دلار ضرب می‌شد که باعث می‌شد قیمت نهایی چند برابر واقعی شود.
// خروجی: ['ok'=>bool, 'api_cost_toman'=>int, 'user_price'=>int, 'profit'=>int]
function smmCalcPrice($service, $quantity)
{
    $quantity = max(0, intval($quantity));
    $rate = floatval($service['rate']);
    if ($rate <= 0 || $quantity <= 0) {
        return ['ok' => false, 'reason' => 'invalid_rate_or_quantity'];
    }

    $apiCostToman = ($quantity / 1000) * $rate;

    $platform = $service['platform'];
    $profitPercent = $service['markup_percent'] !== null
        ? floatval($service['markup_percent'])
        : floatval(smmSetting('smm_profit_' . $platform, 20));

    // برای هم‌راستا ماندن دقیق با موتور قیمت‌گذاری فعلی Stars/Premium/Gift، اعمال
    // سود و گرد کردن قیمت هم از همان توابع virtual_pricing.php استفاده می‌کند
    // (vsApplyProfit/vsRoundPrice) نه یک فرمول موازی جدید.
    $userPriceRaw = function_exists('vsApplyProfit') ? vsApplyProfit($apiCostToman, $profitPercent) : ($apiCostToman * (1 + $profitPercent / 100));

    $apiCostToman = function_exists('vsRoundPrice') ? vsRoundPrice($apiCostToman) : (int) round($apiCostToman);
    $userPrice = function_exists('vsRoundPrice') ? vsRoundPrice($userPriceRaw) : (int) round($userPriceRaw);

    return [
        'ok' => true,
        'api_cost_toman' => $apiCostToman,
        'user_price' => $userPrice,
        'profit' => max(0, $userPrice - $apiCostToman),
        'profit_percent' => $profitPercent,
    ];
}

function smmPriceUnavailableText()
{
    return "⚠️ در حال حاضر امکان محاسبه‌ی قیمت این سرویس وجود ندارد (rate نامعتبر است یا سرویس هنوز Sync نشده). لطفاً بعداً تلاش کنید یا با پشتیبانی تماس بگیرید.";
}

#-----------------[ وضعیت API → متن قابل‌فهم فارسی ]-------------------#
function smmStatusLabel($apiStatus)
{
    $map = [
        'Pending' => '⏳ در انتظار',
        'In progress' => '🔄 در حال انجام',
        'Processing' => '🔄 در حال انجام',
        'Completed' => '✅ تکمیل شده',
        'Partial' => '🟡 نسبی انجام شده',
        'Canceled' => '❌ لغو شده',
        'Cancelled' => '❌ لغو شده',
    ];
    return $map[$apiStatus] ?? ('❔ ' . $apiStatus);
}

#-----------------[ وضعیتِ چندمرحله‌ای کاربر (روی همان Processing_value، با مارکر _smm) ]-------------------#
function smmState($from_id)
{
    global $user;
    $raw = $user['Processing_value'] ?? '';
    $data = json_decode($raw, true);
    return (is_array($data) && !empty($data['_smm'])) ? $data : null;
}

function smmSaveState($from_id, array $state)
{
    global $user;
    $state['_smm'] = true;
    $encoded = json_encode($state, JSON_UNESCAPED_UNICODE);
    update('user', 'Processing_value', $encoded, 'id', $from_id);
    $user['Processing_value'] = $encoded;
}

function smmClearState($from_id)
{
    global $user;
    update('user', 'Processing_value', '0', 'id', $from_id);
    $user['Processing_value'] = '0';
}

#-----------------[ Dispatcher سمت کاربر ]-------------------#
function smmShouldHandle()
{
    global $datain, $user;
    if (is_string($datain) && strpos($datain, 'smm') === 0) return true;
    $step = $user['step'] ?? '';
    if (is_string($step) && strpos($step, 'smm_') === 0) return true;
    return false;
}

function smmDispatch()
{
    global $from_id, $message_id, $datain, $username, $text, $user;

    smmEnsureTables();

    if ($datain === 'smmnoop') {
        return;
    }

    #--------------- انتخاب پلتفرم (ورودی از ردیف چهارم منوی صفحه دوم) ---------------#
    if (preg_match('/^smmplat_(telegram|instagram)$/', $datain, $m)) {
        $platform = $m[1];
        if (smmSetting('smm_enabled_' . $platform, '1') !== '1') {
            Editmessagetext($from_id, $message_id, '⛔️ خدمات ' . smmPlatformLabel($platform) . ' در حال حاضر توسط ادمین غیرفعال شده است.', vsBackToMenuKeyboard(), 'HTML');
            return;
        }
        smmShowCategories($from_id, $message_id, $platform, 0);
        return;
    }

    // لیست دسته‌ها (زیرمجموعه‌های واقعیِ همان سرویس‌های API، مثل «ری‌اکشن»/«ممبر گروه»/«ممبر کانال»/«بوست»/«استارت ربات» و...)
    if (preg_match('/^smmcatpg_(telegram|instagram)_(\d+)$/', $datain, $m)) {
        smmShowCategories($from_id, $message_id, $m[1], intval($m[2]));
        return;
    }
    if (preg_match('/^smmcatidx_(telegram|instagram)_(\d+)$/', $datain, $m)) {
        smmSelectCategory($from_id, $message_id, $m[1], intval($m[2]));
        return;
    }
    if ($datain === 'smmbackcats') {
        $state = smmState($from_id);
        $platform = $state['platform'] ?? null;
        if (!$platform) { smmClearState($from_id); Editmessagetext($from_id, $message_id, "🖥 <b>صفحه دوم | خدمات مجازی</b>\n\nیکی از خدمات زیر را انتخاب کنید:", vsMenuKeyboard(), 'HTML'); return; }
        // اگر این پلتفرم اصلاً بیش از یک دسته ندارد، صفحه‌ی دسته‌ها بی‌فایده است؛
        // مستقیم به منوی اصلی برمی‌گردیم تا حلقه‌ی بی‌معنی رخ ندهد.
        if (count($state['categories'] ?? []) <= 1) {
            smmClearState($from_id);
            Editmessagetext($from_id, $message_id, "🖥 <b>صفحه دوم | خدمات مجازی</b>\n\nیکی از خدمات زیر را انتخاب کنید:", vsMenuKeyboard(), 'HTML');
            return;
        }
        smmShowCategories($from_id, $message_id, $platform, 0);
        return;
    }

    // لیست زیرگروه‌های یک دسته (اولترا/اقتصادی/پرمیوم/...) — فقط وقتی بیش از یک
    // زیرگروه در آن دسته تشخیص داده شده باشد این لایه اصلا نمایش داده می‌شود.
    if (preg_match('/^smmtierpg_(telegram|instagram)_(\d+)_(\d+)$/', $datain, $m)) {
        smmShowTiers($from_id, $message_id, $m[1], intval($m[2]), intval($m[3]));
        return;
    }
    if (preg_match('/^smmtieridx_(telegram|instagram)_(\d+)_(\d+)$/', $datain, $m)) {
        smmSelectTier($from_id, $message_id, $m[1], intval($m[2]), intval($m[3]));
        return;
    }
    if (preg_match('/^smmbacktiers_(telegram|instagram)_(\d+)$/', $datain, $m)) {
        smmShowTiers($from_id, $message_id, $m[1], intval($m[2]), 0);
        return;
    }

    // جدول سرویس‌های داخل یک دسته (دقیقا مثل جدول شماره مجازی: نام | قیمت) —
    // هم برای حالت بدون زیرگروه و هم برای جدول داخل یک زیرگروه انتخاب‌شده استفاده می‌شود.
    if (preg_match('/^smmsvcpg_(telegram|instagram)_(\d+)_(\d+)$/', $datain, $m)) {
        smmShowServicesTable($from_id, $message_id, $m[1], intval($m[2]), intval($m[3]));
        return;
    }
    if (preg_match('/^smmsvcidx_(telegram|instagram)_(\d+)_(\d+)$/', $datain, $m)) {
        smmSelectService($from_id, $message_id, $m[1], intval($m[2]), intval($m[3]));
        return;
    }
    if (preg_match('/^smmtiersvcpg_(telegram|instagram)_(\d+)_(\d+)_(\d+)$/', $datain, $m)) {
        smmShowServicesTable($from_id, $message_id, $m[1], intval($m[2]), intval($m[4]), intval($m[3]));
        return;
    }
    if (preg_match('/^smmtiersvcidx_(telegram|instagram)_(\d+)_(\d+)_(\d+)$/', $datain, $m)) {
        smmSelectService($from_id, $message_id, $m[1], intval($m[2]), intval($m[4]));
        return;
    }

    if ($datain === 'smmback') {
        smmClearState($from_id);
        Editmessagetext($from_id, $message_id, "🖥 <b>صفحه دوم | خدمات مجازی</b>\n\nیکی از خدمات زیر را انتخاب کنید:", vsMenuKeyboard(), 'HTML');
        return;
    }

    if ($datain === 'smmbacksvc') {
        $state = smmState($from_id);
        $platform = $state['platform'] ?? null;
        $catIdx = $state['cat_idx'] ?? null;
        if ($platform === null || $catIdx === null) {
            if ($platform) { smmShowCategories($from_id, $message_id, $platform, 0); return; }
            smmClearState($from_id);
            Editmessagetext($from_id, $message_id, "🖥 <b>صفحه دوم | خدمات مجازی</b>\n\nیکی از خدمات زیر را انتخاب کنید:", vsMenuKeyboard(), 'HTML');
            return;
        }
        smmShowServicesTable($from_id, $message_id, $platform, $catIdx, 0, $state['tier_idx'] ?? null);
        return;
    }

    #--------------- دریافت لینک ---------------#
    if ($datain === '' && ($user['step'] ?? '') === 'smm_link') {
        $state = smmState($from_id);
        if (!$state || ($state['step'] ?? '') !== 'await_link') {
            sendmessage($from_id, '❌ این سفارش منقضی شده. لطفاً دوباره از منو شروع کنید.', vsBackToMenuKeyboard(), 'HTML');
            step('home', $from_id);
            return;
        }
        $link = trim($text);
        if ($link === '' || mb_strlen($link) > 490) {
            sendmessage($from_id, '❌ لینک نامعتبر است. لطفاً لینک صحیح را ارسال کنید:', null, 'HTML');
            return;
        }
        $state['link'] = $link;
        $state['step'] = 'await_qty';
        smmSaveState($from_id, $state);
        $service = smmGetService($state['service_id']);
        sendmessage($from_id,
            "🔢 تعداد سفارش را وارد کنید.\n\n📊 حداقل: " . number_format($service['min_amount']) . "\n📈 حداکثر: " . number_format($service['max_amount']),
            null, 'HTML');
        step('smm_qty', $from_id);
        return;
    }

    #--------------- دریافت تعداد + پیش‌فاکتور ---------------#
    if ($datain === '' && ($user['step'] ?? '') === 'smm_qty') {
        $state = smmState($from_id);
        if (!$state || ($state['step'] ?? '') !== 'await_qty') {
            sendmessage($from_id, '❌ این سفارش منقضی شده. لطفاً دوباره از منو شروع کنید.', vsBackToMenuKeyboard(), 'HTML');
            step('home', $from_id);
            return;
        }
        $service = smmGetService($state['service_id']);
        if (!$service || !$service['enabled']) {
            sendmessage($from_id, '❌ این سرویس دیگر در دسترس نیست.', vsBackToMenuKeyboard(), 'HTML');
            smmClearState($from_id);
            step('home', $from_id);
            return;
        }
        $qty = intval(preg_replace('/[^0-9]/', '', $text));
        if ($qty < intval($service['min_amount']) || $qty > intval($service['max_amount'])) {
            sendmessage($from_id, "❌ تعداد باید بین " . number_format($service['min_amount']) . " تا " . number_format($service['max_amount']) . " باشد. دوباره ارسال کنید:", null, 'HTML');
            return;
        }
        $price = smmCalcPrice($service, $qty);
        if (!$price['ok']) {
            sendmessage($from_id, smmPriceUnavailableText(), vsBackToMenuKeyboard(), 'HTML');
            smmClearState($from_id);
            step('home', $from_id);
            return;
        }
        $state['quantity'] = $qty;
        $state['step'] = 'confirm';
        smmSaveState($from_id, $state);
        $kb = json_encode(['inline_keyboard' => [
            [['text' => '✅ تایید و پرداخت', 'callback_data' => 'smmconfirm', 'style' => 'success']],
            [['text' => '❌ انصراف', 'callback_data' => 'smmback', 'style' => 'danger']],
        ]], JSON_UNESCAPED_UNICODE);
        sendmessage($from_id,
            "🧾 <b>پیش‌فاکتور</b>\n\n"
            . "🌐 پلتفرم: " . smmPlatformLabel($service['platform']) . "\n"
            . "📦 سرویس: " . htmlspecialchars($service['name']) . "\n"
            . "🔗 لینک: " . htmlspecialchars($state['link']) . "\n"
            . "🔢 تعداد: " . number_format($qty) . "\n"
            . "💰 مبلغ قابل پرداخت: " . number_format($price['user_price']) . " تومان\n\n"
            . "در صورت تایید، مبلغ از کیف پول شما کسر خواهد شد.",
            $kb, 'HTML');
        step('smm_confirm', $from_id);
        return;
    }

    #--------------- تایید و ثبت نهایی سفارش ---------------#
    if ($datain === 'smmconfirm') {
        smmFinalizePurchase($from_id, $username, $message_id);
        return;
    }

    #--------------- استعلام وضعیت / گارانتی / لغو ---------------#
    if (preg_match('/^smmstatus_(\d+)$/', $datain, $m)) {
        smmCheckStatus($from_id, $message_id, intval($m[1]));
        return;
    }
    if (preg_match('/^smmrefill_(\d+)$/', $datain, $m)) {
        smmRequestRefill($from_id, $message_id, intval($m[1]));
        return;
    }
    if (preg_match('/^smmcancelorder_(\d+)$/', $datain, $m)) {
        smmRequestCancel($from_id, $message_id, intval($m[1]));
        return;
    }
}

#-----------------[ نمایش صفحه‌بندی‌شده‌ی سرویس‌ها ]-------------------#
#-----------------[ نمایش لیست دسته‌ها (زیرمجموعه‌های واقعیِ category در همان پلتفرم) ]-------------------#
function smmCategoryCounts($platform)
{
    global $pdo;
    $stmt = $pdo->prepare("SELECT category FROM smm_services WHERE platform = ? AND enabled = 1");
    $stmt->execute([$platform]);
    $counts = [];
    foreach ($stmt->fetchAll() as $row) {
        $cat = trim((string) ($row['category'] ?? ''));
        $cat = $cat === '' ? 'سایر خدمات' : $cat;
        $counts[$cat] = ($counts[$cat] ?? 0) + 1;
    }
    ksort($counts, SORT_STRING | SORT_FLAG_CASE);
    return $counts;
}

function smmShowCategories($from_id, $message_id, $platform, $page)
{
    $counts = smmCategoryCounts($platform);
    if (!$counts) {
        Editmessagetext($from_id, $message_id, '⚠️ در حال حاضر هیچ سرویس فعالی برای ' . smmPlatformLabel($platform) . ' موجود نیست. لطفاً بعداً مراجعه کنید.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }
    $categories = array_keys($counts);

    // اگر فقط یک دسته وجود دارد، تپ اضافه لازم نیست؛ مستقیم سراغ همان دسته می‌رویم
    // (که خودش هم اگر چند زیرگروه/تعرفه داشت، لایه‌ی انتخاب زیرگروه را نشان می‌دهد).
    if (count($categories) === 1) {
        smmSaveState($from_id, ['step' => 'categories', 'platform' => $platform, 'categories' => $categories]);
        smmSelectCategory($from_id, $message_id, $platform, 0);
        return;
    }

    smmSaveState($from_id, ['step' => 'categories', 'platform' => $platform, 'categories' => $categories]);
    $labelFn = function ($cat) use ($counts) { return '🔹 ' . $cat . ' (' . $counts[$cat] . ')'; };
    $kb = vnPaginatedKeyboard($categories, $page, SMM_PER_PAGE, $labelFn, "smmcatidx_{$platform}_", "smmcatpg_{$platform}_", 'smmback');
    Editmessagetext($from_id, $message_id, "🌐 <b>خدمات " . smmPlatformLabel($platform) . "</b>\n\nیک دسته را انتخاب کنید:", $kb, 'HTML');
}

// اگر داخل این دسته چند زیرگروه (اولترا/اقتصادی/پرمیوم/...) قابل تشخیص باشد، اول
// لیست زیرگروه‌ها نمایش داده می‌شود؛ اگر فقط یک زیرگروه وجود داشته باشد (یا هیچ‌کدام
// از سرویس‌ها زیرگروه شناخته‌شده‌ای نداشته باشند)، دقیقا مثل قبل مستقیم لیست کامل
// سرویس‌های دسته نمایش داده می‌شود — تپ اضافه‌ای به کاربر تحمیل نمی‌شود.
function smmSelectCategory($from_id, $message_id, $platform, $idx)
{
    $state = smmState($from_id);
    $categories = $state['categories'] ?? null;
    if (!$categories || !isset($categories[$idx])) {
        smmShowCategories($from_id, $message_id, $platform, 0);
        return;
    }
    $category = $categories[$idx];
    $ids = smmServiceIdsForCategory($platform, $category);
    if (!$ids) {
        Editmessagetext($from_id, $message_id, '⚠️ سرویسی در این دسته موجود نیست.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }

    $groups = smmGroupServicesByTier($ids);
    if (count($groups) <= 1) {
        smmShowServicesTable($from_id, $message_id, $platform, $idx, 0);
        return;
    }

    $state['step'] = 'tiers';
    $state['platform'] = $platform;
    $state['cat_idx'] = $idx;
    $state['tier_groups'] = $groups;
    smmSaveState($from_id, $state);

    smmShowTiers($from_id, $message_id, $platform, $idx, 0);
}

// نمایش لیست زیرگروه‌های تشخیص‌داده‌شده‌ی یک دسته (مثلا «🔹 اولترا (11)» / «🔹 اقتصادی (2)»)
function smmShowTiers($from_id, $message_id, $platform, $catIdx, $page)
{
    $state = smmState($from_id);
    $groups = $state['tier_groups'] ?? null;
    $category = $state['categories'][$catIdx] ?? '';
    if (!$groups) {
        // state گم شده (مثلا بعد از مدت طولانی) → دوباره از انتخاب دسته بساز
        smmSelectCategory($from_id, $message_id, $platform, $catIdx);
        return;
    }

    $indexes = array_keys($groups);
    $labelFn = function ($i) use ($groups) {
        return '🔹 ' . $groups[$i]['label'] . ' (' . count($groups[$i]['ids']) . ')';
    };
    $kb = vnPaginatedKeyboard($indexes, $page, SMM_PER_PAGE, $labelFn, "smmtieridx_{$platform}_{$catIdx}_", "smmtierpg_{$platform}_{$catIdx}_", 'smmbackcats');
    Editmessagetext($from_id, $message_id, "🌐 " . smmPlatformLabel($platform) . " — 🔹 " . htmlspecialchars($category) . "\n\nیک زیرگروه را انتخاب کنید:", $kb, 'HTML');
}

function smmSelectTier($from_id, $message_id, $platform, $catIdx, $tierIdx)
{
    $state = smmState($from_id);
    $groups = $state['tier_groups'] ?? null;
    if (!$groups || !isset($groups[$tierIdx])) {
        smmShowTiers($from_id, $message_id, $platform, $catIdx, 0);
        return;
    }
    smmShowServicesTable($from_id, $message_id, $platform, $catIdx, 0, $tierIdx);
}

#-----------------[ سرویس‌های یک دسته ]-------------------#
function smmServiceIdsForCategory($platform, $category)
{
    global $pdo;
    if ($category === 'سایر خدمات') {
        $stmt = $pdo->prepare("SELECT service_id FROM smm_services WHERE platform=? AND enabled=1 AND (category IS NULL OR TRIM(category)='') ORDER BY name ASC");
        $stmt->execute([$platform]);
    } else {
        $stmt = $pdo->prepare("SELECT service_id FROM smm_services WHERE platform=? AND enabled=1 AND category=? ORDER BY name ASC");
        $stmt->execute([$platform, $category]);
    }
    return array_column($stmt->fetchAll(), 'service_id');
}

#-----------------[ تشخیص خودکار «زیرگروه/تعرفه» از روی متن واقعیِ نام سرویس ]-------------------#
// دقیقا مثل smmDetectPlatform (حدس زدن از روی محتوای واقعی، نه Service ID)، وقتی یک
// دسته (مثلا «ویو تلگرام») چند تعرفه‌ی مختلف دارد (اولترا/اقتصادی/پرمیوم/...)، این
// کلمات از روی نام سرویس تشخیص داده می‌شوند تا سرویس‌ها زیرِ همان زیرگروه دسته‌بندی
// شوند. اگر بعدا با کلمه‌ی جدیدی در نام سرویس‌های واقعیِ خودتان مواجه شدید (مثلا
// «هایسپید»)، کافیست یک سطر به همین آرایه اضافه کنید — اولویت تشخیص از بالا به
// پایین است (اولین کلمه‌ای که در نام پیدا شود همان زیرگروه انتخاب می‌شود).
function smmTierKeywordMap()
{
    return [
        'اولترا'  => ['اولترا', 'ultra'],
        'پرمیوم'  => ['پرمیوم', 'premium'],
        'VIP'     => ['vip', 'وی ای پی', 'وی‌ای‌پی'],
        'اقتصادی' => ['اقتصادی', 'ارزان', 'economic', 'cheap'],
        'معمولی'  => ['معمولی', 'استاندارد', 'standard', 'normal'],
        'واقعی'   => ['واقعی', 'ریل', 'real'],
        'فست'     => ['فست', 'سریع', 'fast', 'instant'],
        'میکس'    => ['میکس', 'mix'],
    ];
}

function smmDetectTier($name)
{
    $hay = mb_strtolower((string) $name, 'UTF-8');
    if ($hay === '') return null;
    foreach (smmTierKeywordMap() as $label => $keywords) {
        foreach ($keywords as $kw) {
            if (mb_strpos($hay, mb_strtolower($kw, 'UTF-8')) !== false) {
                return $label;
            }
        }
    }
    return null; // هیچ کلمه‌ی شناخته‌شده‌ای در نام نبود → زیرگروه «سایر»
}

// گروه‌بندی سرویس‌های یک دسته بر اساس زیرگروه تشخیص‌داده‌شده. خروجی لیستی است از
// ['label'=>..., 'ids'=>[...]] که فقط زیرگروه‌های واقعا موجود را برمی‌گرداند (اگر
// همه‌ی سرویس‌های یک دسته زیرگروه یکسان یا نامشخص داشته باشند، فقط یک آیتم برمی‌گردد
// و در آن حالت لایه‌ی انتخاب زیرگروه اصلا نمایش داده نمی‌شود، دقیقا مثل منطق «اگر
// فقط یک دسته وجود دارد» در smmShowCategories).
function smmGroupServicesByTier(array $ids)
{
    $buckets = [];
    foreach (array_keys(smmTierKeywordMap()) as $label) $buckets[$label] = [];
    $buckets['سایر'] = [];

    foreach ($ids as $sid) {
        $service = smmGetService($sid);
        if (!$service) continue;
        $tier = smmDetectTier($service['name']);
        $buckets[$tier !== null ? $tier : 'سایر'][] = $sid;
    }

    $groups = [];
    foreach ($buckets as $label => $groupIds) {
        if ($groupIds) $groups[] = ['label' => $label, 'ids' => $groupIds];
    }
    return array_values($groups);
}

// جدول سرویس‌ها: هر سرویس یک دکمه‌ی تمام‌عرض (نام کامل + قیمت لحظه‌ای برای حداقل
// تعداد). قبلا نام و قیمت در دو ستون کنار هم بودند که برای نام‌های طولانی باعث
// بریده‌شدن شدید متن می‌شد؛ حالا با تمام عرض ردیف در اختیار نام است، فقط اگر
// نام واقعا از حد معمول یک خط طولانی‌تر باشد در انتها با «…» کوتاه می‌شود.
// اگر $tierIdx مقدار داشته باشد یعنی این جدول برای یک زیرگروه (اولترا/اقتصادی/...)
// داخل یک دسته است؛ در آن حالت پیشوند کال‌بک‌ها و دکمه‌ی بازگشت فرق می‌کنند تا
// کاربر به لیست زیرگروه‌ها برگردد، نه مستقیم به لیست دسته‌ها.
function smmServicesTableKeyboard(array $ids, $page, $perPage, $platform, $catIdx, $tierIdx = null)
{
    $total = count($ids);
    $totalPages = max(1, (int) ceil($total / $perPage));
    $page = max(0, min($page, $totalPages - 1));
    $start = $page * $perPage;
    $slice = array_slice($ids, $start, $perPage, true);

    $svcPrefix = $tierIdx !== null ? "smmtiersvcidx_{$platform}_{$catIdx}_{$tierIdx}_" : "smmsvcidx_{$platform}_{$catIdx}_";
    $pgPrefix  = $tierIdx !== null ? "smmtiersvcpg_{$platform}_{$catIdx}_{$tierIdx}_"  : "smmsvcpg_{$platform}_{$catIdx}_";

    $rows = [];

    foreach ($slice as $realIdx => $sid) {
        $service = smmGetService($sid);
        if (!$service) continue;
        $sample = smmCalcPrice($service, max(1, intval($service['min_amount'])));
        $priceLabel = $sample['ok'] ? (number_format($sample['user_price']) . ' ت') : 'نامشخص';
        // فقط اگر نام واقعا خیلی بلند بود (بیشتر از ۶۰ کاراکتر) کوتاه می‌شود؛ در غیر
        // این‌صورت نام کامل نمایش داده می‌شود (جزئیات کامل هم با تپ روی دکمه در صفحه‌ی
        // بعد قابل مشاهده است).
        $name = mb_strimwidth($service['name'], 0, 60, '…');
        $cb = $svcPrefix . $realIdx;
        $rows[] = [
            ['text' => "{$name} — {$priceLabel}", 'callback_data' => $cb, 'style' => 'primary'],
        ];
    }

    $navRow = [];
    if ($page > 0) $navRow[] = ['text' => '◀️ قبلی', 'callback_data' => $pgPrefix . ($page - 1)];
    $navRow[] = ['text' => 'صفحه ' . ($page + 1) . ' از ' . $totalPages, 'callback_data' => 'smmnoop'];
    if ($page + 1 < $totalPages) $navRow[] = ['text' => 'بعدی ▶️', 'callback_data' => $pgPrefix . ($page + 1)];
    $rows[] = $navRow;

    if ($tierIdx !== null) {
        $rows[] = [['text' => '🔙 بازگشت به زیرگروه‌ها', 'callback_data' => "smmbacktiers_{$platform}_{$catIdx}"]];
    } else {
        $rows[] = [['text' => '🔙 بازگشت به دسته‌ها', 'callback_data' => 'smmbackcats']];
    }

    return json_encode(['inline_keyboard' => $rows], JSON_UNESCAPED_UNICODE);
}

// اگر $tierIdx مقدار داشته باشد، لیست سرویس‌ها از همان زیرگروهِ ذخیره‌شده در
// state['tier_groups'] گرفته می‌شود؛ در غیر این‌صورت (حالت قبلی/بدون زیرگروه) همه‌ی
// سرویس‌های دسته مستقیم از دیتابیس خوانده می‌شوند.
function smmShowServicesTable($from_id, $message_id, $platform, $catIdx, $page, $tierIdx = null)
{
    $state = smmState($from_id);
    $categories = $state['categories'] ?? null;
    if (!$categories) {
        $counts = smmCategoryCounts($platform);
        $categories = array_keys($counts);
        $state = ['step' => 'categories', 'platform' => $platform, 'categories' => $categories];
    }
    $category = $categories[$catIdx] ?? null;
    if ($category === null) {
        smmShowCategories($from_id, $message_id, $platform, 0);
        return;
    }

    $tierLabel = null;
    if ($tierIdx !== null) {
        $groups = $state['tier_groups'] ?? null;
        if (!$groups || !isset($groups[$tierIdx])) {
            // زیرگروه‌ها گم شده‌اند (مثلا کاربر بعد از مدت زیادی برگشته) → از اول بساز
            smmSelectCategory($from_id, $message_id, $platform, $catIdx);
            return;
        }
        $ids = $groups[$tierIdx]['ids'];
        $tierLabel = $groups[$tierIdx]['label'];
    } else {
        $ids = smmServiceIdsForCategory($platform, $category);
    }

    if (!$ids) {
        Editmessagetext($from_id, $message_id, '⚠️ سرویسی در این دسته موجود نیست.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }

    $state['step'] = 'services';
    $state['platform'] = $platform;
    $state['cat_idx'] = $catIdx;
    $state['tier_idx'] = $tierIdx;
    $state['service_ids'] = $ids;
    smmSaveState($from_id, $state);

    $kb = smmServicesTableKeyboard($ids, $page, SMM_PER_PAGE, $platform, $catIdx, $tierIdx);
    $headerLine = "🌐 " . smmPlatformLabel($platform) . " — 🔹 " . htmlspecialchars($category);
    if ($tierLabel !== null) $headerLine .= " — 🏷 " . htmlspecialchars($tierLabel);
    Editmessagetext($from_id, $message_id, $headerLine . "\n\nیک سرویس را انتخاب کنید (قیمت مقابل هر سرویس برای حداقل تعداد است):", $kb, 'HTML');
}

function smmSelectService($from_id, $message_id, $platform, $catIdx, $idx)
{
    $state = smmState($from_id);
    $ids = $state['service_ids'] ?? null;
    if (!$ids || !isset($ids[$idx])) {
        smmShowServicesTable($from_id, $message_id, $platform, $catIdx, 0, $state['tier_idx'] ?? null);
        return;
    }
    $serviceId = $ids[$idx];
    $service = smmGetService($serviceId);
    if (!$service || !$service['enabled']) {
        Editmessagetext($from_id, $message_id, '❌ این سرویس دیگر در دسترس نیست.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }

    $sample = smmCalcPrice($service, max(1, intval($service['min_amount'])));
    $priceLine = $sample['ok']
        ? ('💰 قیمت برای حداقل تعداد (' . number_format($service['min_amount']) . '): ' . number_format($sample['user_price']) . ' تومان')
        : '💰 قیمت: در حال حاضر قابل محاسبه نیست (نرخ دلار تنظیم نشده)';

    $text = "📦 <b>سرویس: " . htmlspecialchars($service['name']) . "</b>\n\n"
        . "📊 حداقل سفارش: " . number_format($service['min_amount']) . "\n"
        . "📈 حداکثر سفارش: " . number_format($service['max_amount']) . "\n"
        . $priceLine . "\n"
        . "🔄 گارانتی (Refill): " . ($service['refill'] ? 'دارد' : 'ندارد') . "\n"
        . "❌ امکان لغو: " . ($service['cancel'] ? 'دارد' : 'ندارد') . "\n\n"
        . "🔗 لطفاً لینک/آیدی مقصد را ارسال کنید:";

    $state['service_id'] = $serviceId;
    $state['platform'] = $platform;
    $state['cat_idx'] = $catIdx;
    $state['step'] = 'await_link';
    smmSaveState($from_id, $state);

    $kb = json_encode(['inline_keyboard' => [[['text' => '🔙 بازگشت به لیست سرویس‌ها', 'callback_data' => 'smmbacksvc']]]], JSON_UNESCAPED_UNICODE);
    Editmessagetext($from_id, $message_id, $text, $kb, 'HTML');
    step('smm_link', $from_id);
}

#-----------------[ کسر از کیف‌پول + ثبت سفارش واقعی نزد API ]-------------------#
function smmFinalizePurchase($from_id, $username, $message_id)
{
    $state = smmState($from_id);
    if (!$state || ($state['step'] ?? '') !== 'confirm') {
        Editmessagetext($from_id, $message_id, '❌ این سفارش منقضی شده. لطفاً دوباره از منو شروع کنید.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }
    $service = smmGetService($state['service_id']);
    if (!$service || !$service['enabled']) {
        Editmessagetext($from_id, $message_id, '❌ این سرویس دیگر در دسترس نیست.', vsBackToMenuKeyboard(), 'HTML');
        smmClearState($from_id);
        return;
    }
    $qty = intval($state['quantity']);
    $link = $state['link'];
    $price = smmCalcPrice($service, $qty);
    if (!$price['ok']) {
        Editmessagetext($from_id, $message_id, smmPriceUnavailableText(), vsBackToMenuKeyboard(), 'HTML');
        smmClearState($from_id);
        return;
    }

    $balance = intval(select('user', 'Balance', 'id', $from_id)['Balance'] ?? 0);
    if ($balance < $price['user_price']) {
        Editmessagetext($from_id, $message_id,
            "❌ موجودی کیف پول شما کافی نیست.\n\n💰 موجودی فعلی: " . number_format($balance) . " تومان\n💳 مبلغ مورد نیاز: " . number_format($price['user_price']) . " تومان",
            vsBackToMenuKeyboard(), 'HTML');
        smmClearState($from_id);
        return;
    }

    // کسر موجودی → ثبت سفارش نزد API → در صورت شکست، بازگشت کامل وجه (طبق درخواست:
    // «سفارش به عنوان موفق ثبت نشود و مبلغ کاربر بدون ثبت سفارش نهایی نشود»)
    update('user', 'Balance', (string) ($balance - $price['user_price']), 'id', $from_id);

    $res = smmClient()->addOrder($service['service_id'], $link, $qty);

    if (!$res['ok']) {
        update('user', 'Balance', (string) $balance, 'id', $from_id);
        if (function_exists('vsSendGroupError')) {
            vsSendGroupError("⚠️ <b>خطای ثبت سفارش خدمات " . smmPlatformLabel($service['platform']) . "</b>\n\n👤 کاربر: <a href=\"tg://user?id={$from_id}\">{$from_id}</a>\n📦 سرویس: " . htmlspecialchars($service['name']) . " (#{$service['service_id']})\n🔢 تعداد: {$qty}\n❌ نوع خطا: " . htmlspecialchars((string) ($res['error_type'] ?? 'unknown')) . (isset($res['error_detail']) ? ("\nجزئیات: " . htmlspecialchars((string) $res['error_detail'])) : '') . "\n💰 مبلغ (بازگشت داده شد): " . number_format($price['user_price']) . ' تومان');
        }
        Editmessagetext($from_id, $message_id, "❌ متاسفانه ثبت سفارش با خطا مواجه شد و مبلغ به کیف پول شما بازگردانده شد.\n\nلطفاً بعداً دوباره تلاش کنید یا با پشتیبانی در تماس باشید.", vsBackToMenuKeyboard(), 'HTML');
        smmClearState($from_id);
        return;
    }

    $apiOrderId = $res['data']['order'] ?? null;
    if (!$apiOrderId) {
        update('user', 'Balance', (string) $balance, 'id', $from_id);
        if (function_exists('vsSendGroupError')) {
            vsSendGroupError("⚠️ <b>پاسخ نامعتبر از API هنگام ثبت سفارش خدمات " . smmPlatformLabel($service['platform']) . "</b>\n\n👤 کاربر: <a href=\"tg://user?id={$from_id}\">{$from_id}</a>\n📦 سرویس: " . htmlspecialchars($service['name']) . "\n💰 مبلغ (بازگشت داده شد): " . number_format($price['user_price']) . ' تومان');
        }
        Editmessagetext($from_id, $message_id, "❌ پاسخ نامعتبر از سرویس‌دهنده دریافت شد. مبلغ به کیف پول شما بازگردانده شد.", vsBackToMenuKeyboard(), 'HTML');
        smmClearState($from_id);
        return;
    }

    $orderId = smmCreateOrder($from_id, $username, $service, $link, $qty, $apiOrderId, $price);
    smmClearState($from_id);

    $kb = smmOrderActionsKeyboard($orderId, $service);
    Editmessagetext($from_id, $message_id,
        "✅ <b>سفارش با موفقیت ثبت شد</b>\n\n"
        . "📦 سرویس: " . htmlspecialchars($service['name']) . "\n"
        . "🔗 لینک: " . htmlspecialchars($link) . "\n"
        . "🔢 تعداد: " . number_format($qty) . "\n"
        . "💰 مبلغ: " . number_format($price['user_price']) . " تومان\n"
        . "🆔 شماره سفارش: #{$orderId}",
        $kb, 'HTML');
}

function smmOrderActionsKeyboard($orderId, $service)
{
    $rows = [];
    $rows[] = [['text' => '🔄 استعلام وضعیت', 'callback_data' => 'smmstatus_' . $orderId]];
    if (!empty($service['refill'])) {
        $rows[] = [['text' => '🔁 درخواست گارانتی (Refill)', 'callback_data' => 'smmrefill_' . $orderId]];
    }
    if (!empty($service['cancel'])) {
        $rows[] = [['text' => '❌ لغو سفارش', 'callback_data' => 'smmcancelorder_' . $orderId, 'style' => 'danger']];
    }
    $rows[] = [['text' => '🔙 بازگشت به منو', 'callback_data' => 'smmback']];
    return json_encode(['inline_keyboard' => $rows], JSON_UNESCAPED_UNICODE);
}

#-----------------[ ثبت سفارش در دیتابیس + گزارش (فوری، چون تحویل خودکار توسط API است) ]-------------------#
function smmCreateOrder($from_id, $username, $service, $link, $qty, $apiOrderId, $price)
{
    global $pdo;
    smmEnsureTables();

    $stmt = $pdo->prepare("INSERT INTO smm_orders
        (user_id, username, platform, service_id, service_name, link, quantity, api_order_id, amount_paid, api_cost, profit, status, created_at)
        VALUES (:u,:un,:plat,:sid,:sname,:link,:qty,:aoid,:paid,:cost,:profit,'pending', NOW())");
    $stmt->execute([
        'u' => $from_id, 'un' => $username, 'plat' => $service['platform'], 'sid' => $service['service_id'],
        'sname' => $service['name'], 'link' => $link, 'qty' => $qty, 'aoid' => $apiOrderId,
        'paid' => $price['user_price'], 'cost' => $price['api_cost_toman'], 'profit' => $price['profit'],
    ]);
    $orderId = $pdo->lastInsertId();

    // این خدمات به‌صورت خودکار توسط API انجام می‌شوند (برخلاف Stars/Premium/Gift که
    // دستی توسط ادمین انجام می‌شود)؛ بنابراین گزارشِ کانال عمومی همینجا و بلافاصله
    // ارسال می‌شود — دقیقا هم‌راستا با رفتار فعلی ماژول «شماره مجازی».
    if (function_exists('sendMemberOrderReportChannel')) {
        $timejalali = function_exists('jdate') ? jdate('Y/m/d H:i') : date('Y-m-d H:i');
        sendMemberOrderReportChannel(
            $service['name'],
            (string) $qty,
            '-',
            number_format($price['user_price']) . ' تومان',
            $timejalali,
            $from_id,
            smmPlatformLabel($service['platform'])
        );
    }

    if (function_exists('vsSendGroupReport')) {
        $adminText = "🆕 <b>سفارش جدید خدمات " . smmPlatformLabel($service['platform']) . "</b>\n\n"
            . "👤 کاربر: <a href=\"tg://user?id={$from_id}\">{$from_id}</a>\n"
            . "📦 سرویس: " . htmlspecialchars($service['name']) . " (#{$service['service_id']})\n"
            . "🔗 لینک: " . htmlspecialchars($link) . "\n"
            . "🔢 تعداد: " . number_format($qty) . "\n"
            . "💰 مبلغ کاربر: " . number_format($price['user_price']) . " تومان\n"
            . "💵 هزینه API: " . number_format($price['api_cost_toman']) . " تومان\n"
            . "📈 سود: " . number_format($price['profit']) . " تومان\n"
            . "🆔 سفارش داخلی: #{$orderId} | 🆔 سفارش API: #{$apiOrderId}";
        vsSendGroupReport($adminText);
    }

    return $orderId;
}

#-----------------[ استعلام وضعیت / گارانتی / لغو ]-------------------#
function smmOrderById($orderId, $from_id)
{
    global $pdo;
    smmEnsureTables();
    $stmt = $pdo->prepare("SELECT * FROM smm_orders WHERE id=? AND user_id=?");
    $stmt->execute([$orderId, $from_id]);
    return $stmt->fetch() ?: null;
}

function smmCheckStatus($from_id, $message_id, $orderId)
{
    global $pdo;
    $order = smmOrderById($orderId, $from_id);
    if (!$order) {
        Editmessagetext($from_id, $message_id, '❌ این سفارش یافت نشد.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }
    $res = smmClient()->status($order['api_order_id']);
    $service = smmGetService($order['service_id']);
    $kb = $service ? smmOrderActionsKeyboard($orderId, $service) : vsBackToMenuKeyboard();

    if (!$res['ok']) {
        if (function_exists('vsSendGroupError')) {
            vsSendGroupError("⚠️ <b>خطای استعلام وضعیت سفارش خدمات مجازی</b>\n\n🆔 سفارش داخلی: #{$orderId} | 🆔 API: #{$order['api_order_id']}\n❌ نوع خطا: " . htmlspecialchars((string) ($res['error_type'] ?? 'unknown')));
        }
        Editmessagetext($from_id, $message_id, "⚠️ در حال حاضر امکان استعلام وضعیت وجود ندارد. بعداً دوباره تلاش کنید.", $kb, 'HTML');
        return;
    }

    $status = $res['status_data'];
    $apiStatus = $status['status'] ?? 'Pending';
    $remains = $status['remains'] ?? null;
    $startCount = $status['start_count'] ?? null;

    $pdo->prepare("UPDATE smm_orders SET status=:st, remains=:rem, start_count=:sc, updated_at=NOW() WHERE id=:id")
        ->execute(['st' => $apiStatus, 'rem' => $remains, 'sc' => $startCount, 'id' => $orderId]);

    $text = "📦 وضعیت سفارش #{$orderId}\n\n"
        . "📌 وضعیت: " . smmStatusLabel($apiStatus) . "\n";
    if ($startCount !== null) $text .= "🔢 تعداد شروع: {$startCount}\n";
    if ($remains !== null) $text .= "⏳ باقی‌مانده: {$remains}\n";

    Editmessagetext($from_id, $message_id, $text, $kb, 'HTML');
}

function smmRequestRefill($from_id, $message_id, $orderId)
{
    global $pdo;
    $order = smmOrderById($orderId, $from_id);
    $service = $order ? smmGetService($order['service_id']) : null;
    if (!$order || !$service || empty($service['refill'])) {
        Editmessagetext($from_id, $message_id, '❌ گارانتی برای این سفارش در دسترس نیست.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }
    $res = smmClient()->refill($order['api_order_id']);
    $kb = smmOrderActionsKeyboard($orderId, $service);
    if (!$res['ok']) {
        if (function_exists('vsSendGroupError')) {
            vsSendGroupError("⚠️ <b>خطای ثبت گارانتی (Refill)</b>\n\n🆔 سفارش داخلی: #{$orderId} | 🆔 API: #{$order['api_order_id']}\n❌ نوع خطا: " . htmlspecialchars((string) ($res['error_type'] ?? 'unknown')));
        }
        Editmessagetext($from_id, $message_id, '⚠️ ثبت درخواست گارانتی با خطا مواجه شد. بعداً دوباره تلاش کنید یا با پشتیبانی تماس بگیرید.', $kb, 'HTML');
        return;
    }
    $refillId = $res['data']['refill'] ?? null;
    if ($refillId) {
        $pdo->prepare("UPDATE smm_orders SET refill_id=:r, refill_status='requested', updated_at=NOW() WHERE id=:id")
            ->execute(['r' => $refillId, 'id' => $orderId]);
    }
    Editmessagetext($from_id, $message_id, "✅ درخواست گارانتی برای سفارش #{$orderId} ثبت شد.\n🆔 شناسه گارانتی: " . ($refillId ?? '-'), $kb, 'HTML');
}

function smmRequestCancel($from_id, $message_id, $orderId)
{
    global $pdo;
    $order = smmOrderById($orderId, $from_id);
    $service = $order ? smmGetService($order['service_id']) : null;
    if (!$order || !$service || empty($service['cancel'])) {
        Editmessagetext($from_id, $message_id, '❌ لغو برای این سفارش در دسترس نیست.', vsBackToMenuKeyboard(), 'HTML');
        return;
    }
    $res = smmClient()->cancel($order['api_order_id']);
    if (!$res['ok']) {
        if (function_exists('vsSendGroupError')) {
            vsSendGroupError("⚠️ <b>خطای لغو سفارش خدمات مجازی</b>\n\n🆔 سفارش داخلی: #{$orderId} | 🆔 API: #{$order['api_order_id']}\n❌ نوع خطا: " . htmlspecialchars((string) ($res['error_type'] ?? 'unknown')));
        }
        Editmessagetext($from_id, $message_id, '⚠️ لغو سفارش با خطا مواجه شد. بعداً دوباره تلاش کنید یا با پشتیبانی تماس بگیرید.', smmOrderActionsKeyboard($orderId, $service), 'HTML');
        return;
    }
    $pdo->prepare("UPDATE smm_orders SET status='cancel_requested', updated_at=NOW() WHERE id=:id")->execute(['id' => $orderId]);
    Editmessagetext($from_id, $message_id, "✅ درخواست لغو سفارش #{$orderId} ثبت شد.", vsBackToMenuKeyboard(), 'HTML');
}

#################################################################
#                     پنل مدیریت (سمت ادمین)                     #
#################################################################

function smmAdminKeyboard()
{
    return json_encode([
        'keyboard' => [
            [['text' => '🔑 تنظیم API Key'], ['text' => '🌐 آدرس API']],
            [['text' => '🔁 همگام‌سازی سرویس‌ها از API'], ['text' => '💰 موجودی API']],
            [['text' => '🗂 مدیریت سرویس‌ها']],
            [['text' => '📈 درصد سود تلگرام'], ['text' => '📈 درصد سود اینستاگرام']],
            [['text' => '⚙️ فعال/غیرفعال تلگرام'], ['text' => '⚙️ فعال/غیرفعال اینستاگرام']],
            [['text' => '🧾 آخرین سفارش‌ها']],
            [['text' => '🔙 بازگشت به پنل خدمات مجازی']],
        ],
        'resize_keyboard' => true,
    ]);
}

function smmAdminShouldHandle()
{
    global $text, $datain, $user, $admin_ids, $from_id;
    if (!in_array($from_id, $admin_ids ?? [])) return false;
    if ($text === SMM_ADMIN_BUTTON_TEXT) return true;
    if (is_string($datain) && strpos($datain, 'smmadmin') === 0) return true;
    $step = $user['step'] ?? '';
    if (is_string($step) && strpos($step, 'smmadmin_') === 0) return true;
    $texts = ['🔑 تنظیم API Key', '🌐 آدرس API', '🔁 همگام‌سازی سرویس‌ها از API', '💰 موجودی API', '🗂 مدیریت سرویس‌ها', '📈 درصد سود تلگرام', '📈 درصد سود اینستاگرام', '⚙️ فعال/غیرفعال تلگرام', '⚙️ فعال/غیرفعال اینستاگرام', '🧾 آخرین سفارش‌ها', '🔙 بازگشت به پنل خدمات مجازی'];
    if (in_array($text, $texts, true)) return true;
    return false;
}

function smmAdminDispatch()
{
    global $text, $datain, $from_id, $message_id, $user, $pdo, $vsAdminKeyboard;

    smmEnsureTables();

    if ($text === SMM_ADMIN_BUTTON_TEXT) {
        sendmessage($from_id, "📡 <b>تنظیمات خدمات تلگرام/اینستاگرام (apiaddress.com)</b>\n\n"
            . "تلگرام: " . (smmSetting('smm_enabled_telegram', '1') === '1' ? 'فعال ✅' : 'غیرفعال ❌') . "\n"
            . "اینستاگرام: " . (smmSetting('smm_enabled_instagram', '1') === '1' ? 'فعال ✅' : 'غیرفعال ❌') . "\n"
            . "آخرین همگام‌سازی: " . (intval(smmSetting('smm_last_sync_at', 0)) > 0 ? date('Y-m-d H:i', intval(smmSetting('smm_last_sync_at'))) . ' (' . smmSetting('smm_last_sync_count', 0) . ' سرویس)' : 'هنوز انجام نشده'),
            smmAdminKeyboard(), 'HTML');
        step('home', $from_id);
        return;
    }
    if ($text === '🔙 بازگشت به پنل خدمات مجازی') {
        sendmessage($from_id, '🔙 بازگشت به پنل خدمات مجازی.', $vsAdminKeyboard, 'HTML');
        step('home', $from_id);
        return;
    }

    #--- API Key ---#
    if ($text === '🔑 تنظیم API Key') {
        $has = trim((string) smmSetting('smm_api_key', '')) !== '' || trim((string) (isset($GLOBALS['smm_api_key']) ? $GLOBALS['smm_api_key'] : '')) !== '';
        sendmessage($from_id, ($has ? '✅ کلید قبلاً تنظیم شده است.' : '⚠️ هنوز کلیدی تنظیم نشده است.') . "\n\nAPI Key جدید apiaddress.com را ارسال کنید:\n\n<i>پیشنهاد می‌شود بعد از ثبت، همین پیام حاوی کلید را از چت پاک کنید.</i>", null, 'HTML');
        step('smmadmin_setkey', $from_id);
        return;
    }
    if ($datain === '' && ($user['step'] ?? '') === 'smmadmin_setkey') {
        $val = trim($text);
        if ($val === '') {
            sendmessage($from_id, 'کلید نمی‌تواند خالی باشد.', smmAdminKeyboard(), 'HTML');
            step('home', $from_id);
            return;
        }
        smmSetSetting('smm_api_key', $val);
        sendmessage($from_id, '✅ API Key با موفقیت و به‌صورت امن در تنظیمات دیتابیس ذخیره شد (نه داخل کد).', smmAdminKeyboard(), 'HTML');
        step('home', $from_id);
        return;
    }

    #--- آدرس API ---#
    if ($text === '🌐 آدرس API') {
        $cur = smmApiUrl();
        sendmessage($from_id, "آدرس فعلی: <code>" . htmlspecialchars($cur ?: '(تنظیم نشده)') . "</code>\n\nآدرس جدید Base URL را ارسال کنید (یا عدد 0 برای بازگشت به مقدار پیش‌فرض config.php):", null, 'HTML');
        step('smmadmin_seturl', $from_id);
        return;
    }
    if ($datain === '' && ($user['step'] ?? '') === 'smmadmin_seturl') {
        $val = trim($text);
        smmSetSetting('smm_api_url', $val === '0' ? '' : $val);
        sendmessage($from_id, '✅ آدرس API ذخیره شد.', smmAdminKeyboard(), 'HTML');
        step('home', $from_id);
        return;
    }

    #--- همگام‌سازی سرویس‌ها ---#
    if ($text === '🔁 همگام‌سازی سرویس‌ها از API') {
        $res = smmSyncServices();
        if (!$res['ok']) {
            sendmessage($from_id, '❌ همگام‌سازی ناموفق بود. نوع خطا: ' . htmlspecialchars((string) ($res['error_type'] ?? 'unknown')) . (isset($res['error_detail']) ? ("\nجزئیات: " . htmlspecialchars((string) $res['error_detail'])) : ''), smmAdminKeyboard(), 'HTML');
            return;
        }
        $tgCount = count(smmListServices('telegram', false));
        $igCount = count(smmListServices('instagram', false));
        sendmessage($from_id, "✅ همگام‌سازی انجام شد.\n\n📦 کل سرویس‌های دریافتی از API: {$res['count']}\n📱 شناسایی‌شده به‌عنوان تلگرام: {$tgCount}\n📸 شناسایی‌شده به‌عنوان اینستاگرام: {$igCount}\n\n⚠️ همه‌ی این سرویس‌ها به‌صورت پیش‌فرض غیرفعال هستند. از «🗂 مدیریت سرویس‌ها» هرکدام را که می‌خواهید فعال کنید.", smmAdminKeyboard(), 'HTML');
        return;
    }

    #--- موجودی API ---#
    if ($text === '💰 موجودی API') {
        $res = smmClient()->balance();
        if (!$res['ok']) {
            sendmessage($from_id, '❌ دریافت موجودی ناموفق بود. نوع خطا: ' . htmlspecialchars((string) ($res['error_type'] ?? 'unknown')), smmAdminKeyboard(), 'HTML');
            return;
        }
        $bal = $res['data']['balance'] ?? '?';
        $cur = $res['data']['currency'] ?? '';
        sendmessage($from_id, "💰 موجودی فعلی پنل apiaddress.com:\n\n<b>{$bal} {$cur}</b>", smmAdminKeyboard(), 'HTML');
        return;
    }

    #--- فعال/غیرفعال کل پلتفرم ---#
    if ($text === '⚙️ فعال/غیرفعال تلگرام') {
        $cur = smmSetting('smm_enabled_telegram', '1');
        $new = $cur === '1' ? '0' : '1';
        smmSetSetting('smm_enabled_telegram', $new);
        sendmessage($from_id, 'وضعیت فعلی خدمات تلگرام: ' . ($new === '1' ? 'فعال ✅' : 'غیرفعال ❌'), smmAdminKeyboard(), 'HTML');
        return;
    }
    if ($text === '⚙️ فعال/غیرفعال اینستاگرام') {
        $cur = smmSetting('smm_enabled_instagram', '1');
        $new = $cur === '1' ? '0' : '1';
        smmSetSetting('smm_enabled_instagram', $new);
        sendmessage($from_id, 'وضعیت فعلی خدمات اینستاگرام: ' . ($new === '1' ? 'فعال ✅' : 'غیرفعال ❌'), smmAdminKeyboard(), 'HTML');
        return;
    }

    #--- درصد سود هر پلتفرم ---#
    if ($text === '📈 درصد سود تلگرام') {
        update('user', 'Processing_value', 'smm_profit_telegram', 'id', $from_id);
        sendmessage($from_id, 'درصد سود فعلی تلگرام: ' . smmSetting('smm_profit_telegram', 20) . "%\n\nدرصد سود جدید را عدد ارسال کنید (مثلاً 20):", null, 'HTML');
        step('smmadmin_setprofit', $from_id);
        return;
    }
    if ($text === '📈 درصد سود اینستاگرام') {
        update('user', 'Processing_value', 'smm_profit_instagram', 'id', $from_id);
        sendmessage($from_id, 'درصد سود فعلی اینستاگرام: ' . smmSetting('smm_profit_instagram', 20) . "%\n\nدرصد سود جدید را عدد ارسال کنید (مثلاً 20):", null, 'HTML');
        step('smmadmin_setprofit', $from_id);
        return;
    }
    if ($datain === '' && ($user['step'] ?? '') === 'smmadmin_setprofit') {
        $val = floatval(str_replace(',', '.', trim($text)));
        if ($val < 0) {
            sendmessage($from_id, 'عدد نامعتبر است.', smmAdminKeyboard(), 'HTML');
            step('home', $from_id);
            return;
        }
        smmSetSetting($user['Processing_value'], (string) $val);
        sendmessage($from_id, '✅ درصد سود ذخیره شد.', smmAdminKeyboard(), 'HTML');
        step('home', $from_id);
        return;
    }

    #--- مدیریت سرویس‌ها: انتخاب فیلتر (فقط بر اساس پلتفرم؛ فعال/غیرفعال دیگر دو دکمه‌ی جدا نیست) ---#
    if ($text === '🗂 مدیریت سرویس‌ها' || $datain === 'smmadminback') {
        $kb = json_encode(['inline_keyboard' => [
            [['text' => '📱 تلگرام', 'callback_data' => 'smmadminlist_telegram_0']],
            [['text' => '📸 اینستاگرام', 'callback_data' => 'smmadminlist_instagram_0']],
            [['text' => '❔ نامشخص (نیاز به تعیین پلتفرم)', 'callback_data' => 'smmadminlist_unknown_0']],
        ]], JSON_UNESCAPED_UNICODE);
        if ($datain === 'smmadminback') {
            Editmessagetext($from_id, $message_id, 'کدام دسته از سرویس‌ها را می‌خواهید مدیریت کنید؟', $kb, 'HTML');
        } else {
            sendmessage($from_id, 'کدام دسته از سرویس‌ها را می‌خواهید مدیریت کنید؟', $kb, 'HTML');
        }
        return;
    }
    if (preg_match('/^smmadminlist_(telegram|instagram|unknown)_(\d+)$/', $datain, $m)) {
        smmAdminShowList($from_id, $message_id, $m[1], intval($m[2]));
        return;
    }
    if (preg_match('/^smmadminbulk_(enable|disable)_(telegram|instagram|unknown)$/', $datain, $m)) {
        $where = smmAdminFilterWhere($m[2]);
        $pdo->prepare("UPDATE smm_services SET enabled=? WHERE {$where['sql']}")->execute(array_merge([$m[1] === 'enable' ? 1 : 0], $where['params']));
        smmAdminShowList($from_id, $message_id, $m[2], 0);
        return;
    }
    if (preg_match('/^smmadminsvc_([A-Za-z0-9_\-]+)_(telegram|instagram|unknown)_(\d+)$/', $datain, $m)) {
        smmAdminShowServiceDetail($from_id, $message_id, $m[1], $m[2], intval($m[3]));
        return;
    }
    if (preg_match('/^smmadmintoggle_([A-Za-z0-9_\-]+)_(telegram|instagram|unknown)_(\d+)$/', $datain, $m)) {
        $stmt = $pdo->prepare("SELECT enabled FROM smm_services WHERE service_id=?");
        $stmt->execute([$m[1]]);
        $row = $stmt->fetch();
        if ($row) {
            $pdo->prepare("UPDATE smm_services SET enabled=? WHERE service_id=?")->execute([$row['enabled'] ? 0 : 1, $m[1]]);
        }
        // بعد از تاگل، همان لیست (همان صفحه) دوباره رفرش می‌شود؛ نه صفحه‌ی جزئیات — یعنی
        // ادمین می‌تواند پشت سر هم روی چند سرویس بزند بدون رفت‌وبرگشت به صفحه‌ی جزئیات.
        smmAdminShowList($from_id, $message_id, $m[2], intval($m[3]));
        return;
    }
    if (preg_match('/^smmadmintoggledetail_([A-Za-z0-9_\-]+)_(telegram|instagram|unknown)_(\d+)$/', $datain, $m)) {
        $stmt = $pdo->prepare("SELECT enabled FROM smm_services WHERE service_id=?");
        $stmt->execute([$m[1]]);
        $row = $stmt->fetch();
        if ($row) {
            $pdo->prepare("UPDATE smm_services SET enabled=? WHERE service_id=?")->execute([$row['enabled'] ? 0 : 1, $m[1]]);
        }
        smmAdminShowServiceDetail($from_id, $message_id, $m[1], $m[2], intval($m[3]));
        return;
    }
    if (preg_match('/^smmadminsetplat_([A-Za-z0-9_\-]+)_(telegram|instagram|none)_(telegram|instagram|unknown)_(\d+)$/', $datain, $m)) {
        $newPlatform = $m[2] === 'none' ? null : $m[2];
        $pdo->prepare("UPDATE smm_services SET platform=?, platform_source='manual' WHERE service_id=?")->execute([$newPlatform, $m[1]]);
        smmAdminShowServiceDetail($from_id, $message_id, $m[1], $m[3], intval($m[4]));
        return;
    }
    if (preg_match('/^smmadminsetcat_([A-Za-z0-9_\-]+)_(telegram|instagram|unknown)_(\d+)$/', $datain, $m)) {
        update('user', 'Processing_value', $m[1], 'id', $from_id);
        update('user', 'Processing_value_one', $m[2] . '|' . $m[3], 'id', $from_id);
        Editmessagetext($from_id, $message_id, "✏️ نام دسته (Category) جدید این سرویس را ارسال کنید (برای مثال «ممبر گروه» یا «بوست تلگرام»)؛ این نام همانی است که کاربر در منوی دسته‌ها می‌بیند:", json_encode(['inline_keyboard' => []]));
        step('smmadmin_setcategory', $from_id);
        return;
    }
    if ($datain === '' && ($user['step'] ?? '') === 'smmadmin_setcategory') {
        $serviceId = $user['Processing_value'];
        [$filter, $offset] = explode('|', $user['Processing_value_one']);
        $newCat = trim($text);
        if ($newCat === '') {
            sendmessage($from_id, 'نام دسته نمی‌تواند خالی باشد.', smmAdminKeyboard(), 'HTML');
            step('home', $from_id);
            return;
        }
        $pdo->prepare("UPDATE smm_services SET category=? WHERE service_id=?")->execute([$newCat, $serviceId]);
        sendmessage($from_id, '✅ دسته‌ی سرویس به «' . htmlspecialchars($newCat) . '» تغییر کرد.', smmAdminKeyboard(), 'HTML');
        step('home', $from_id);
        return;
    }

    #--- آخرین سفارش‌ها ---#
    if ($text === '🧾 آخرین سفارش‌ها') {
        $rows = $pdo->query("SELECT * FROM smm_orders ORDER BY id DESC LIMIT 15")->fetchAll();
        if (!$rows) {
            sendmessage($from_id, 'هنوز هیچ سفارشی ثبت نشده است.', smmAdminKeyboard(), 'HTML');
            return;
        }
        $lines = [];
        foreach ($rows as $r) {
            $lines[] = "#{$r['id']} | " . smmPlatformLabel($r['platform']) . " | " . htmlspecialchars($r['service_name']) . " × {$r['quantity']} | " . number_format($r['amount_paid']) . " تومان | " . htmlspecialchars($r['status']);
        }
        sendmessage($from_id, "🧾 <b>۱۵ سفارش آخر:</b>\n\n" . implode("\n", $lines), smmAdminKeyboard(), 'HTML');
        return;
    }
}

#-----------------[ کمکی: نمایش لیست سرویس‌ها بر اساس فیلتر (پلتفرم)، با تاگل مستقیم و Bulk ]-------------------#
function smmAdminFilterWhere($filter)
{
    if ($filter === 'unknown') {
        return ['sql' => 'platform IS NULL', 'params' => []];
    }
    return ['sql' => 'platform = ?', 'params' => [$filter]];
}

function smmAdminFilterLabel($filter)
{
    if ($filter === 'unknown') return '❔ نامشخص';
    return smmPlatformLabel($filter);
}

function smmAdminShowList($from_id, $message_id, $filter, $offset)
{
    global $pdo;
    $where = smmAdminFilterWhere($filter);
    $perPage = 10;

    $countStmt = $pdo->prepare("SELECT COUNT(*) c, SUM(enabled) e FROM smm_services WHERE {$where['sql']}");
    $countStmt->execute($where['params']);
    $countRow = $countStmt->fetch();
    $total = intval($countRow['c'] ?? 0);
    $enabledCount = intval($countRow['e'] ?? 0);

    if ($total === 0) {
        Editmessagetext($from_id, $message_id, 'هیچ سرویسی در این دسته پیدا نشد. ابتدا از «🔁 همگام‌سازی سرویس‌ها از API» استفاده کنید.', json_encode(['inline_keyboard' => [[['text' => '🔙 بازگشت', 'callback_data' => 'smmadminback']]]], JSON_UNESCAPED_UNICODE), 'HTML');
        return;
    }

    $stmt = $pdo->prepare("SELECT service_id, name, category, enabled FROM smm_services WHERE {$where['sql']} ORDER BY name ASC LIMIT {$perPage} OFFSET {$offset}");
    $stmt->execute($where['params']);
    $rows = $stmt->fetchAll();

    // نکته: با تپ روی هر سرویس در همین لیست، بلافاصله فعال/غیرفعال می‌شود (بدون
    // نیاز به باز کردن صفحه‌ی جزئیات)؛ برای تنظیمات دقیق‌تر (پلتفرم/دسته) از
    // دکمه‌ی 🔧 کنار همان سرویس استفاده کنید. دو دکمه‌ی زیر هم کل این فیلتر
    // (همه‌ی صفحات، نه فقط همین صفحه) را یک‌جا فعال/غیرفعال می‌کنند تا مدیریت
    // ده‌ها/صدها سرویس دیگر «دونه‌دونه» نباشد.
    $btnRows = [];
    $btnRows[] = [
        ['text' => '✅ فعال کردن همه (' . $total . ')', 'callback_data' => 'smmadminbulk_enable_' . $filter],
        ['text' => '❌ غیرفعال کردن همه', 'callback_data' => 'smmadminbulk_disable_' . $filter],
    ];
    foreach ($rows as $r) {
        $label = ($r['enabled'] ? '✅ ' : '❌ ') . mb_strimwidth($r['name'], 0, 34, '…');
        $btnRows[] = [
            ['text' => $label, 'callback_data' => "smmadmintoggle_{$r['service_id']}_{$filter}_{$offset}"],
            ['text' => '🔧', 'callback_data' => "smmadminsvc_{$r['service_id']}_{$filter}_{$offset}"],
        ];
    }
    $nav = [];
    if ($offset > 0) $nav[] = ['text' => '⏫ قبلی', 'callback_data' => "smmadminlist_{$filter}_" . max(0, $offset - $perPage)];
    if ($offset + $perPage < $total) $nav[] = ['text' => 'بعدی ⏬', 'callback_data' => "smmadminlist_{$filter}_" . ($offset + $perPage)];
    if ($nav) $btnRows[] = $nav;
    $btnRows[] = [['text' => '🔙 بازگشت', 'callback_data' => 'smmadminback']];

    $text = smmAdminFilterLabel($filter) . " — {$enabledCount} از {$total} سرویس فعال\n\nروی هر سرویس بزنید تا فعال/غیرفعال شود؛ 🔧 برای تنظیمات دقیق (پلتفرم/دسته):";
    Editmessagetext($from_id, $message_id, $text, json_encode(['inline_keyboard' => $btnRows], JSON_UNESCAPED_UNICODE), 'HTML');
}

function smmAdminShowServiceDetail($from_id, $message_id, $serviceId, $filter, $offset)
{
    $service = smmGetService($serviceId);
    if (!$service) {
        Editmessagetext($from_id, $message_id, '❌ این سرویس دیگر در کش موجود نیست (شاید در Sync بعدی حذف شده).', json_encode(['inline_keyboard' => [[['text' => '🔙 بازگشت', 'callback_data' => 'smmadminback']]]], JSON_UNESCAPED_UNICODE), 'HTML');
        return;
    }
    $text = "📦 <b>" . htmlspecialchars($service['name']) . "</b>\n\n"
        . "🆔 Service ID: <code>" . htmlspecialchars($service['service_id']) . "</code>\n"
        . "🗂 دسته (category) فعلی: " . htmlspecialchars($service['category'] ?: '-') . "\n"
        . "🌐 پلتفرم فعلی: " . smmPlatformLabel($service['platform']) . " (" . ($service['platform_source'] === 'manual' ? 'دستی توسط ادمین' : 'تشخیص خودکار') . ")\n"
        . "💵 Rate (API، هر ۱۰۰۰ واحد): {$service['rate']}\n"
        . "📊 حداقل: " . number_format($service['min_amount']) . " | 📈 حداکثر: " . number_format($service['max_amount']) . "\n"
        . "🔄 Refill: " . ($service['refill'] ? 'دارد' : 'ندارد') . " | ❌ Cancel: " . ($service['cancel'] ? 'دارد' : 'ندارد') . "\n"
        . "🚦 وضعیت نمایش به کاربر: " . ($service['enabled'] ? 'فعال ✅' : 'غیرفعال ❌');

    $rows = [
        [['text' => $service['enabled'] ? '❌ غیرفعال کن' : '✅ فعال کن', 'callback_data' => "smmadmintoggledetail_{$serviceId}_{$filter}_{$offset}"]],
        [
            ['text' => '📱 پلتفرم = تلگرام', 'callback_data' => "smmadminsetplat_{$serviceId}_telegram_{$filter}_{$offset}"],
            ['text' => '📸 پلتفرم = اینستاگرام', 'callback_data' => "smmadminsetplat_{$serviceId}_instagram_{$filter}_{$offset}"],
        ],
        [['text' => '❔ پلتفرم = نامشخص', 'callback_data' => "smmadminsetplat_{$serviceId}_none_{$filter}_{$offset}"]],
        [['text' => '✏️ تغییر نام دسته (Category)', 'callback_data' => "smmadminsetcat_{$serviceId}_{$filter}_{$offset}"]],
        [['text' => '🔙 بازگشت به لیست', 'callback_data' => "smmadminlist_{$filter}_{$offset}"]],
    ];
    Editmessagetext($from_id, $message_id, $text, json_encode(['inline_keyboard' => $rows], JSON_UNESCAPED_UNICODE), 'HTML');
}