<?php
function flow($msg)
{
    file_put_contents(__DIR__.'/flow.log',
        date("H:i:s") . " | " . $msg . "\n",
        FILE_APPEND
    );
}
function debug_log($msg)
{
    file_put_contents(
        __DIR__."/debug_flow.txt",
        date("H:i:s") . " | " . $msg . PHP_EOL,
        FILE_APPEND
    );
}
file_put_contents(__DIR__.'/alive.txt', date('H:i:s')."\n", FILE_APPEND);

file_put_contents(
    __DIR__.'/heartbeat.log',
    date('H:i:s') . " | BOT HIT\n",
    FILE_APPEND
);

function setUserState($chat_id, $state)
{
    file_put_contents(
        __DIR__."/user_states/".$chat_id.".txt",
        $state
    );
}

function getUserState($chat_id)
{
    $file = __DIR__."/user_states/".$chat_id.".txt";

    if (!file_exists($file)) {
        return null;
    }

    return trim(file_get_contents($file));
}

function clearUserState($chat_id)
{
    $file = __DIR__."/user_states/".$chat_id.".txt";

    if (file_exists($file)) {
        unlink($file);
    }
}
require_once __DIR__ . '/conn.php';
date_default_timezone_set('Asia/Kolkata');

function spin_log($msg)
{
    file_put_contents(
        __DIR__ . "/spin_debug.log",
        date("Y-m-d H:i:s") . " | " . $msg . PHP_EOL,
        FILE_APPEND
    );
}

function balance_debug($msg)
{
    file_put_contents(
        __DIR__ . "/balance_debug.log",
        date("Y-m-d H:i:s") . " | " . $msg . PHP_EOL,
        FILE_APPEND
    );
}


function handle_spin_check(PDO $pdo, $chat_id)
{
    spin_log("SPIN CHECK | USER={$chat_id}");

    try {

        $today = date('Y-m-d');

        /* 💰 Today's Deposit */

        $stmt = $pdo->prepare("
            SELECT COALESCE(SUM(amount),0)
            FROM deposit_history
            WHERE user_id=? 
            AND status='SUCCESS'
            AND DATE(created_at)=?
        ");
        $stmt->execute([$chat_id, $today]);

        $deposit = (float)$stmt->fetchColumn();

        spin_log("TODAY DEPOSIT = {$deposit}");

        /* 🎯 Spins */

        $totalSpins = floor($deposit / 300);

        $stmt = $pdo->prepare("
            SELECT COUNT(*) FROM spin_history
            WHERE user_id=? AND DATE(created_at)=?
        ");
        $stmt->execute([$chat_id, $today]);

        $usedSpins = (int)$stmt->fetchColumn();

        $remaining = max(0, $totalSpins - $usedSpins);

        spin_log("SPINS | TOTAL={$totalSpins} USED={$usedSpins} LEFT={$remaining}");

       sendMessage(
    $chat_id,
    "🎡 *Sᴘɪɴ & Wɪɴ Mᴀᴄʜɪɴᴇ* 🎡🔥\n\n".
    "💰 *Aᴀᴊ Kᴀ Dᴇᴘᴏsɪᴛ:* ₹{$deposit}\n".
    "🎯 *Sᴘɪɴs Eᴀʀɴᴇᴅ:* {$totalSpins}\n".
    "🔁 *Sᴘɪɴs Usᴇᴅ:* {$usedSpins}\n".
    "✅ *Sᴘɪɴs Aᴠᴀɪʟᴀʙʟᴇ:* {$remaining}\n\n".
    "💎 *Rᴇᴡᴀʀᴅs Pᴏᴏʟ:* 😎🔥\n".
    "₹10 😎\n".
    "₹20 😎\n".
    "₹40 🔥\n".
    "₹500 😈🔥\n".
    "₹1000 💎👑\n\n".
    "⚡ *Rᴜʟᴇ Sᴜɴ ʟᴏ Bʀᴏ 😎*\n".
    "👉 *Pᴇʀ Dᴀʏ Jɪᴛɴɪ Bᴀᴀʀ ₹300 Dᴇᴘᴏsɪᴛ Kᴀʀᴏɢᴇ, Uᴛɴɪ Bᴀᴀʀ Sᴘɪɴ Kᴀ Mᴀᴜᴋᴀ Mɪʟᴇɢᴀ!* 😈🔥",
    [
        "inline_keyboard" => [
            [
                ["text"=>"🎡 Sᴛᴀʀᴛ Sᴘɪɴ 😈", "callback_data"=>"SPIN_DO"]
            ]
        ]
    ],
    "Markdown"
);


        spin_log("SPIN CHECK UI SENT");

    } catch (Throwable $e) {

        spin_log("ERROR = " . $e->getMessage());

        sendMessage($chat_id, "❌ Spin error");
    }
}
function handle_spin(PDO $pdo, $chat_id)
{
    spin_log("SPIN START | USER={$chat_id}");

    try {

        $today = date('Y-m-d');

        /* 💰 Deposit */

        $stmt = $pdo->prepare("
            SELECT COALESCE(SUM(amount),0)
            FROM deposit_history
            WHERE user_id=? 
            AND status='SUCCESS'
            AND DATE(created_at)=?
        ");
        $stmt->execute([$chat_id, $today]);

        $deposit = (float)$stmt->fetchColumn();
        $totalSpins = floor($deposit / 300);

        spin_log("DEPOSIT={$deposit} TOTAL_SPINS={$totalSpins}");

        /* 🔁 Used Spins */

        $stmt = $pdo->prepare("
            SELECT COUNT(*) FROM spin_history
            WHERE user_id=? 
            AND DATE(created_at)=?
        ");
        $stmt->execute([$chat_id, $today]);

        $usedSpins = (int)$stmt->fetchColumn();

        spin_log("USED_SPINS={$usedSpins}");

        if ($usedSpins >= $totalSpins) {

            spin_log("NO SPINS LEFT");

            sendMessage(
    $chat_id,
    "❌ *Aᴀᴊ Kᴇ Sᴘɪɴs Kʜᴀᴛᴀᴍ Hᴏ Gᴀʏᴇ 😎*\n\n".
    "💰 *Pʜʟᴇ ₹300 Dᴇᴘᴏsɪᴛ Kᴀʀᴏ — Tᴀʙ Hɪ Sᴘɪɴ Kᴀ Mᴀᴜᴋᴀ Mɪʟᴇɢᴀ!* 🔥😈",
    null,
    "Markdown"
);
return;

        }

        /* 🎡 SEND MESSAGE (SAFE) */

        $raw = sendMessage($chat_id, "🎡 Initializing Spin...");
        $msg = json_decode($raw, true);

        if (empty($msg['result']['message_id'])) {

            spin_log("MESSAGE SEND FAILED");

            sendMessage($chat_id, "❌ Spin UI error");
            return;
        }

        $mid = $msg['result']['message_id'];

        spin_log("MESSAGE_ID={$mid}");

        /* 🎡 Animation */

        for ($round = 1; $round <= 8; $round++) {

            editMessage($chat_id, $mid,
                "🎡 *SPINNING ROUND {$round}/8*\n\n".
                "⬅️ ₹10 | ₹20 | ₹40 | ₹500 | ₹1000"
            );
        }

        spin_log("ANIMATION DONE");

        /* 🎯 Reward */

       $rand = mt_rand(1, 100);

if ($rand <= 65) {
    $reward = 10;   // ✅ 65% 😎
}
elseif ($rand <= 95) {
    $reward = 20;   // ✅ 30% 😎
}
else {
    $reward = 40;   // ✅ 5% 🔥😈
}

        spin_log("REWARD={$reward}");

        /* ✅ Credit */

        add_balance($pdo, $chat_id, $reward, "Spin Reward");

        spin_log("BALANCE ADDED");

        /* ✅ Save */

        $stmt = $pdo->prepare("
            INSERT INTO spin_history (user_id, reward)
            VALUES (?, ?)
        ");
        $stmt->execute([$chat_id, $reward]);

        spin_log("HISTORY SAVED");

        /* 🎉 Result */

        editMessage(
    $chat_id,
    $mid,
    "🎉 *Sᴘɪɴ Rᴇsᴜʟᴛ Aᴀ Gᴀʏᴀ!* 🎡🔥\n\n".
    "💰 *Bʀᴏ, Tᴜᴍɴᴇ Jᴇᴇᴛ Lɪʏᴀ:* ₹{$reward} 😎🔥\n\n".
    "😈 *Dᴇᴋʜᴀ? Kɪsᴍᴀᴛ Hᴏ Tᴏ Aɪsɪ!*",
    null,
    "Markdown"
);


        spin_log("SPIN SUCCESS");

    } catch (Throwable $e) {

        spin_log("ERROR = " . $e->getMessage());

        sendMessage($chat_id, "❌ Spin crashed");
    }
}





function handle_telegram_session_buy(PDO $pdo, $chat_id, $server_id, $qty, $cid)
{
    buy_log("===== TELEGRAM BUY START =====");
    buy_log("USER = {$chat_id}");
    buy_log("SERVER = {$server_id}");
    buy_log("QTY = {$qty}");

    if ($qty < 1 || $qty > 20) {
        buy_log("ERROR: INVALID QTY");
        sendAlert("❌ Invalid quantity.", $cid);
        return;
    }

    if (!class_exists('ZipArchive')) {
        buy_log("ERROR: ZIP EXTENSION NOT ENABLED");
        sendAlert("❌ ZIP extension missing on server.", $cid);
        return;
    }

    try {

        $pdo->beginTransaction();
        buy_log("TRANSACTION STARTED");

        /* ✅ LOCK STOCK */

        $stmt = $pdo->prepare("
            SELECT id, file_path
            FROM session_stock
            WHERE server_id=? AND is_used=0
            LIMIT {$qty}
            FOR UPDATE
        ");
        $stmt->execute([$server_id]);

        $sessions = $stmt->fetchAll(PDO::FETCH_ASSOC);

        buy_log("STOCK FETCHED = " . count($sessions));

        if (count($sessions) < $qty) {

            buy_log("ERROR: NOT ENOUGH STOCK");

            $pdo->rollBack();
            sendAlert("❌ Only " . count($sessions) . " sessions available.", $cid);
            return;
        }

        /* ✅ FETCH PRICE */

        $stmt = $pdo->prepare("SELECT price FROM account_servers WHERE id=?");
        $stmt->execute([$server_id]);

        $price = (float)$stmt->fetchColumn();
      $total = $price * $qty;

$discount = 0;

/* 😎 BULK DISCOUNT LOGIC */

if ($qty >= 20) {
    $discount = 20;   // 20% 😈🔥
}
elseif ($qty >= 10) {
    $discount = 10;   // 10% 🔥
}
elseif ($qty >= 5) {
    $discount = 5;    // 5% 😎
}

/* Apply discount */

if ($discount > 0) {

    $discountAmount = ($total * $discount) / 100;
    $total -= $discountAmount;

    buy_log("DISCOUNT APPLIED = {$discount}%");
    buy_log("DISCOUNT AMOUNT = {$discountAmount}");
}

buy_log("FINAL TOTAL = {$total}");


        buy_log("PRICE = {$price}");
        buy_log("TOTAL = {$total}");

        /* ✅ LOCK BALANCE */

        $stmt = $pdo->prepare("
            SELECT balance FROM user_data WHERE user_id=? FOR UPDATE
        ");
        $stmt->execute([$chat_id]);

        $balance = (float)$stmt->fetchColumn();

        buy_log("BALANCE = {$balance}");

        if ($balance < $total) {

            buy_log("ERROR: LOW BALANCE");

            $pdo->rollBack();
            sendAlert("❌ Insufficient balance.", $cid);
            return;
        }

        /* ✅ CUT BALANCE */

        cut_balancess($pdo, $chat_id, $total);
        buy_log("BALANCE CUT SUCCESS");

        /* ✅ MARK USED */

        $ids = array_column($sessions, 'id');
        $in  = implode(',', $ids);

        buy_log("SESSION IDS = {$in}");

        $pdo->query("
            UPDATE session_stock
            SET is_used=1, used_by='{$chat_id}', used_at=NOW()
            WHERE id IN ($in)
        ");

        buy_log("STOCK MARKED USED");

        /* ✅ ZIP CREATION */

        $zipName = "sessions_" . time() . ".zip";
        $zipPath = $_SERVER['DOCUMENT_ROOT'] . "/tmp/" . $zipName;

        buy_log("ZIP PATH = {$zipPath}");

        if (!is_dir($_SERVER['DOCUMENT_ROOT'] . "/tmp")) {

            buy_log("ERROR: TMP FOLDER MISSING");

            $pdo->rollBack();
            sendAlert("❌ TMP folder missing.", $cid);
            return;
        }

        if (!is_writable($_SERVER['DOCUMENT_ROOT'] . "/tmp")) {

            buy_log("ERROR: TMP NOT WRITABLE");

            $pdo->rollBack();
            sendAlert("❌ TMP folder not writable.", $cid);
            return;
        }

        $zip = new ZipArchive();

        if (!$zip->open($zipPath, ZipArchive::CREATE)) {

            buy_log("ERROR: ZIP OPEN FAILED");

            $pdo->rollBack();
            sendAlert("❌ ZIP creation failed.", $cid);
            return;
        }

        foreach ($sessions as $s) {

            $fullPath = $_SERVER['DOCUMENT_ROOT'] . "/" . $s['file_path'];

            buy_log("ADDING FILE = {$fullPath}");

            if (file_exists($fullPath)) {

                $zip->addFile($fullPath, basename($fullPath));
                buy_log("FILE ADDED ✅");

            } else {

                buy_log("FILE MISSING ❌ = {$fullPath}");
            }
        }

        $zip->close();

     buy_log("ZIP EXISTS = " . (file_exists($zipPath) ? "YES" : "NO"));

if (file_exists($zipPath)) {
    buy_log("ZIP SIZE = " . filesize($zipPath));
}

        $pdo->commit();
        buy_log("TRANSACTION COMMIT");

        /* ✅ DELIVER */

     sendDocument(
    $chat_id,
    new CURLFile(realpath($zipPath)),
    "✅ Bʀᴏ, Tᴜᴍʜᴀʀᴇ {$qty} Aᴄᴄᴏᴜɴᴛs Yᴇ Rᴀʜᴇ 😎🔥\n\n".
    "📦 Sᴇssɪᴏɴ Zɪᴘ Fɪʟᴇ Rᴇᴀᴅʏ Hᴀɪ\n\n".
    "👇 Isᴇ Yᴀʜᴀ Dᴀʟᴅᴏ:\n".
    "https://t.me/TELETHON_SESSION_LOGIN_BOT 🚀\n\n".
       "🔑Paaword  ye dal do = pass345word :\n".
    "⚡ Aᴘᴋᴀ Tᴇʟᴇɢʀᴀᴍ OTP Kᴇ Tʜʀᴏᴜɢʜ Lᴏɢɪɴ Hᴏ Jᴀʏᴇɢᴀ\n\n".
    "🔐 Sᴀғᴇ Lᴏɢɪɴ Tɪᴘ: Tᴇʟᴇɢʀᴀᴍ Dᴇsᴋᴛᴏᴘ Yᴀ Tᴇʟᴇɢʀᴀᴘʜ Aᴘᴘ Usᴇ Kᴀʀɴᴀ Zʏᴀᴅᴀ Sᴀғᴇ Rʜᴇɢᴀ 😎🔥"
);


        buy_log("DOCUMENT SENT");
        buy_log("===== TELEGRAM BUY SUCCESS =====");

    } catch (Throwable $e) {

        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }

        buy_log("EXCEPTION = " . $e->getMessage());

        sendAlert("❌ ZIP generation failed.", $cid);
    }
}



function show_account_servers(PDO $pdo, string $chat_id)
{
    $rows = $pdo->query("
        SELECT id, name FROM account_servers
        WHERE is_active=1
    ")->fetchAll(PDO::FETCH_ASSOC);

    $buttons = [];

    foreach ($rows as $r) {
        $buttons[] = [
            ["text" => $r['name'], "callback_data" => "ACC_VIEW {$r['id']}"]
        ];
    }



    sendMessage(
    $chat_id,
    "📦 *😎🔥 Bᴀᴛᴀᴏ Kɪs Cʜᴇᴇᴢ Kᴀ Rᴇᴀᴅʏᴍᴀᴅᴇ Aᴄᴄᴏᴜɴᴛ Cʜᴀʜɪʏᴇ? 🚀*\n\n".
    "👇 *Bᴀs Nɪᴄʜᴇ Cʜᴏᴏsᴇ Kᴀʀ Lᴏ* 😎💥",
    ["inline_keyboard" => $buttons],
    "Markdown"
);
}
function show_telegram_confirm(PDO $pdo, $chat_id, $server_id)
{
    $s = $pdo->query("
        SELECT * FROM account_servers WHERE id={$server_id}
    ")->fetch(PDO::FETCH_ASSOC);

    $bal = $pdo->prepare("SELECT balance FROM user_data WHERE user_id=?");
    $bal->execute([$chat_id]);

    $balance = $bal->fetchColumn();

    sendMessage(
        $chat_id,
        "⚠️ *Confirm Telegram Session Purchase*\n\n".
        "Service: {$s['name']}\n".
        "Price: ₹{$s['price']}\n".
        "Balance: ₹{$balance}",
        [
            "inline_keyboard" => [
                [
                    ["text" => "✅ Yes Buy", "callback_data" => "TG_BUY {$server_id}"],
                    ["text" => "❌ Cancel", "callback_data" => "ACC_SERVERS"]
                ]
            ]
        ],
        "Markdown"
    );
}

function show_telegram_session_detail(PDO $pdo, $chat_id, $server_id)
{
    $stmt = $pdo->prepare("
        SELECT COUNT(*) 
        FROM session_stock
        WHERE server_id=? AND is_used=0
    ");
    $stmt->execute([$server_id]);

    $stock = (int)$stmt->fetchColumn();

    $server = $pdo->query("
        SELECT * FROM account_servers WHERE id={$server_id}
    ")->fetch(PDO::FETCH_ASSOC);

    if ($stock <= 0) {

        sendMessage(
            $chat_id,
            "🚫 *Tᴇʟᴇɢʀᴀᴍ Sᴇssɪᴏɴs Oᴜᴛ Oғ Sᴛᴏᴄᴋ 😴💔*",
            [
                "inline_keyboard" => [
                    [
                        ["text"=>"🔙 Back", "callback_data"=>"ACC_SERVERS"]
                    ]
                ]
            ]
        );

        return;
    }

    /* ✅ QUANTITY BUTTON GRID 😎🔥 */

    $keyboard = [];
    $row = [];

    for ($i = 1; $i <= 20; $i++) {

        $row[] = [
            "text" => (string)$i,
            "callback_data" => "TG_BUY {$server_id}|{$i}"
        ];

        if ($i % 5 == 0) {
            $keyboard[] = $row;
            $row = [];
        }
    }

 sendMessage(
    $chat_id,
    "📲 *{$server['name']}* 🚀🔥\n\n".
    "💰 *Pʀɪᴄᴇ:* ₹{$server['price']} 💸\n".
    "📊 *Sᴛᴏᴄᴋ:* ✅ {$stock} 😎\n\n".
    "💥 *Dɪsᴄᴏᴜɴᴛ Oғғᴇʀs:* 😈🔥\n".
    "🎯 5+ Qᴜᴀɴᴛɪᴛʏ → 5% Dɪsᴄᴏᴜɴᴛ 😎\n".
    "🚀 10+ Qᴜᴀɴᴛɪᴛʏ → 10% Dɪsᴄᴏᴜɴᴛ 🔥\n".
    "👑 20+ Qᴜᴀɴᴛɪᴛʏ → 20% Dɪsᴄᴏᴜɴᴛ 😈🔥\n\n".
    "🎯 *Kɪᴛɴᴀ Qᴜᴀɴᴛɪᴛʏ Cʜᴀʜɪʏᴇ?* 👇",
        [
            "inline_keyboard" => array_merge(
                $keyboard,
                [
                    [
                        ["text"=>"🔙 Back", "callback_data"=>"ACC_SERVERS"]
                    ]
                ]
            )
        ]
    );
}



function show_account_detail(PDO $pdo, string $chat_id, int $server_id)
{
    $stmt = $pdo->prepare("SELECT * FROM account_servers WHERE id=?");
    $stmt->execute([$server_id]);
    $server = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$server) {
        sendMessage($chat_id, "❌ Server not found.");
        return;
    }

    /* ✅ TELEGRAM SESSION MODE 🔥 */
if (stripos($server['name'], 'telegram') !== false) {

    show_telegram_session_detail($pdo, $chat_id, $server_id);
    return;
}



    // 🔥 NORMAL ACCOUNT STOCK LOGIC
    $stmt = $pdo->prepare("
        SELECT COUNT(*) 
        FROM accounts_stock
        WHERE server_id=? AND is_used=0
    ");
    $stmt->execute([$server_id]);
    $stock = (int)$stmt->fetchColumn();

    if ($stock <= 0) {
        sendMessage($chat_id, "🚫 *Oᴜᴛ Oғ Sᴛᴏᴄᴋ 😴💔*");
        return;
    }

   sendMessage(
    $chat_id,
    "📦 *{$server['name']}* 🚀🔥\n\n".
    "💰 *Pʀɪᴄᴇ:* ₹{$server['price']} 💸\n".
    "📊 *Sᴛᴏᴄᴋ:* ✅ {$stock} 😎\n\n".
    "⚡ *Dᴀʙᴀᴏ Bᴜʏ — Aᴄᴄᴏᴜɴᴛ Tᴜʀᴀɴᴛ Mɪʟᴇɢᴀ!* 🚀",
    [
        "inline_keyboard" => [
            [
                ["text" => "✅ Bᴜʏ Nᴏᴡ 🔥", "callback_data" => "ACC_CONFIRM {$server_id}"]
            ]
        
            ]
        ]
    );
}
function confirm_account_buy(PDO $pdo, string $chat_id, int $server_id)
{
    $s = $pdo->query("
        SELECT * FROM account_servers WHERE id={$server_id}
    ")->fetch(PDO::FETCH_ASSOC);

    $bal = $pdo->prepare("SELECT balance FROM user_data WHERE user_id=?");
    $bal->execute([$chat_id]);
    $balance = $bal->fetchColumn();

    sendMessage(
    $chat_id,
    "⚠️ *Oʜʜ Sᴜɴᴏ, Cᴏɴғɪʀᴍ Kᴀʀᴏ 😎*\n\n".
    "📦 *Sᴇʀᴠɪᴄᴇ:* {$s['name']} 🚀\n".
    "💰 *Pʀɪᴄᴇ:* ₹{$s['price']} 💸\n".
    "👛 *Tᴜᴍʜᴀʀᴀ Bᴀʟᴀɴᴄᴇ:* ₹{$balance}\n\n".
    "🔥 *Dᴀʙᴀᴏ Bᴜʏ — Aᴄᴄᴏᴜɴᴛ Tᴜʀᴀɴᴛ Mɪʟᴇɢᴀ!*",
    [
        "inline_keyboard" => [
            [
                ["text" => "✅ Hᴀᴀɴ Bʜᴀɪ Bᴜʏ 🔥", "callback_data" => "ACC_BUY {$server_id}"],
                ["text" => "❌ Rᴇʜɴᴇ Dᴏ 😴", "callback_data" => "ACC_SERVERS"]
            ]
        ]
    ],
    "Markdown"
);

}


function process_account_buy(PDO $pdo, string $chat_id, int $server_id, $cid)
{
    buy_log("START | user={$chat_id} server={$server_id}");

    try {
        // 1️⃣ Start transaction
        $pdo->beginTransaction();
        buy_log("BEGIN TRANSACTION");

        // 2️⃣ Fetch server
        $stmt = $pdo->prepare("SELECT * FROM account_servers WHERE id=? AND is_active=1");
        $stmt->execute([$server_id]);
        $server = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$server) {
            buy_log("ERROR: SERVER NOT FOUND");
            $pdo->rollBack();
            sendAlert("❌ Server not found.", $cid);
            return;
        }

        buy_log("SERVER OK | price={$server['price']}");

        // 3️⃣ Lock user balance
        $stmt = $pdo->prepare("
            SELECT balance
            FROM user_data
            WHERE user_id=? FOR UPDATE
        ");
        $stmt->execute([$chat_id]);
        $balance = (float)$stmt->fetchColumn();

        buy_log("BALANCE={$balance}");

        if ($balance < (float)$server['price']) {
            buy_log("ERROR: LOW BALANCE");
            $pdo->rollBack();
            sendAlert("❌ Insufficient balance.", $cid);
            return;
        }

        // 4️⃣ Lock ONE unused account
        $stmt = $pdo->prepare("
            SELECT id, username, password, extra_info
            FROM accounts_stock
            WHERE server_id=? AND is_used=0
            LIMIT 1
            FOR UPDATE
        ");
        $stmt->execute([$server_id]);
        $account = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$account) {
            buy_log("ERROR: OUT OF STOCK");
            $pdo->rollBack();
            sendAlert("❌ Out of stock.", $cid);
            return;
        }

        buy_log("ACCOUNT ID={$account['id']}");

        // 5️⃣ Cut balance
        cut_balancess($pdo, $chat_id, (float)$server['price']);
        buy_log("CUT BALANCE");

        // 6️⃣ Mark account as used
        $stmt = $pdo->prepare("
            UPDATE accounts_stock
            SET is_used=1, used_by=?, used_at=NOW()
            WHERE id=?
        ");
        $stmt->execute([$chat_id, $account['id']]);
        buy_log("MARK ACCOUNT USED");

        // 7️⃣ Commit
        $pdo->commit();
        buy_log("COMMIT");

        // ==========================
        // ✅ DELIVERY (NEW MESSAGE)
        // ==========================
$message =
    "✅ *Pᴜʀᴄʜᴀsᴇ Sᴜᴄᴄᴇssғᴜʟʟ!* 🎉🔥\n\n".
    "📦 *Aᴄᴄᴏᴜɴᴛ Dᴇᴛᴀɪʟs:* 😎👇\n".
    "━━━━━━━━━━━━━━━\n".
    "👤 *Usᴇʀɴᴀᴍᴇ:* `{$account['username']}`\n".
    "🔑 *Pᴀssᴡᴏʀᴅ:* `{$account['password']}`\n";

        if (!empty($account['extra_info'])) {
            $message .= "Info: {$account['extra_info']}\n";
        }

        $message .=
            "----------------------\n\n".
            $server['success_message'];

        buy_log("SEND MESSAGE");

        // 🔥 Always send as NEW MESSAGE
        sendMessage($chat_id, $message);

        buy_log("SUCCESS END");

    } catch (Throwable $e) {
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        buy_log("EXCEPTION: " . $e->getMessage());
        sendAlert("❌ Internal error. Please contact support.", $cid);
    }
}

function buy_log($msg)
{
    $line = date('Y-m-d H:i:s') . " | " . $msg . PHP_EOL;
    file_put_contents(__DIR__ . "/account_buy.log", $line, FILE_APPEND);
}


// ================= REFERRAL DEBUG =================
function referDebug($msg)
{
    $file = __DIR__ . '/refer_debug.log';
    $time = date('Y-m-d H:i:s');
    file_put_contents($file, "[$time] $msg\n", FILE_APPEND);
}


// ================= PROCESS COMMISSION =================
function processReferralCommission(PDO $pdo, array $order)
{
    referDebug("START order_id={$order['order_id']} user={$order['user_id']}");

    // 1️⃣ duplicate check
    $chk = $pdo->prepare("SELECT 1 FROM reseller_earnings WHERE order_id=?");
    $chk->execute([$order['order_id']]);

    if ($chk->fetch()) {
        referDebug("SKIP duplicate order {$order['order_id']}");
        return false;
    }

    // 2️⃣ referral info
    $stmt = $pdo->prepare("
        SELECT referred_by, reseller_margin
        FROM user_data
        WHERE user_id=?
    ");
    $stmt->execute([$order['user_id']]);
    $u = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$u) {
        referDebug("USER NOT FOUND {$order['user_id']}");
        return false;
    }

    referDebug("REF INFO referred_by={$u['referred_by']} margin={$u['reseller_margin']}");

    if (empty($u['referred_by']) || floatval($u['reseller_margin']) <= 0) {
        referDebug("NO COMMISSION CONDITIONS FAILED");
        return false;
    }

    $margin = floatval($u['reseller_margin']);

    // 3️⃣ ensure reseller row
    $pdo->prepare("
        INSERT IGNORE INTO resellers (user_id, balance, total_earnings, total_referrals)
        VALUES (?,0,0,0)
    ")->execute([$u['referred_by']]);

    // 4️⃣ add balance
    $up = $pdo->prepare("
        UPDATE resellers
        SET balance = balance + ?, total_earnings = total_earnings + ?
        WHERE user_id=?
    ");
    $up->execute([$margin, $margin, $u['referred_by']]);

    referDebug("BALANCE UPDATED rows=".$up->rowCount());

    // 5️⃣ log earning
    $pdo->prepare("
        INSERT INTO reseller_earnings
        (order_id, reseller_id, user_id, margin)
        VALUES (?,?,?,?)
    ")->execute([
        $order['order_id'],
        $u['referred_by'],
        $order['user_id'],
        $margin
    ]);

    referDebug("SUCCESS commission added order {$order['order_id']}");

    return true;
}

function send_reseller_dashboard(PDO $pdo, $chat_id){

    $stmt = $pdo->prepare("SELECT * FROM resellers WHERE user_id=?");
    $stmt->execute([$chat_id]);
    $r = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$r) {
        $pdo->prepare("INSERT INTO resellers (user_id) VALUES (?)")
            ->execute([$chat_id]);
        $r = ['balance'=>0,'total_earnings'=>0,'total_referrals'=>0];
    }

   sendMessage(
    $chat_id,
    "👥 *Rᴇsᴇʟʟᴇʀ Dᴀsʜʙᴏᴀʀᴅ*\n\n"
  . "💰 Bᴀʟᴀɴᴄᴇ: ₹{$r['balance']}\n"
  . "📈 Tᴏᴛᴀʟ Eᴀʀɴɪɴɢs: ₹{$r['total_earnings']}\n"
  . "👤 Tᴏᴛᴀʟ Rᴇғᴇʀʀᴀʟs: {$r['total_referrals']}",
    [
        "inline_keyboard" => [
            [
                ["text"=>"🔗 Cʀᴇᴀᴛᴇ Lɪɴᴋ","callback_data"=>"RESELLER_CREATE"],
                ["text"=>"📂 Mʏ Lɪɴᴋs","callback_data"=>"RESELLER_LINKS"]
            ],
            [
                ["text"=>"💸 Wɪᴛʜᴅʀᴀᴡ Bᴀʟᴀɴᴄᴇ", "callback_data"=>"RESELLER_WITHDRAW"]
            ]
        ]
    ],
    "Markdown"
);
}



function redeem_promocode(PDO $pdo, $chat_id, $text){

    $code = strtoupper(trim($text));

    // 1️⃣ PROMO EXIST?
 $stmt = $pdo->prepare("SELECT * FROM promo_codes WHERE code = ?");

    $stmt->execute([$code]);
    $promo = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$promo) {
        sendMessage(
            $chat_id,
            "❌ *Kᴜᴄʜ Bʜɪ Tᴜᴋᴋᴀ Mᴀᴛ Mᴀʀᴏ Cʜᴀɴɴᴇʟ Pᴇ Pʀᴏᴍᴏᴄᴏᴅᴇ Aᴀʏᴇɢᴀ Vᴏ Dᴀʟɴᴀ Tɪᴍᴇ Wᴀsᴛᴇ Nʜɪ Mᴇʀᴀ* 😎"
        );
        return;
    }

    // 2️⃣ PROMO OVER?
    if ($promo['used_count'] >= $promo['max_uses']) {

        $pdo->prepare("UPDATE promo_codes SET status='over' WHERE id=?")
            ->execute([$promo['id']]);

        sendMessage(
            $chat_id,
            "❌ *Sᴏ Mᴀᴛ, Tʜᴏᴅᴀ Jᴀʟᴅɪ Aᴀʏᴀ Kᴀʀᴏ — Pʀᴏᴍᴏ Cᴏᴅᴇ Kʜᴀᴛᴀᴍ Hᴏ Gᴀʏᴀ, Aᴀʙ Cʜᴀɴɴᴇʟ Pᴀʀ Jᴀʟᴅ Hɪ Aᴀʏᴇɢᴀ, Jᴏɪɴ Hᴏ Jᴀᴏ! 🚀😴*"
        );
        return;
    }

    // 3️⃣ USER ALREADY USED?
    $check = $pdo->prepare("SELECT 1 FROM promo_redeems WHERE promo_id=? AND user_id=?");
    $check->execute([$promo['id'], $chat_id]);

    if ($check->fetch()) {
        sendMessage(
            $chat_id,
            "❌ *Eᴋ Bᴀᴀʀ Rᴇᴅᴇᴇᴍ Hᴏ Cʜᴜᴋᴀ 😅*"
        );
        return;
    }

    // 4️⃣ MIN RECHARGE CHECK
    $stmt = $pdo->prepare("SELECT spend, balance FROM user_data WHERE user_id=?");
    $stmt->execute([$chat_id]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    $totalAmount = $user['spend'] + $user['balance'];

    if ($totalAmount < $promo['min_recharge']) {
        sendMessage(
            $chat_id,
            "❌ *Mɪɴɪᴍᴜᴍ Rᴇᴄʜᴀʀɢᴇ ₹{$promo['min_recharge']} Cʜᴀʜɪʏᴇ — Jᴀᴏ Tʜᴏᴅᴀ Rᴇᴄʜᴀʀɢᴇ Kᴀʀᴏ, Tᴀʙ Hɪ Mᴀᴢᴇ Lᴏ Pʀᴏᴍᴏ Cᴏᴅᴇ Kᴇ 😎*."
        );
        return;
    }

    // 5️⃣ REDEEM (TRANSACTION SAFE)
    $pdo->beginTransaction();

 $pdo->prepare("
    UPDATE user_data 
    SET balance = balance + ?, 
        damo = damo + ?
    WHERE user_id = ?
")->execute([$promo['bonus_amount'], $promo['bonus_amount'], $chat_id]);


    $pdo->prepare("INSERT INTO promo_redeems (promo_id, user_id) VALUES (?, ?)")
        ->execute([$promo['id'], $chat_id]);

    $pdo->prepare("UPDATE promo_codes SET used_count = used_count + 1 WHERE id = ?")
        ->execute([$promo['id']]);

    $pdo->commit();

   sendMessage(
    $chat_id,
    "✅ *Aᴀᴀᴀ Hᴀᴀ Mᴀᴢᴀ Aᴀ Gᴀʏᴀ 😎🔥*\n\n".
    "💰 *Lᴏ Bʜᴀɪ Fʀᴇᴇ Mᴇ ₹{$promo['bonus_amount']} — Aᴜʀ Dᴀʙᴀᴋᴇ Mᴀᴢᴇ Kᴀʀᴏ!* 🎉\n\n".
    "🤝 *Bᴀs Hᴀᴀɴ, Gᴀᴅᴅᴀʀɪ Mᴀᴛ Kᴀʀɴᴀ — Bᴏᴛ Uꜱᴇ Kᴀʀᴛᴇ Rᴀʜɴᴀ Aᴜʀ Sᴜᴘᴘᴏʀᴛ Kᴀʀᴛᴇ Rᴀʜᴏ.*\n".
    "🚀 *Bʜᴜᴛ Sᴀᴀʀᴇ Pʀᴏᴍᴏ Cᴏᴅᴇ Aᴀɴᴇ Wᴀʟᴇ Hᴀɪ!*",
    null,
    "Markdown"
);
}



function autoCheckSms($sms){
    global $pdo;

    $response = "📩 *🔥 Lᴏ Mɪʟ Gᴀʏᴀ! Bᴏʟᴀ Tʜᴀ Nᴀ — Bᴀs 2 Sᴇᴄ Lᴀɢᴇɢᴀ 😎*\n\n";

    /* ================= VIP CHECK ================= */
    $clean = preg_replace('/\d+/', '', strtolower(trim($sms)));

    $vipFound = false;

    $sql = "
        SELECT service_name, server_name
        FROM format_check
        WHERE INSTR(:clean, sms_format) > 0
        ORDER BY LENGTH(sms_format) DESC
        LIMIT 1
    ";

    $stmt = $pdo->prepare($sql);
    $stmt->execute([':clean' => $clean]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($row) {
        $vipFound = true;
        $response .= "*Sᴡɪғᴛ Sᴇʀᴠᴇʀ (VIP💎)*\n";
        $response .= "•{$row['service_name']}\n";
   
    } else {
             $response .= "*Sᴡɪғᴛ Sᴇʀᴠᴇʀ (VIP💎)*\n";
        $response .= "❌ Not Available\n\n";
    }

    /* ================= PREMIUM CHECK ================= */
    $api_key = "5e099c4f01a1e5ebc9d6ccf86e554613";
    $url = "https://pyn-kaing.site/stubs/handler_api.php"
         . "?api_key=$api_key&action=CheckSMS&text=" . urlencode($sms);

    $context = stream_context_create([
        'http' => ['timeout' => 5]
    ]);

    $data = @file_get_contents($url, false, $context);

    if ($data && $data !== "false") {

        $parts = explode(":", trim($data));

        if (count($parts) >= 2) {
            $otp = trim($parts[0]);
            $servers = array_map('trim', explode(",", $parts[1]));

               $response .= "*Sᴡɪғᴛ sᴇʀᴠᴇʀ ( Pʀᴇᴍɪᴜᴍ 🔥)*\n";
           
           

            foreach ($servers as $s) {
                $response .= "• $s\n";
            }
        } else {
               $response .= "*Sᴡɪғᴛ sᴇʀᴠᴇʀ ( Pʀᴇᴍɪᴜᴍ 🔥)*\n";
            $response .= "❌ Not Available\n";
        }

    } else {
             $response .= "*Sᴡɪғᴛ sᴇʀᴠᴇʀ ( Pʀᴇᴍɪᴜᴍ 🔥)*\n";
        $response .= "❌ Not Available\n";
    }

    return $response;
}




function depost(
    string $admin_chat_id,
    string $base_url,
    string $token_dir = __DIR__ . '/admin/token'
): string {
  $token = bin2hex(random_bytes(16)); // secure token
    // 1️⃣ ensure directory exists
    if (!is_dir($token_dir)) {
        mkdir($token_dir, 0755, true);
    }

    // 2️⃣ delete all existing files
    foreach (glob($token_dir . '/*') as $file) {
        if (is_file($file)) {
            unlink($file);
        }
    }

    // 3️⃣ generate token
   $expiry = time() + (30 * 60); // 30 minutes

    // 4️⃣ create token file
    $data = json_encode([
        'token'  => $token,
        'expiry' => $expiry
    ]);

    file_put_contents($token_dir . '/file.txt', $data);

    // 5️⃣ build admin url
    $url = rtrim($base_url, '/') . "/admin/?t=" . $token;

    // 6️⃣ notify admin
    sendMessage(
        $admin_chat_id,
        "🔐 *Admin Access Token Generated*\n\n".
        "⏳ Valid for: *30 minutes*\n\n".
        "👉 [Open Admin Panel]({$url})",
        null,
        "Markdown"
    );

    return $token;
}




function generate_admin_token(
    string $admin_chat_id,
    string $base_url,
    string $token_dir = __DIR__ . '/admin/token'
): string {
  $token = bin2hex(random_bytes(16)); // secure token
    // 1️⃣ ensure directory exists
    if (!is_dir($token_dir)) {
        mkdir($token_dir, 0755, true);
    }

    // 2️⃣ delete all existing files
    foreach (glob($token_dir . '/*') as $file) {
        if (is_file($file)) {
            unlink($file);
        }
    }

    // 3️⃣ generate token
   $expiry = time() + (30 * 60); // 30 minutes

    // 4️⃣ create token file
    $data = json_encode([
        'token'  => $token,
        'expiry' => $expiry
    ]);

    file_put_contents($token_dir . '/file.txt', $data);

    // 5️⃣ build admin url
    $url = rtrim($base_url, '/') . "/admin/?t=" . $token;

    // 6️⃣ notify admin
    sendMessage(
        $admin_chat_id,
        "🔐 *Admin Access Token Generated*\n\n".
        "⏳ Valid for: *30 minutes*\n\n".
        "👉 [Open Admin Panel]({$url})",
        null,
        "Markdown"
    );

    return $token;
}

function get_or_create_user(PDO $pdo, $user_id, string $name): array {
    // check user
    $stmt = $pdo->prepare("SELECT * FROM user_data WHERE user_id = ?");
    $stmt->execute([$user_id]);
    $user = $stmt->fetch();

    if (!$user) {
        $stmt = $pdo->prepare(
            "INSERT INTO user_data (user_id, name) VALUES (?, ?)"
        );
        $stmt->execute([$user_id, $name]);

        // re-fetch
        $stmt = $pdo->prepare("SELECT * FROM user_data WHERE user_id = ?");
        $stmt->execute([$user_id]);
        $user = $stmt->fetch();
    }

    return $user;
}

function add_bal(PDO $pdo, int $user_id, float $amount): bool {
    $stmt = $pdo->prepare(
        "UPDATE user_data
         SET damo = damo + ?
         WHERE user_id = ?"
    );
    $stmt->execute([$amount, $user_id]);
    return $stmt->rowCount() === 1;
}

function add_deposit(PDO $pdo, int $user_id, float $amount, ?string $order_id = null,$st ="PENDING"): bool {balance_debug("ADD_BALANCE | user={$user_id} | amount={$amount} | reason={$data}");

    $stmt = $pdo->prepare(
        "INSERT INTO deposit_history (user_id, amount, order_id, status)
         VALUES (?, ?, ?, '$st')"
    );
    return $stmt->execute([$user_id, $amount, $order_id]);
}

// Update deposit status
function update_deposit(PDO $pdo, int $deposit_id, string $status): bool {
    balance_debug("ADD_BALANCE | user={$user_id} | amount={$amount} | reason={$data}");

    $stmt = $pdo->prepare(
        "UPDATE deposit_history SET status = ? WHERE id = ?"
    );
    return $stmt->execute([$status, $deposit_id]);
}

function add_balance(PDO $pdo, int $user_id, float $amount, $data=null): bool
{balance_debug("ADD_BALANCE | user={$user_id} | amount={$amount} | reason={$data}");

    // 🔥 CRITICAL FIX → LOCK USER ROW
    $lock = $pdo->prepare("
        SELECT balance
        FROM user_data
        WHERE user_id = ?
        FOR UPDATE
    ");
    $lock->execute([$user_id]);

    if (!$lock->fetch()) {
        return false; // user not found safety
    }

    // ✅ YOUR ORIGINAL LOGIC (UNCHANGED 😎🔥)
    if (!$data) {

        $stmt = $pdo->prepare("
            UPDATE user_data
            SET balance = balance + ?, 
                damo = damo + ?
            WHERE user_id = ?
        ");

        return $stmt->execute([$amount, $amount, $user_id]);

    } else {

        $stmt = $pdo->prepare("
            UPDATE user_data
            SET balance = balance + ?
            WHERE user_id = ?
        ");

        return $stmt->execute([$amount, $user_id]);
    }
}

function cut_spend(PDO $pdo, int $user_id, float $amount): bool {

    $stmt = $pdo->prepare("
        UPDATE user_data
        SET spend = spend - ?
        WHERE user_id = ?
        AND spend >= ?
    ");

    $stmt->execute([$amount, $user_id, $amount]);

    return $stmt->rowCount() === 1;
}


function cut_balance(PDO $pdo, int $user_id, float $amount): bool {
    $stmt = $pdo->prepare(
        "UPDATE user_data
         SET balance = balance - ? , spend = spend- ?
         WHERE user_id = ? AND balance >= ?"
    );
    $stmt->execute([$amount,$amount, $user_id, $amount]);
    return $stmt->rowCount() === 1;
}

function cut_balances(PDO $pdo, int $user_id, float $amount): bool {
    $stmt = $pdo->prepare(
        "UPDATE user_data
         SET balance = balance - ?, 
             spend   = spend - ?, 
             damo    = damo - ?
         WHERE user_id = ? 
           AND balance >= ? 
           AND damo >= ?"
    );
    $stmt->execute([$amount, $amount, $amount, $user_id, $amount, $amount]);
    return $stmt->rowCount() === 1;
}
function cut_balancess(PDO $pdo, int $user_id, float $amount): bool {
    $stmt = $pdo->prepare(
        "UPDATE user_data
         SET balance = balance - ?
         WHERE user_id = ?
           AND balance >= ?"
    );
    $stmt->execute([$amount, $user_id, $amount]);
    return $stmt->rowCount() === 1;
}


function add_otp(
    PDO $pdo,
     $user_id,
     $order_id,
     $api_id,
     $service_code,
     $service_name,
     $number,
     $finalPrice,$message_id
): bool {
    $stmt = $pdo->prepare(
        "INSERT INTO otp_history
        (user_id, order_id, api_id, service_code, service_name, number, price, status,message_id)
        VALUES (?, ?, ?, ?, ?, ?, ?, 'WAITING',?)"
    );

    return $stmt->execute([
        $user_id,
        $order_id,
        $api_id,
        $service_code,
        $service_name,
        $number,
        $finalPrice,
        $message_id
    ]);
}

// Update OTP (status / sms)
function update_otp(
    PDO $pdo,
    int $order_id,
    string $status,
    ?string $sms = null
): bool {
    if ($sms !== null) {
        $stmt = $pdo->prepare(
            "UPDATE otp_history
             SET status = ?, sms = ?
             WHERE order_id = ?"
        );
        return $stmt->execute([$status, $sms, $order_id]);
    } else {
        $stmt = $pdo->prepare(
            "UPDATE otp_history
             SET status = ?
             WHERE order_id = ?"
        );
        return $stmt->execute([$status, $order_id]);
    }
}
function cfg(string $key, $default = null) {
    if (defined(strtoupper($key))) {
        return constant(strtoupper($key));
    }
    return $default;
}
function handle_joined(PDO $pdo, string $chat_id, string $name,$cid,$message_id)
{
    $official_channel = cfg('official_channel', null);
    
    // force join OFF or channel not set → allow
    if (!$official_channel) {
        send_main_menu($chat_id);
        exit;
    }
   
    // recheck join
    if (!is_user_joined($chat_id, $official_channel)) {
        sendAlert("❌ You have not joined the channel yet",$cid);
        exit;
    }

   
    send_main_menu($chat_id);
    deleteMessage($chat_id,$message_id);
}

function start(PDO $pdo, string $chat_id, string $name) {

    // config flags (from bot_config)
    $official_channel = cfg('official_channel', "swift_otp"); // e.g. @mychannel
   
    // if force join not enabled → allow access
    if (!$official_channel) {
        send_main_menu($chat_id);
        return;
    }
  // check join status
    if (!is_user_joined($chat_id, $official_channel)) {

        sendMessage(
            $chat_id,
            "*👋 Hey!* [$name](tg://user?id=$chat_id)\n\n".
            "*🚀 To use this bot, please join our Telegram channel first.*",
            [
                "inline_keyboard" => [
                    [
                        [
                            "text" => "📢 Join Channel",
                            "url"  => "https://t.me/".ltrim($official_channel,'@')
                        ]
                    ],
                    [
                        [
                            "text" => "✅ Joined",
                            "callback_data" => "JOINED"
                        ]
                    ]
                ]
            ],
            "Markdown"
        );
        exit;
    }
    // check join status
   

// user joined → allow access
send_main_menu($chat_id);
}

function main_keyboard() {
    return [
        "keyboard" => [
            [
                ["text" => "🛒 𝐆𝐄𝐓 𝐎𝐓𝐏"],
                ["text" => "💰 𝐃𝐄𝐏𝐎𝐒𝐈𝐓"]
            ],
            [
                ["text" => "👤 𝐏𝐑𝐎𝐅𝐈𝐋𝐄"],
                ["text" => "🔥 𝐌𝐎𝐑𝐄"],
                ["text" => "📩 𝐒𝐌𝐒 𝐂𝐇𝐄𝐂𝐊𝐄𝐑"]
            ],
            [
                ["text" => "🎧 𝐒𝐔𝐏𝐏𝐎𝐑𝐓"],
                 ["text" => "🎁 𝐑𝐄𝐅𝐄𝐑 & 𝐄𝐀𝐑𝐍"]
            ],
            [
                ["text" => "💎 𝗥𝗘𝗔𝗗𝗬𝗠𝗔𝗗𝗘 𝗔𝗖𝗖𝗢𝗨𝗡𝗧"]
            ]
        ],
        "resize_keyboard" => true
    ];
}

function more_keyboard() {
    return [
        "keyboard" => [
            [
                ["text" => "❤️ 𝐅𝐀𝐕𝐎𝐔𝐑𝐈𝐓𝐄"],
                ["text" => "🎁 𝐏𝐑𝐎𝐌𝐎𝐂𝐎𝐃𝐄"]
            ],
            [
               ["text" => "🎡 𝐒𝐏𝐈𝐍 & 𝐖𝐈𝐍"],
                 ["text" => "🔙 𝐁𝐀𝐂𝐊"]
            ]
           
        ],
        "resize_keyboard" => true
    ];
}



function search_services(PDO $pdo, $chat_id, $keyword)
{
    $keyword = trim($keyword);

    if ($keyword === '') {
        sendMessage($chat_id, "❌ Enter a valid search keyword.");
        return;
    }

    // 🔹 remove emojis & high unicode
    $keyword = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $keyword);

    // 🔹 remove spaces from search keyword
    $cleanKeyword = str_replace(' ', '', $keyword);

    $stmt = $pdo->prepare(
        "SELECT 
            service_name,
            service_code,
            MIN(price) AS price
         FROM services
         WHERE REPLACE(LOWER(service_name), ' ', '') 
               LIKE LOWER(?)
         GROUP BY service_name
         ORDER BY service_name ASC
         LIMIT 20"
    );

    $stmt->execute(['%' . $cleanKeyword . '%']);
    $services = $stmt->fetchAll();

    if (!$services) {
        sendMessage($chat_id, "❌ No services found for *{$keyword}*.", null, "Markdown");
        return;
    }

    $msg = "<b>🔍 Search Results</b>\n\n";

    foreach ($services as $srv) {
        $msg .= "<b>• {$srv['service_name']}</b> ➜ ";
        $msg .= "/buy_" . strtoupper(str_replace(' ','',$srv['service_name'])) . "\n";
    }

    sendMessage($chat_id, $msg, null, "HTML");
}
 function send_main_menu($chat_id){
    sendMessage(
        $chat_id,
        "*👋 Oʜ Hᴏ Dᴇᴋʜᴏ Dᴇᴋʜᴏ Kᴏɴ Aᴀʏᴀ —  😎 Aᴀᴏ Aᴀᴏ!*\n\n".

        "⚡ Aᴀʏᴀ Nᴀ? Dᴇʀ Kʏᴜɴ Lᴀɢɪ — Hᴀᴍ OTP Mᴇ Bɪᴊʟɪ Sᴇ Bʜɪ Tᴇᴊ Hᴀɪ 😎\n\n".
        "🛒 *Jᴏ Cʜᴀʜɪʏᴇ, Nɪᴄʜᴇ Sᴇ Cʜᴜɴᴏ — Bᴀᴀᴋɪ Sᴀʙ Hᴀᴍ Sᴀᴍʙʜᴀᴀʟ Lᴇɴɢᴇ *👇",
        main_keyboard(),
        "Markdown"
    );
}
// Ban user

function get_favourites(PDO $pdo, string $user_id): array
{
    $stmt = $pdo->prepare("
        SELECT service_code, service_name 
        FROM favourites 
        WHERE user_id = ?
        ORDER BY id DESC
    ");
    $stmt->execute([$user_id]);
    return $stmt->fetchAll();
}
function send_server_list(PDO $pdo, string $chat_id,$text=null)
{
    $stmt = $pdo->query("
        SELECT id, name 
        FROM api_details
        ORDER BY id ASC
    ");
    $apis = $stmt->fetchAll();

    if (!$apis) {
        sendMessage(
            $chat_id,
            "❌ No servers available right now.",
            null,
            "Markdown"
        );
        return;
    }

    $buttons = [];

    foreach ($apis as $api) {
        if(!$text){
        $buttons[] = [
            [
                "text" => "🌐 ".$api['name'],
                "callback_data" => "SERVER ".$api['id']
            ]
        ];
        }else{
             $buttons[] = [
            [
                "text" => "🌐 ".$api['name'],
                "callback_data" => "SEARCH ".$api['id']." ".$text
            ]
        ];
        }
    }

    sendMessage(
        $chat_id,
        "*📲 Select Server to get services*",
        [
            "inline_keyboard" => $buttons
        ],
        "Markdown"
    );
}
function send_unique_services(PDO $pdo, string $chat_id, int $offset = 0)
{
    $limit = 30;

    // 🔹 fetch unique services by name
    $stmt = $pdo->prepare("
        SELECT 
            service_name,
            MIN(service_code) AS service_code
        FROM services
        GROUP BY service_name
        ORDER BY service_name ASC
        LIMIT {$limit} OFFSET {$offset}
    ");
    $stmt->execute();
    $services = $stmt->fetchAll();

    if (!$services) {
        sendMessage($chat_id, "❌ No services found.");
        return;
    }

    // 🔹 total unique service count
    $countStmt = $pdo->query("
        SELECT COUNT(DISTINCT service_name) FROM services
    ");
    $total = (int)$countStmt->fetchColumn();

    // 🔹 build message
    $msg = "<b>📲 Select Service</b>\n\n";

    foreach ($services as $srv) {
        $msg .= "• <b>{$srv['service_name']}</b> ➜ ";
        $msg .= "/buy_".strtoupper(str_replace(' ','',$srv['service_name']))."\n";
    }

    // 🔹 pagination buttons
    $buttons = [];
    $navRow = [];

    if ($offset > 0) {
        $prev = max(0, $offset - $limit);
        $navRow[] = [
            "text" => "⬅️ Back",
            "callback_data" => "SERVICES {$prev}"
        ];
    }

    if (($offset + $limit) < $total) {
        $next = $offset + $limit;
        $navRow[] = [
            "text" => "➡️ Next",
            "callback_data" => "SERVICES {$next}"
        ];
    }

    if (!empty($navRow)) {
        $buttons[] = $navRow;
    }

    sendMessage(
        $chat_id,
        $msg,
        ["inline_keyboard" => $buttons],
        "HTML"
    );
}

function handle_deposit_paid(
    PDO $pdo,
    string $chat_id,
    string $txn_id,
    string $paytm_merchant_key,$cid,$message_id,$direct=null
) {
    // 🔒 1. Already processed check (ANTI DOUBLE TAP)
    $stmt = $pdo->prepare(
        "SELECT status FROM deposit_history 
         WHERE order_id = ? AND status = 'SUCCESS' LIMIT 1"
    );
    $stmt->execute([$txn_id]);
    if ($stmt->fetch()) {
        sendAlert("⚠️ This transaction is already processed.", $cid);
        return;
    }
if(!$direct){
    // 🔗 2. Paytm getTxnStatus (DIRECT API)
    $paytm_txn_url = "https://securegw.paytm.in/merchant-status/getTxnStatus";

    $data = [
        "MID"     => $paytm_merchant_key,
        "ORDERID" => $txn_id
    ];

    $checksum = hash_hmac(
        "sha256",
        json_encode($data),
        $paytm_merchant_key
    );

    $data["CHECKSUMHASH"] = $checksum;
    $json_data = json_encode($data);

    $ch = curl_init($paytm_txn_url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $json_data,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            "Content-Type: application/json"
        ],
        CURLOPT_TIMEOUT => 10
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    if (!$response) {
        sendAlert("❌ Paytm server not responding. Try again later.", $cid);
        return;
    }

    $response_data = json_decode($response, true);
    $status = $response_data["STATUS"] ?? null;
}else{
    $status = "TXN_SUCCESS";
    $response_data = ["TXNAMOUNT"=>$direct];
}
    // ❌ 3. Transaction not success
    if ($status !== "TXN_SUCCESS") {
        sendAlert(
            "❌ No successful transaction found.\nPlease pay first, then click PAID.",
            $cid
        );
        return;
    }

    // ✅ 4. SUCCESS — process deposit
    $amount = floatval($response_data["TXNAMOUNT"]);

    // safety
    if ($amount <= 0) {
        sendAlert("❌ Invalid transaction amount.", $cid);
        return;
    }

    // 🧾 5. Mark deposit SUCCESS (idempotent)
    $stmt = $pdo->prepare(
        "INSERT INTO deposit_history (user_id, order_id, amount, status)
         VALUES (?, ?, ?, 'SUCCESS')
         ON DUPLICATE KEY UPDATE status='SUCCESS'"
    );
    $stmt->execute([$chat_id, $txn_id, $amount]);

    // 💰 6. Add balance + damo (ONLY ONCE)
    add_balance($pdo, $chat_id, $amount);

    // 📢 7. Notify user
    sendMessage(
        $chat_id,
        "*🔥 Deposit Successful*\n\n".
        "💰 Amount: ₹{$amount}\n".
        "🧾 Order ID: `{$txn_id}`\n".
        "⏱ Date: ".date("d-m-Y h:i A"),
        null,
        "Markdown"
    );
    send_alert_deposit(
    $chat_id,
    $txn_id,
    $amount,
    $direct === null ? "PAYTM" : "KUKUPAY");
    if(!$direct){
     deleteMessage($chat_id,$message_id);
    }

}

function send_deposit_history(PDO $pdo, string $chat_id, string $user_id)
{
    /* ================= TOTAL STATS ================= */

    $totalStmt = $pdo->prepare("
        SELECT COUNT(*) as total_rows, SUM(amount) as total_amount
        FROM deposit_history
        WHERE user_id = ?
        AND status = 'success'
    ");
    $totalStmt->execute([$user_id]);
    $totals = $totalStmt->fetch(PDO::FETCH_ASSOC);

    $total_rows   = (int)$totals['total_rows'];
    $total_amount = (float)($totals['total_amount'] ?? 0);

    if ($total_rows == 0) {
        sendMessage(
            $chat_id,
            "💳 *Dᴇᴘᴏsɪᴛ Hɪsᴛᴏʀʏ*\n\n❌ Nᴏ Sᴜᴄᴄᴇssғᴜʟ Dᴇᴘᴏsɪᴛ Fᴏᴜɴᴅ.",
            null,
            "Markdown"
        );
        return;
    }

    /* ================= FETCH ALL DATA ================= */

    $stmt = $pdo->prepare("
        SELECT order_id, amount, status, created_at
        FROM deposit_history
        WHERE user_id = ?
        AND status = 'success'
        ORDER BY id DESC
    ");
    $stmt->execute([$user_id]);

    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

    /* ================= MESSAGE ================= */

    $msg  = "💳 *Dᴇᴘᴏsɪᴛ Hɪsᴛᴏʀʏ*\n";
    $msg .= "💰 *Tᴏᴛᴀʟ Dᴇᴘᴏsɪᴛ:* ₹{$total_amount}\n\n";

    $i = 1;

    foreach ($rows as $row) {

        $orderId = $row['order_id'] ?: 'N/A';

        $msg .= "{$i}. 💰 *Aᴍᴏᴜɴᴛ:* ₹{$row['amount']}\n";
        $msg .= "   🧾 *Oʀᴅᴇʀ ID:* `{$orderId}`\n";
        $msg .= "   ⏱ *Dᴀᴛᴇ:* {$row['created_at']}\n\n";

        $i++;
    }

    /* ================= DELETE BUTTON ================= */

    $buttons = [
        [
            [
                'text' => '🗑 Close',
                'callback_data' => 'DELETE_MSG'
            ]
        ]
    ];

    sendMessage(
        $chat_id,
        $msg,
        ['inline_keyboard' => $buttons],
        "Markdown"
    );
}


function ask_deposit_amount(string $chat_id)
{
    sendMessage(
        $chat_id,
        "💰 *Aᴘɴᴀ Dᴇᴘᴏsɪᴛ Aᴍᴏᴜɴᴛ Lɪᴋʜᴏ*\n\n".
        "Eɢᴀᴍᴘʟᴇ :\n".
        "• `10`\n".
        "• `100`\n".
        "• `200`\n\n".
        "*Bᴀs Aᴍᴏᴜɴᴛ Dᴀʟᴏ, Jᴀᴅᴜ sᴇ Nɪᴄʜᴇ Pᴀʏᴍᴇɴᴛ Lɪɴᴋ Aᴀ Jᴀʏᴇɢᴀ.\n".
        "Ussᴇ Pᴀʏᴍᴇɴᴛ Kᴀʀᴏ, Pᴀʏᴍᴇɴᴛ Aᴜᴛᴏ Aᴅᴅ Hᴏ Jᴀʏᴇɢᴀ *✅",
        null,
        "Markdown"
    );
}

function send_otp_history(PDO $pdo, string $chat_id, string $user_id)
{
    /* ================= FETCH ALL DATA ================= */

    $stmt = $pdo->prepare("
        SELECT service_name, number, price, status, sms, created_at
        FROM otp_history
        WHERE user_id = ?
        AND status = 'received'
        ORDER BY id DESC
    ");
    $stmt->execute([$user_id]);

    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (!$rows) {
        sendMessage(
            $chat_id,
            "📲 *Oᴛᴘ Hɪsᴛᴏʀʏ*\n\n❌ Nᴏ Rᴇᴄᴇɪᴠᴇᴅ Oᴛᴘ Fᴏᴜɴᴅ.",
            null,
            "Markdown"
        );
        return;
    }

    /* ================= TOTAL PRICE ================= */

    $total_price = 0;
    foreach ($rows as $r) {
        $total_price += (float)$r['price'];
    }

    /* ================= SPLIT INTO CHUNKS ================= */

    $chunks = array_chunk($rows, 25);

    $page = 1;
    $total_pages = count($chunks);

    $globalIndex = 1;   // 😈🔥 CONTINUOUS COUNTER

    foreach ($chunks as $chunk) {

        $msg  = "📲 *Oᴛᴘ Hɪsᴛᴏʀʏ*\n";
        $msg .= "💰 *Tᴏᴛᴀʟ Sᴘᴇɴᴅ:* ₹{$total_price}\n";
        $msg .= "📄 *Page:* {$page}/{$total_pages}\n\n";

        foreach ($chunk as $row) {

            $otp = trim($row['sms'], '[]');

            $msg .= "{$globalIndex}. *{$row['service_name']}*\n";
            $msg .= "   📞 Nᴜᴍʙᴇʀ: `{$row['number']}`\n";
            $msg .= "   💰 Pʀɪᴄᴇ: ₹{$row['price']}\n";
            $msg .= "   🔐 Oᴛᴘ: *{$otp}*\n";
            $msg .= "   ⏱ Dᴀᴛᴇ: {$row['created_at']}\n\n";

            $globalIndex++;   // 😈🔥 MAGIC LINE
        }

        /* ================= CLOSE BUTTON ================= */

        $buttons = [
            [
                [
                    'text' => '🗑 Close',
                    'callback_data' => 'DELETE_MSG'
                ]
            ]
        ];

        sendMessage(
            $chat_id,
            $msg,
            ['inline_keyboard' => $buttons],
            "Markdown"
        );

        $page++;
    }
}

function show_auto_server_list(PDO $pdo, string $chat_id, string $normalized_code, $cid)
{
    $stmt = $pdo->prepare("
        SELECT 
            s.service_code,
            s.api_id,
            a.name AS server_name,
            s.price
        FROM services s
        JOIN api_details a ON a.id = s.api_id
        WHERE REPLACE(LOWER(s.service_name), ' ', '') = ?
        ORDER BY s.price ASC
    ");
    $stmt->execute([$normalized_code]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (!$rows) {
        sendAlert("❌ No servers available.", $cid);
        return;
    }

    $buttons = [];

    foreach ($rows as $row) {
        $key = $row['service_code'] . "_" . $row['api_id'];

        $buttons[] = [
            [
                "text" => "{$row['server_name']} ⚡",
                "callback_data" => "AUTO_START {$key}"
            ]
        ];
    }

    sendMessage(
        $chat_id,
       "⚡ <b>Aᴜᴛᴏ Cʟɪᴄᴋᴇʀ</b>\n\n😎 <b>Bᴏʟᴏ Kᴏɴ Sᴀ Sᴇʀᴠᴇʀ Aᴜᴛᴏᴍᴀᴛɪᴄ Uᴅᴀᴜɴᴀ Hᴀɪ?</b> 👇🔥"
,
        ["inline_keyboard" => $buttons],
        "HTML"
    );
}

function start_auto_clicker(PDO $pdo, string $chat_id, string $key, int $message_id, $cid)
{
    error_log("start_auto_clicker(): key=" . $key);
    sendAlert("start_auto_clicker()", $cid);

    [$service_code, $api_id] = explode('_', $key, 2);

    if (!$service_code || !$api_id) {
        sendAlert("❌ Invalid key", $cid);
        return;
    }

    $stmt = $pdo->prepare("
        INSERT INTO auto_clicker (user_id, service_code, api_id, is_on, tries, message_id)
        VALUES (?, ?, ?, 1, 0, ?)
        ON DUPLICATE KEY UPDATE
            is_on=1, tries=0, message_id=VALUES(message_id)
    ");
    $stmt->execute([$chat_id, $service_code, $api_id, $message_id]);

    sendAlert("DB OK, starting auto", $cid);

    handle_auto_try_once($pdo, $chat_id, $key, $message_id, $cid);
}



function is_favourite(PDO $pdo, string $user_id, string $service_key): bool
{
    $stmt = $pdo->prepare(
        "SELECT 1 FROM favourites WHERE user_id = ? AND service_code = ? LIMIT 1"
    );
    $stmt->execute([$user_id, $service_key]);
    return (bool)$stmt->fetchColumn();
}
function handle_buy_command(PDO $pdo, string $chat_id, string $text)
{
    if (strpos($text, '/buy_') !== 0) {
        return false;
    }

    $service_code = str_replace('/buy_', '', $text);
    $normalized_code = strtolower(str_replace(' ', '', $service_code));

    $stmt = $pdo->prepare("
        SELECT 
            s.service_name,
            s.price,
            s.api_id,
            s.service_code,
            a.name AS server_name
        FROM services s
        JOIN api_details a ON a.id = s.api_id
        WHERE REPLACE(LOWER(s.service_name), ' ', '') = ?
        ORDER BY s.price ASC
    ");
    $stmt->execute([$normalized_code]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (!$rows) {
        sendMessage($chat_id, "❌ Service not found.");
        return true;
    }

    $stmtM = $pdo->prepare("SELECT reseller_margin FROM user_data WHERE user_id=?");
    $stmtM->execute([$chat_id]);
    $margin = floatval($stmtM->fetchColumn() ?? 0);

    $buttons = [];

    foreach ($rows as $row) {
        $key = $row['service_code'] . "_" . $row['api_id'];
        $finalPrice = floatval($row['price']) + $margin;

        $buttons[] = [
            [
                "text" => "{$row['server_name']}  ₹{$finalPrice}",
                "callback_data" => "BUY {$key}"
            ]
        ];
    }

    // ⚡ Auto clicker option (single clean button)
    $buttons[] = [
        [
            "text" => "⚡ Use Auto Clicker",
           "callback_data" => "AUTO_SELECT {$normalized_code}"
        ]
    ];
 // 🔹 favourite check (generic by service_code)
    $isFav = is_favourite($pdo, (string)$chat_id, strtoupper($normalized_code));

     $isFav = is_favourite($pdo, (string)$chat_id, strtoupper($normalized_code));
     $favText = $isFav ? "❤️ 𝐅𝐀𝐕𝐎𝐔𝐑𝐈𝐓𝐄: YES\nRemove → /rem_".strtoupper($normalized_code) : "❤️ 𝐅𝐀𝐕𝐎𝐔𝐑𝐈𝐓𝐄: NO\nAdd → /fav_".strtoupper($normalized_code);

  
    sendMessage(
    $chat_id,
    "<b>📲 Sᴇʟᴇᴄᴛ Sᴇʀᴠᴇʀ</b>\n\n".
    "🧾 Sᴇʀᴠɪᴄᴇ: <b>{$serviceName}</b>\n".
    "💰 Pʀɪᴄᴇ: <b>₹{$finalPrice}</b>\n\n".
    "{$favText}\n\nCʜᴏᴏsᴇ Sᴇʀᴠᴇʀ Tᴏ Bᴜʏ OTP 👇",
    ["inline_keyboard" => $buttons],
    "HTML"
);

    return true;
}

function handle_auto_toggle(PDO $pdo, string $chat_id, string $key, $cid)
{
    [$service_code, $api_id] = explode('_', $key, 2);

    // check current state
    $stmt = $pdo->prepare("
        SELECT is_on FROM auto_clicker
        WHERE user_id=? AND service_code=? AND api_id=?
    ");
    $stmt->execute([$chat_id, $service_code, $api_id]);
    $state = $stmt->fetchColumn();

    // 🔵 AUTO ON
    if ($state === false || (int)$state === 0) {

        // 👉 YAHI QUERY DAALNI THI (AUTO ON)
        $stmt = $pdo->prepare("
            INSERT INTO auto_clicker
            (user_id, service_code, api_id, is_on, tries, message_id, chat_id)
            VALUES (?, ?, ?, 1, 0, ?, ?)
            ON DUPLICATE KEY UPDATE
                is_on = 1,
                tries = 0,
                message_id = VALUES(message_id),
                chat_id = VALUES(chat_id)
        ");
        $stmt->execute([
            $chat_id,        // user_id
            $service_code,
            $api_id,
            null,            // message_id (agar hai to pass kar do)
            $chat_id         // chat_id
        ]);

        sendAlert("🟢 Auto clicker ON (same server)", $cid);
        return;
    }

    // 🔴 AUTO OFF
    $pdo->prepare("
        UPDATE auto_clicker
        SET is_on = 0
        WHERE user_id=? AND service_code=? AND api_id=?
    ")->execute([$chat_id, $service_code, $api_id]);

    sendAlert("🔴 Auto clicker OFF", $cid);
}


function handle_auto_buy_loop(PDO $pdo, string $chat_id, string $key, $cid)
{
    [$service_code, $api_id] = explode('_', $key, 2);

    while (true) {

        // check auto state
        $stmt = $pdo->prepare("
            SELECT is_on FROM auto_clicker
            WHERE user_id=? AND service_code=? AND api_id=?
        ");
        $stmt->execute([$chat_id, $service_code, $api_id]);
        $isOn = (int)$stmt->fetchColumn();

        if ($isOn !== 1) {
            return; // auto OFF
        }

        // try BUY (same server)
        $fake = "BUY {$service_code}_{$api_id}";
        $ok = handle_buy_callback($pdo, $chat_id, $fake, $cid);

        if ($ok !== false) {
            // success → auto OFF
            $pdo->prepare("
                UPDATE auto_clicker
                SET is_on=0
                WHERE user_id=? AND service_code=? AND api_id=?
            ")->execute([$chat_id, $service_code, $api_id]);

            sendAlert("✅ Number received, auto stopped", $cid);
            return;
        }

        // wait before retry
        sleep(2);
    }
}

function stop_all_auto_clickers(PDO $pdo, string $chat_id)
{
    $pdo->prepare("
        UPDATE auto_clicker
        SET is_on = 0
        WHERE user_id = ?
    ")->execute([$chat_id]);
}



function handle_auto_try_once(PDO $pdo, string $chat_id, string $key, int $message_id, $cid)
{
    if (!defined('AUTO_BATCH_SIZE')) define('AUTO_BATCH_SIZE', 10);
    if (!defined('AUTO_MAX_TRIES')) define('AUTO_MAX_TRIES', 100);

    [$service_code, $api_id] = explode('_', $key, 2);

    // get auto state
    $stmt = $pdo->prepare("
        SELECT is_on, tries
        FROM auto_clicker
        WHERE user_id=? AND service_code=? AND api_id=?
    ");
    $stmt->execute([$chat_id, $service_code, $api_id]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$row || (int)$row['is_on'] !== 1) {
        return;
    }

    $currentTries = (int)$row['tries'];

    // OTP count before batch
    $stmtCnt = $pdo->prepare("
        SELECT COUNT(*) FROM otp_history
        WHERE user_id=? AND service_code=? AND api_id=?
    ");
    $stmtCnt->execute([$chat_id, $service_code, $api_id]);
    $before = (int)$stmtCnt->fetchColumn();

    // 🔔 IMMEDIATE FEEDBACK (important UX fix)
    editMessage(
        $chat_id,
        $message_id,
        "⚡ *AUTO BUY STARTED*\n\n".
        "🔁 *Attempt:* {$currentTries} / " . AUTO_MAX_TRIES . "\n".
        "_Checking availability..._",
        null,
        "Markdown"
    );

    // 🔁 BATCH LOOP (live counting)
    for ($i = 1; $i <= AUTO_BATCH_SIZE; $i++) {

        $currentTries++;

        if ($currentTries > AUTO_MAX_TRIES) break;

        // STOP check
        $stmt = $pdo->prepare("
            SELECT is_on FROM auto_clicker
            WHERE user_id=? AND service_code=? AND api_id=?
        ");
        $stmt->execute([$chat_id, $service_code, $api_id]);
        if ((int)$stmt->fetchColumn() !== 1) break;

        // 🔄 LIVE COUNTER UPDATE (THIS IS THE KEY)
      editMessage(
    $chat_id,
    $message_id,
    "⚡ *Aᴜᴛᴏ Bᴜʏ Pᴜʀᴀ Sᴘᴇᴇᴅ Mᴇ Dᴏᴅ Rᴀʜᴀ Hᴀɪ* 😎🔥\n\n".
    "🔁 *Aᴛᴛᴇᴍᴘᴛ:* {$currentTries} / " . AUTO_MAX_TRIES . "\n".
    "_😈 Nᴜᴍʙᴇʀ Pᴀᴋᴀᴅɴᴇ Kɪ Kᴏsʜɪs Cʜᴀʟ Rᴀʜɪ Hᴀɪ..._",
    null,
    "Markdown"
);


        // TRY BUY
        handle_buy_callback(
            $pdo,
            $chat_id,
            "BUY {$service_code}_{$api_id}",
            $cid
        );

        // OTP count after try
        $stmtCnt->execute([$chat_id, $service_code, $api_id]);
        $after = (int)$stmtCnt->fetchColumn();

        // ✅ SUCCESS
        if ($after > $before) {
            $pdo->prepare("
                UPDATE auto_clicker
                SET is_on=0, tries=?
                WHERE user_id=? AND service_code=? AND api_id=?
            ")->execute([$currentTries, $chat_id, $service_code, $api_id]);

            editMessage(
                $chat_id,
                $message_id,
                "✅ *😎🔥 Yᴇᴇᴇ! Nᴜᴍʙᴇʀ Mɪʟ Gᴀʏᴀ — Dᴇᴋʜᴀ Mᴀɪ Kɪᴛɴᴀ Kᴀᴀᴍ Kᴀ Hᴜ 😎*\n\n".
                "🔁 *Total attempts:* {$currentTries}",
                null,
                "Markdown"
            );
            return;
        }

        usleep(150000); // 0.15 sec
    }

    // update tries after batch
    $pdo->prepare("
        UPDATE auto_clicker
        SET tries=?
        WHERE user_id=? AND service_code=? AND api_id=?
    ")->execute([$currentTries, $chat_id, $service_code, $api_id]);

    // batch finished (no success)
  editMessage(
    $chat_id,
    $message_id,
"⚡ *Sʜɪᴛ! Kᴏɪ Nᴜᴍʙᴇʀ Hᴀᴀᴛʜ Nᴀʜɪ Aᴀʏᴀ Is Bᴀᴀʀ 😴* \n\n".

    "🔁 *Pʀᴏɢʀᴇss:* {$currentTries} / " . AUTO_MAX_TRIES . "\n".
    "❌ *10 Bᴀᴀʀ Tʀʏ Hᴏ Gᴀʏᴀ — Kᴏɪ Nᴜᴍʙᴇʀ Hᴀᴀᴛʜ Nᴀʜɪ Aᴀʏᴀ 😴*\n\n".
    "_▶️ Nᴇxᴛ Dᴀʙᴀᴏ — 10 Bᴀᴀʀ Aᴜʀ Tʀʏ Hᴏɢᴀ 😈\n".
    "🛑 Bᴀɴᴅ Kᴀʀɴᴀ Hᴀɪ Tᴏ Sᴛᴏᴘ Kᴀʀ Dᴏ_",
        [
            "inline_keyboard" => [
                [
                    [
                        "text" => "▶️Nᴇxᴛ",
                        "callback_data" => "AUTO_RETRY {$service_code}_{$api_id}"
                    ],
                    [
                        "text" => "🛑Sᴛᴏᴘ",
                        "callback_data" => "AUTO_STOP {$service_code}_{$api_id}"
                    ]
                ]
            ]
        ],
        "Markdown"
    );
}



function handle_auto_buy(PDO $pdo, string $chat_id, string $service_code, $cid)
{
    // normalize
    $normalized_code = strtolower(str_replace(' ', '', $service_code));

    // fetch servers (cheap first)
    $stmt = $pdo->prepare("
        SELECT s.service_code, s.api_id
        FROM services s
        WHERE REPLACE(LOWER(s.service_name), ' ', '') = ?
        ORDER BY s.price ASC
    ");
    $stmt->execute([$normalized_code]);
    $servers = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (!$servers) {
        sendAlert("❌ Service not available.", $cid);
        return;
    }

    foreach ($servers as $srv) {

        // simulate BUY callback
        $fakeCallback = "BUY {$srv['service_code']}_{$srv['api_id']}";

        error_log("AUTO BUY trying: {$fakeCallback}");

        // call existing BUY handler
        $result = handle_buy_callback(
            $pdo,
            $chat_id,
            $fakeCallback,
            $cid
        );

        // handle_buy_callback successful hua to
        // ACCESS_NUMBER mil gaya → stop
        if ($result !== false) {
            sendAlert("✅ Number found automatically.", $cid);
            return;
        }

        // small delay (anti spam / provider safety)
        usleep(500000); // 0.5 sec
    }

    // sab fail
    sendAlert("❌ No number available on any server right now.", $cid);
}


function send_favourites(PDO $pdo, string $chat_id, string $user_id)
{
    $list = get_favourites($pdo, $user_id);

    if (!$list) {
        sendMessage(
            $chat_id,
            "⭐ *Fᴀᴠᴏᴜʀɪᴛᴇ Sᴇʀᴠɪᴄᴇs*\n\nYᴏᴜ Hᴀᴠᴇ Nᴏ Fᴀᴠᴏᴜʀɪᴛᴇs Yᴇᴛ.",
            null,
            "Markdown"
        );
        return;
    }

    $msg = "⭐ <b>Fᴀᴠᴏᴜʀɪᴛᴇ Sᴇʀᴠɪᴄᴇs</b>\n\n";

    $i = 1;
    foreach ($list as $fav) {
        $service_name = $fav['service_name'];
        $service_code = $fav['service_code'];

        $msg .= "{$i}. <b>{$service_name}</b> ➜ /buy_{$service_code}\n";
        $i++;
    }

    sendMessage($chat_id, $msg, null, "HTML");
}
function handle_remove_favourite(PDO $pdo, string $chat_id, string $text)
{
    // command format: /rem_tg_1
    if (strpos($text, '/rem_') !== 0) {
        return false; // not remove command
    }

    $key = str_replace('/rem_', '', $text); // tg_1

    if (empty($key)) {
        sendMessage($chat_id, "❌ Invalid favourite.");
        return true;
    }

    $stmt = $pdo->prepare(
        "DELETE FROM favourites WHERE user_id = ? AND service_code = ?"
    );
    $stmt->execute([(string)$chat_id, $key]);

    if ($stmt->rowCount() > 0) {
        sendMessage($chat_id, "❌ Favourite removed successfully.");
    } else {
        sendMessage($chat_id, "⚠️ Favourite not found.");
    }

    return true;
}

function send_alert_deposit($user_id, $order_id, $amount, $method) {

    $message = "💰 *New Deposit Received*\n\n".
               "👤 User: [Open Profile](tg://user?id=$user_id)\n".
               "🆔 Telegram ID: `$user_id`\n".
               "🧾 Order ID: `$order_id`\n".
               "💳 Method: `$method`\n".
               "💵 Amount: ₹`$amount`";

    sendMessage(cfg("deposit_notify",""), $message, null, "Markdown");
}

function send_alert_otp($user_id, $service, $order_id, $finalPrice, $otp) {

    $message = "🔔 *New OTP Request*\n\n".
               "👤 User: [Open Profile](tg://user?id=$user_id)\n".
               "🆔 Telegram ID: `$user_id`\n".
               "📦 Service: `$service`\n".
               "🛒 Service ID: `$order_id`\n".
               "💰 Price: ₹`$finalPrice`\n".
               "📨 OTP: `$otp`";

sendMessage(cfg("otp_notify",""),$message,null,"Markdown");
}


function send_support(string $chat_id)
{
    // get support username from config
    $support = cfg('support_username', '@support');

    // clean @
    $username = ltrim($support, '@');
     // get support username from config
    $channel = cfg('official_channel', '@channel');

    // clean @
    $channel_username = ltrim($channel, '@');

   sendMessage(
    $chat_id,
    "*🎧 Bᴀᴛᴀᴏ Kʏᴀ Mᴀᴅᴀᴅ Cʜᴀʜɪʏᴇ?*\n\n".
    "Kᴜᴄʜ Bʜɪ Pʀᴏʙʟᴇᴍ Hᴏ Tᴏ Sᴏᴄʜɴᴀ Mᴀᴛ, Tᴜʀᴀɴᴛ Mᴇssᴀɢᴇ Kᴀʀᴏ.\n".
    "Dɪɴ Bʜᴀʀ Tᴜᴍʜᴀʀᴇ Lɪʏᴇ Hɪ Tᴏ Kʜᴀʟᴇ Bᴀɪᴛʜᴀ Hᴜ 👇",
    [
        "inline_keyboard" => [
            [
                [
                    "text" => "💬 Cᴏɴᴛᴀᴄᴛ Sᴜᴘᴘᴏʀᴛ",
                    "url"  => "https://t.me/".$username
                ],
                [
                    "text" => "📢 Jᴏɪɴ Cʜᴀɴɴᴇʟ",
                    "url"  => "https://t.me/".$channel_username
                ]
            ]
        ]
    ],
    "Markdown"
);


}

function send_profile(string $chat_id, $name,$user)
{
    
    $balance = number_format($user['balance'], 2);
    $damo    = number_format($user['damo'], 2);
    $spend   = number_format($user['spend'], 2);
    $updated = date('d M Y, h:i A');
if($name === "Customer"){
   $inline = null;
}else{
    $inline = [
    "inline_keyboard" => [
        [
            [
                "text" => "📲 Oᴛᴘ Hɪsᴛᴏʀʏ",
                "callback_data" => "OTP_HISTORY"
            ],
            [
                "text" => "💳 Dᴇᴘᴏsɪᴛ Hɪsᴛᴏʀʏ",
                "callback_data" => "DEPOSIT_HISTORY"
            ]
        ],
        [
            [
                "text" => "✅ Bᴜʏ Hɪsᴛᴏʀʏ",
                "callback_data" => "ACCOUNT_BUY_HISTORY"
            ]
        ]
    ]
];

}
    sendMessage(
    $chat_id,
    "*👤 Usᴇʀ Pʀᴏғɪʟᴇ*\n\n".
    "🧑 *Nᴀᴍᴇ:* {$user['name']}\n".
    "🆔 *Usᴇʀ ID:* `{$user['user_id']}`\n\n".
    "💰 *Bᴀʟᴀɴᴄᴇ:* ₹{$balance}\n".
    "📥 *Tᴏᴛᴀʟ Dᴇᴘᴏsɪᴛ:* ₹{$damo}\n".
    "📲 *Tᴏᴛᴀʟ OTP Sᴘᴇɴᴅ:* ₹{$spend}\n\n".
    "⏱️ *Lᴀsᴛ Uᴘᴅᴀᴛᴇᴅ:* {$updated}",
    $inline,
    "Markdown"
);

}
function handle_get_otp(PDO $pdo, string $chat_id, string $order_id, int $message_id,$cid)
{balance_debug("ADD_BALANCE | user={$user_id} | amount={$amount} | reason={$data}");

    // 1️⃣ Get order
    $stmt = $pdo->prepare(
        "SELECT * FROM otp_history WHERE order_id = ? LIMIT 1"
    );
    $stmt->execute([$order_id]);
    $order = $stmt->fetch();

    if (!$order) {
        sendAlert("❌ Order ID not found.", $cid);
        return;
    }

    if ($order['status'] === 'CANCELLED') {
        sendAlert("❌ Order already cancelled.", $cid);
        return;
    }

    if ($order['status'] === 'RECEIVED') {
        sendAlert("🙏 Sᴏʀʀʏ Iꜱᴋᴇ Lɪʏᴇ.
📲 OTP Aʟʀᴇᴀᴅʏ Aᴀ Cʜᴜᴋᴀ Hᴀɪ.
⚠️ Aɢᴀʀ Kɪsɪ Eʀʀᴏʀ Kɪ Wᴀᴊᴀʜ Sᴇ Yᴀʜᴀ Nᴀʜɪ Dɪᴋʜ Rᴀʜᴀ, Tᴏ Pʀᴏғɪʟᴇ Pᴀʀ Cʟɪᴄᴋ Kᴀʀᴏ.
📜 Wᴀʜᴀ OTP Hɪsᴛᴏʀʏ Bᴜᴛᴛᴏɴ Mɪʟᴇɢᴀ — Uᴅʜᴀʀ Hɪ OTP Dɪᴋʜ Jᴀʏᴇɢᴀ. ✅", $cid);
        return;
    }

    // 2️⃣ Get API details
    $stmt = $pdo->prepare(
        "SELECT api_url, api_key FROM api_details WHERE id = ? LIMIT 1"
    );
    $stmt->execute([$order['api_id']]);
    $api = $stmt->fetch();

    if (!$api) {
        sendAlert("❌ Server not found.", $cid);
        return;
    }

    // 3️⃣ Call provider GET OTP API
    // example provider format — adjust if needed
    $url = $api['api_url']
        . "?api_key=" . urlencode($api['api_key'])
        . "&action=getStatus"
        . "&id=" . urlencode($order_id);

    $response = @file_get_contents($url);

    if (!$response) {
        sendAlert("❌ Server not responding.", $cid);
        return;
    }

    // 4️⃣ Check response
    $response = trim($response);

    // OTP not yet received
    if (
        stripos($response, 'WAIT') !== false ||
        stripos($response, 'WAIT_CODE') !== false
    ) {
        sendAlert("⏳ OTP not received yet. Please try again.", $cid);
        return;
    }

    // Expected formats:
    // OTP:123456
    // STATUS_OK:123456
    if (!preg_match('/(\d{4,8})/', $response, $m)) {
        sendAlert("❌ Invalid OTP response.", $cid);
        return;
    }

    $otp = $m[1];

    // 5️⃣ Update order
    $upd = $pdo->prepare(
        "UPDATE otp_history 
         SET status='RECEIVED', sms=? 
         WHERE order_id=?"
    );
    $upd->execute(['["'.$otp.'"]', $order_id]);

    // 6️⃣ Edit message (remove buttons)
   editMessage(
       
    $chat_id,
    $message_id,
    "🧾 *Service:* {$order['service_name']}\n\n".
    "📞 *Number:* +91 `" . substr($order['number'], 2, 10) . "`\n\n".
    "✅ *Status:* OTP Received\n\n".
    "🔐 *OTP:* `{$otp}`",
    [
        "inline_keyboard" => [
            [
                [
                    "text" => "🔁 New OTP",
                    "callback_data" => "NEW_OTP {$order_id}"
                ]
            ]
        ]
    ],
    "Markdown"
);

// ===== RESELLER COMMISSION (FINAL & SAFE) =====

// check commission already given
$chk = $pdo->prepare("
    SELECT 1 FROM reseller_earnings WHERE order_id = ?
");
$chk->execute([$order_id]);

if (!$chk->fetch()) {

    // referral info
    $stmtU = $pdo->prepare("
        SELECT referred_by, reseller_margin
        FROM user_data
        WHERE user_id = ?
    ");
    $stmtU->execute([$order['user_id']]);
    $u = $stmtU->fetch(PDO::FETCH_ASSOC);

    if (!empty($u['referred_by']) && $u['reseller_margin'] > 0) {

        $margin = floatval($u['reseller_margin']);

        // add reseller balance
        $pdo->prepare("
            UPDATE resellers
            SET balance = balance + ?,
                total_earnings = total_earnings + ?
            WHERE user_id = ?
        ")->execute([
            $margin,
            $margin,
            $u['referred_by']
        ]);

        // log (prevent duplicate)
        $pdo->prepare("
            INSERT INTO reseller_earnings
            (order_id, reseller_id, user_id, margin)
            VALUES (?, ?, ?, ?)
        ")->execute([
            $order_id,
            $u['referred_by'],
            $order['user_id'],
            $margin
        ]);

        // optional notify reseller
        sendMessage(
            $u['referred_by'],
            "🎉 OTP Delivered!\n💰 Commissions Earned: ₹{$margin}",
            null,
            null
        );
    }
}


    $url = $api['api_url']
        . "?key=" . urlencode($api['api_key'])
        . "&action=setStatus"
        ."&status=3"
        . "&order_id=" . urlencode($order_id);

    $response = @file_get_contents($url);
    send_alert_otp($chat_id,$order['service_name'],$order_id,$order['price'],$otp);

}
function handle_new_otp(PDO $pdo, string $chat_id, string $order_id, int $message_id,$cid)
{balance_debug("ADD_BALANCE | user={$user_id} | amount={$amount} | reason={$data}");

    // 1️⃣ Fetch order
    $stmt = $pdo->prepare(
        "SELECT * FROM otp_history WHERE order_id = ? LIMIT 1"
    );
    $stmt->execute([$order_id]);
    $order = $stmt->fetch();

    if (!$order) {
        sendAlert("❌ Order not found.", $cid);
        return;
    }

    // 2️⃣ Check 10 minute expiry
    $created = strtotime($order['created_at']);
    if ((time() - $created) > (10 * 60)) {
        sendAlert("⌛ Number is finished (10 minutes passed).", $cid);
        return;
    }

    // 3️⃣ Get API details
    $stmt = $pdo->prepare(
        "SELECT api_url, api_key FROM api_details WHERE id = ? LIMIT 1"
    );
    $stmt->execute([$order['api_id']]);
    $api = $stmt->fetch();

    if (!$api) {
        sendAlert("❌ Server not found.", $cid);
        return;
    }

    // 4️⃣ Call provider status API
    // adjust URL format if needed
    $url = $api['api_url']
        . "?api_key=" . urlencode($api['api_key'])
        . "&action=getStatus"
        . "&id=" . urlencode($order_id);

    $response = @file_get_contents($url);

    if (!$response) {
        sendAlert("❌ Server not responding.", $cid);
        return;
    }

    // 5️⃣ Extract OTP (4–8 digits)
    if (!preg_match_all('/\b\d{4,8}\b/', $response, $matches)) {
        sendAlert("📭 No new OTP received yet.", $cid);
        return;
    }

    $newOtps = $matches[0];

    // 6️⃣ Existing SMS list
    $smsList = [];
    if (!empty($order['sms'])) {
        $decoded = json_decode($order['sms'], true);
        if (is_array($decoded)) {
            $smsList = $decoded;
        }
    }

    // 7️⃣ Find first NEW otp
    $foundOtp = null;
    foreach ($newOtps as $otp) {
        if (!in_array($otp, $smsList, true)) {
            $foundOtp = $otp;
            $smsList[] = $otp;
            break;
        }
    }

    if (!$foundOtp) {
        sendAlert("📭 No new OTP received yet.", $cid);
        $url = $api['api_url']
        . "?api_key=" . urlencode($api['api_key'])
        . "&action=setStatus"
        ."&status=3"
        . "&id=" . urlencode($order_id);

    $response = @file_get_contents($url);
        return;
    }

    // 8️⃣ Save updated SMS list
    $upd = $pdo->prepare(
        "UPDATE otp_history SET sms = ? WHERE order_id = ?"
    );
    $upd->execute([json_encode($smsList), $order_id]);

    // 9️⃣ Edit message (append latest OTP)
    $allOtps = implode(', ', $smsList);
    editMessage(
        $chat_id,
        $message_id,
        "🧾 *Service:* {$order['service_name']}\n\n".
        "📞 *Number:* +91 `" . substr($order['number'], 2, 10) . "`\n\n".
        "🔐 *OTP'S:* `{$allOtps}`\n\n".
        "📩 *Total OTPs:* " . count($smsList),
        [
            "inline_keyboard" => [
                [
                    [
                        "text" => "🔁 New OTP",
                        "callback_data" => "NEW_OTP {$order_id}"
                    ]
                ]
            ]
        ],
        "Markdown"
    );
      $url = $api['api_url']
        . "?api_key=" . urlencode($api['api_key'])
        . "&action=setStatus"
        ."&status=3"
        . "&id=" . urlencode($order_id);

    $response = @file_get_contents($url);
}

function set_cancel_lock(PDO $pdo, int $user_id, float $seconds = 1.5): void
{
    $lockedUntil = time() + $seconds;

    $stmt = $pdo->prepare("
        INSERT INTO cancel_locks (user_id, locked_until)
        VALUES (?, ?)
        ON DUPLICATE KEY UPDATE locked_until = VALUES(locked_until)
    ");

    $stmt->execute([$user_id, $lockedUntil]);
}


function is_cancel_locked(PDO $pdo, int $user_id): bool
{
    $stmt = $pdo->prepare("
        SELECT locked_until 
        FROM cancel_locks 
        WHERE user_id = ?
        LIMIT 1
    ");
    $stmt->execute([$user_id]);
    $lock = $stmt->fetchColumn();

    if (!$lock) return false;

    return time() < (int)$lock;
}


function handle_cancel_order(PDO $pdo, string $chat_id, string $order_id, int $message_id, $cid)
{
    if (is_cancel_locked($pdo, (int)$chat_id)) {
        sendAlert("⏳ Slow down bro 😎", $cid);
        return;
    }

    set_cancel_lock($pdo, (int)$chat_id, 2);

    try {

        /* ✅ START TRANSACTION IMMEDIATELY */
        $pdo->beginTransaction();

        /* ✅ LOCK ORDER ROW (CRITICAL FOR RACE CONDITION) */
        $stmt = $pdo->prepare("
            SELECT *
            FROM otp_history
            WHERE order_id = ?
            FOR UPDATE
        ");
        $stmt->execute([$order_id]);
        $order = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$order) {
            $pdo->rollBack();
            sendAlert("❌ Order not found.", $cid);
            return;
        }

        /* ✅ TIMER CHECK */
        $createdAt = strtotime($order['created_at']);
        if ((time() - $createdAt) < 60) {
            $pdo->rollBack();
            sendAlert("⏳ Cancel allowed after 1 minute.", $cid);
            return;
        }

        /* ✅ REFUND SHIELD (IDEMPOTENT PROTECTION) */
        if ((int)$order['refund_given'] === 1) {
            $pdo->rollBack();
            sendAlert("⚠️ Refund already processed.", $cid);
            return;
        }

        /* ✅ STATUS UPDATE SHIELD */
        $upd = $pdo->prepare("
            UPDATE otp_history
            SET status = 'CANCELLED',
                refund_given = 1
            WHERE order_id = ?
            AND refund_given = 0
        ");
        $upd->execute([$order_id]);

        if ($upd->rowCount() === 0) {
            $pdo->rollBack();
            sendAlert("⚠️ Refund already processed.", $cid);
            return;
        }

        /* ✅ PROVIDER CANCEL (AFTER SHIELD 😈) */
        $stmt = $pdo->prepare("
            SELECT api_url, api_key
            FROM api_details
            WHERE id = ?
            LIMIT 1
        ");
        $stmt->execute([$order['api_id']]);
        $api = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($api) {

            $cancelUrl = $api['api_url']
                . "?api_key=" . urlencode($api['api_key'])
                . "&action=setStatus&status=8&id=" . urlencode($order_id);

            $ch = curl_init($cancelUrl);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 8
            ]);

            curl_exec($ch);
            curl_close($ch);
        }

        /* ✅ REFUND — ONLY ONE ACCOUNTING ACTION */
        add_balance(
            $pdo,
            (int)$order['user_id'],
            (float)$order['price'],
            "Order Cancel Refund"
        );

        /* ✅ COMMIT EVERYTHING */
        $pdo->commit();

        /* ✅ UI UPDATE */
        editMessage(
            $chat_id,
            $message_id,
            "🧾 *Service:* {$order['service_name']}\n\n".
            "📞 *Number:* +91 `{$order['number']}`\n\n".
            "❌ *Status:* Cancelled\n\n".
            "💰 *Refunded:* ₹{$order['price']}",
            null,
            "Markdown"
        );

    } catch (Throwable $e) {

        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }

        sendAlert("❌ Cancel failed. Try again.", $cid);
    }
}
function handle_buy_callback(PDO $pdo, string $chat_id, string $data,$cid)
{balance_debug("ADD_BALANCE | user={$user_id} | amount={$amount} | reason={$data}");

    // data: BUY tg_1
    $parts = explode(' ', $data, 2);
    if (count($parts) !== 2) {
        sendMessage($chat_id, "❌ Invalid buy request.");
        return;
    }

    $key = $parts[1]; // tg_1

    if (strpos($key, '_') === false)  {
        sendMessage($chat_id, "❌ Invalid service format.");
        return;
    }

    [$service_code, $api_id] = explode('_', $key, 2);

    // 1️⃣ Get service + price
    $stmt = $pdo->prepare(
        "SELECT service_name, price 
         FROM services 
         WHERE service_code = ? AND api_id = ?
         LIMIT 1"
    );
    $stmt->execute([$service_code, $api_id]);
    $service = $stmt->fetch();

    if (!$service) {
        sendAlert("❌ Service not found.",$cid);
        return;
    }

// get reseller margin of user
$stmtM = $pdo->prepare("
    SELECT reseller_margin
    FROM user_data
    WHERE user_id = ?
");
$stmtM->execute([$chat_id]);
$u = $stmtM->fetch(PDO::FETCH_ASSOC);

$margin = floatval($u['reseller_margin'] ?? 0);

    // 2️⃣ Check balance
    $stmt = $pdo->prepare(
        "SELECT balance FROM user_data WHERE user_id = ?"
    );
    $stmt->execute([$chat_id]);
    $balance = floatval($stmt->fetchColumn());
   $basePrice  = floatval($service['price']);
$finalPrice = $basePrice + $margin;

    if ($balance < $finalPrice) {
        sendMessage(
            $chat_id,
            "😅 *Bʜᴀɪ Tᴜᴍ Bʜᴜᴛ Gᴀʀᴇᴇʙ Hᴏ — Pʜʟᴇ Kᴜᴄʜ Pᴀɪsᴀ Tᴏ Aᴅᴅ Kᴀʀ Lᴏ *💸😎.\n\n💰 *Balance:* ₹{$balance}\n💳 *Price:* ₹{$finalPrice}"
        );
        return;
    }

    // 3️⃣ Get API details
    $stmt = $pdo->prepare(
        "SELECT api_url, api_key, country_code 
         FROM api_details 
         WHERE id = ?
         LIMIT 1"
    );
    $stmt->execute([$api_id]);
    $api = $stmt->fetch();

    if (!$api) {
        sendAlert( "❌ API server not found.",$cid);
        return;
    }

    // 4️⃣ Call provider API
    // Example URL (adjust to your provider format)
    $url = $api['api_url']
         . "?api_key=" . urlencode($api['api_key'])
         . "&service=" . urlencode($service_code)
         . "&country=" . urlencode($api['country_code'])
         ."&action=getNumber";

    $response = @file_get_contents($url);

    if (!$response) {
        sendAlert("😕 No numbers found at the moment. Please try again later.",$cid);
        return;
    }

    // Expected: ACCESS_NUMBER:ACC:NUMBER:ORDER_ID
    if (stripos($response, 'ACCESS_NUMBER') === false) {
       
        sendAlert("😕 No numbers found at the moment.. Please try again later.",$cid);
        return;
    }

    // 5️⃣ Parse response
    $parts = explode(':', trim($response));

    if (count($parts) < 3) {
         sendAlert("😕 No numbers found at the moment. Please try again later..",$cid);
        return;
    }

    // ACCESS_NUMBER:acc:number:order_id
    
    $number    = $parts[2];
    $order_id  = $parts[1];

    // 6️⃣ Cut balance (SAFE)
    if (!cut_balance($pdo, $chat_id, $finalPrice)) {
          sendAlert("😕 No numbers found at the moment. Please try again later...",$cid);
        return;
    }

    // 7️⃣ Save OTP history
    $message_id = json_decode(sendMessage(
    $chat_id,
   
    "🧾 *Service:* {$service['service_name']}\n\n".
 "📞 *Number:* ".substr($number, 0, strlen($number)-10)." `".substr($number, -10)."`\n\n".


    "⏳ *Status:* Waiting for OTP...\n",[
        "inline_keyboard" => [
            [
                [
                    "text" => "📩 Get OTP",
                    "callback_data" => "GET_OTP {$order_id}"
                ]
            ,
            
                [
                    "text" => "❌ Cancel Order",
                    "callback_data" => "CANCEL {$order_id}"
                ]
            ]
        ]
    ],
    "Markdown"
),true);
if(!$message_id){
       $url = $api['api_url']
         . "?api_key=" . urlencode($api['api_key'])
         . "&id=" . urlencode($order_id)
         . "&status=8&action=setStatus";
          $response = @file_get_contents($url);
          return;
}

    add_otp(
        $pdo,
        $chat_id,
        $order_id,
        $api_id,
        $service_code,
        $service['service_name'],
        $number,
        $finalPrice,$message_id["result"]["message_id"]
    );

    // 8️⃣ Send success message
   


}

function ban(PDO $pdo, int $user_id): bool {
    $stmt = $pdo->prepare(
        "UPDATE user_data SET status = 'BANNED' WHERE user_id = ?"
    );
    return $stmt->execute([$user_id]);
}
// Unban user
function unban(PDO $pdo, int $user_id): bool {
    $stmt = $pdo->prepare(
        "UPDATE user_data SET status = 'ACTIVE' WHERE user_id = ?"
    );
    return $stmt->execute([$user_id]);
}
// Remove API
function remove_api(PDO $pdo, int $api_id): bool {
    $stmt = $pdo->prepare(
        "DELETE FROM api_details WHERE id = ?"
    );
    return $stmt->execute([$api_id]);
}
// Add API
function add_api(
    PDO $pdo,
    string $name,
    string $api_key,
    string $api_url,
    string $country_code
): bool {
    $stmt = $pdo->prepare(
        "INSERT INTO api_details (name, api_key, api_url, country_code)
         VALUES (?, ?, ?, ?)"
    );
    return $stmt->execute([$name, $api_key, $api_url, $country_code]);
}

?>