<?php

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_deposit(PDO $pdo, int $user_id, float $amount, ?string $order_id = null,$st ="PENDING"): bool {
    $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 {
    $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 {
    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 = ?");
  
      return $stmt->execute([$amount, $user_id]);
    
   
}

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 add_otp(
    PDO $pdo,
     $user_id,
     $order_id,
     $api_id,
     $service_code,
     $service_name,
     $number,
     $price,$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,
        $price,
        $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;
    }

    // joined → allow access
    sendMessage(
        $chat_id,
        "✅ *Access granted!*\nWelcome $name 👋",
        null,
        "Markdown"
    );

    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;
    }

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

function main_keyboard() {
    return [
        "keyboard" => [
            [
                ["text" => "📲 Get OTP"],
                ["text" => "➕ Deposit"]
            ],
            [
                ["text" => "👤 Profile"],
                ["text" => "⭐ Favourite"]
            ],
            [
                ["text" => "🆘 Support"]
            ]
        ],
        "resize_keyboard" => true,
        "one_time_keyboard" => false
    ];
}
function search_services(PDO $pdo,  $chat_id,  $keyword)
{
    $keyword = trim($keyword);

    if ($keyword === '') {
        sendMessage($chat_id, "❌ Enter a valid search keyword.");
        return;
    }
$keyword = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $keyword);

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

$stmt->execute(['%' . $keyword . '%']);
$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) {
        $key = $srv['service_code'];
        $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,
    " *🔥 Wᴇʟᴄᴏᴍᴇ Tᴏ Sᴡɪꜰᴛ OTP Bᴏᴛ 🔥*\n\n🚀 Lɪɢʜᴛ Sᴇ Bʜɪ Tᴇᴊ Sᴘᴇᴇᴅ 🚀
\n🛒 Sᴇʟᴇᴄᴛ ᴀɴ ᴏᴘᴛɪᴏɴ ʙᴇʟᴏᴡ: 👇",
    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)
{
    $stmt = $pdo->prepare("
        SELECT order_id, amount, status, created_at
        FROM deposit_history
        WHERE user_id = ?
        ORDER BY id DESC
        LIMIT 20
    ");
    $stmt->execute([$user_id]);
    $rows = $stmt->fetchAll();

    if (!$rows) {
        sendMessage(
            $chat_id,
            "💳 *Deposit History*\n\nNo deposit history found.",
            null,
            "Markdown"
        );
        return;
    }

    $msg = "💳 *Deposit History (Last 20)*\n\n";

    $i = 1;
    foreach ($rows as $row) {
        $orderId = $row['order_id'] ?: 'N/A';

        $msg .= "{$i}. 💰 Amount: ₹{$row['amount']}\n";
        $msg .= "   🧾 Order ID: `{$orderId}`\n";
        $msg .= "   📌 Status: *{$row['status']}*\n";
        $msg .= "   ⏱ Date: {$row['created_at']}\n\n";
        $i++;
    }

    sendMessage($chat_id, $msg, null, "Markdown");
}
function ask_deposit_amount(string $chat_id)
{
    sendMessage(
        $chat_id,
        "💰 *Enter deposit amount*\n\n".
        "Example:\n".
        "• `100`\n".
        "• `110`\n".
        "• `1000`\n\n".
        "Type only the amount (numbers only).",
        null,
        "Markdown"
    );
}

function send_otp_history(PDO $pdo, string $chat_id, string $user_id)
{
    $stmt = $pdo->prepare("
        SELECT service_name, number, price, status, created_at
        FROM otp_history
        WHERE user_id = ?
        ORDER BY id DESC
        LIMIT 20
    ");
    $stmt->execute([$user_id]);
    $rows = $stmt->fetchAll();

    if (!$rows) {
        sendMessage(
            $chat_id,
            "📲 *OTP History*\n\nNo OTP history found.",
            null,
            "Markdown"
        );
        return;
    }

    $msg = "📲 *OTP History (Last 20)*\n\n";

    $i = 1;
    foreach ($rows as $row) {
        $msg .= "{$i}. *{$row['service_name']}*\n";
        $msg .= "   📞 Number: `{$row['number']}`\n";
        $msg .= "   💰 Price: ₹{$row['price']}\n";
        $msg .= "   📌 Status: *{$row['status']}*\n";
        $msg .= "   ⏱ Date: {$row['created_at']}\n\n";
        $i++;
    }

    sendMessage($chat_id, $msg, null, "Markdown");
}
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)
{
    // example: /buy_tg
    if (strpos($text, '/buy_') !== 0) {
        return false;
    }

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

    if ($service_code === '') {
        sendMessage($chat_id, "❌ Invalid service.");
        return true;
    }
$normalized_code = strtolower(str_replace(' ', '', $service_code));

    // 🔹 fetch ALL servers for this service
 $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();


    if (!$rows) {
        sendMessage($chat_id, "❌ Service not found.");
        return true;
    }
$service_code  = $rows[0]['service_code'];
    $serviceName = $rows[0]['service_name'];

    // 🔹 build buttons (server wise)
    $buttons = [];
    foreach ($rows as $row) {
        $service_code  = $row['service_code'];
        $key = $service_code . "_" . $row['api_id'];

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

    // 🔹 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 ? "⭐ Favourite: YES\nRemove → /rem_".strtoupper($normalized_code) : "⭐ Favourite: NO\nAdd → /fav_".strtoupper($normalized_code);

  
    // 🔹 send UI
    sendMessage(
        $chat_id,
        "<b>📲 Select Server</b>\n\n".
        "🧾 Service: <b>{$serviceName}</b>\n\n$favText\n\nChoose server to buy OTP 👇",
        ["inline_keyboard" => $buttons],
        "HTML"
    );

    return true;
}


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

    if (!$list) {
        sendMessage(
            $chat_id,
            "⭐ *Favourite Services*\n\nYou have no favourites yet.",
            null,
            "Markdown"
        );
        return;
    }

    $msg = "⭐ <b>Favourite Services</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, $price, $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: ₹`$price`\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, '@');

    sendMessage(
        $chat_id,
        "*🆘 Support Center*\n\n".
        "Need help? Contact our support team 👇",
        [
            "inline_keyboard" => [
                [
                    [
                        "text" => "💬 Contact Support",
                        "url"  => "https://t.me/".$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" => "📲 OTP History", "callback_data" => "OTP_HISTORY"],
                    ["text" => "💳 Deposit History", "callback_data" => "DEPOSIT_HISTORY"]
                ]
            ]
        ];
}
    sendMessage(
        $chat_id,
        "*👤 User Profile*\n\n".
        "🧑 *Name:* {$user['name']}\n".
        "🆔 *User ID:* `{$user['user_id']}`\n\n".
        "💰 *Balance:* ₹{$balance}\n".
        "📥 *Total Deposit:* ₹{$damo}\n".
        "📲 *Total OTP Spend:* ₹{$spend}\n\n".
        "⏱️ *Last Updated:* {$updated}",
       $inline,
        "Markdown"
    );
}
function handle_get_otp(PDO $pdo, string $chat_id, string $order_id, int $message_id,$cid)
{
    // 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("✅ OTP already received.", $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"
);
    $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)
{
    // 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 handle_cancel_order(PDO $pdo, string $chat_id, string $order_id, int $message_id, $cid)
{
    try {
        $pdo->beginTransaction();

        // 1️⃣ Lock order row (VERY IMPORTANT)
        $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 ID not found.", $cid);
            return;
        }

        // Already cancelled → NO REFUND
        if ($order['status'] === 'CANCELLED') {
            $pdo->commit();
            sendAlert("⚠️ This order is already cancelled.", $cid);
            return;
        }

        if ($order['status'] !== 'WAITING') {
            $pdo->rollBack();
            sendAlert("⚠️ This order cannot be cancelled.", $cid);
            return;
        }

        // 2️⃣ Provider 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(PDO::FETCH_ASSOC);

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

        // 3️⃣ Provider status check
        $statusUrl = $api['api_url']
            . "?api_key=" . urlencode($api['api_key'])
            . "&action=getStatus&id=" . urlencode($order_id);

        $statusResp = @file_get_contents($statusUrl);

        if (!$statusResp || stripos($statusResp, 'WAIT_CODE') === false) {
            $pdo->rollBack();
            sendAlert("⚠️ Order already processed click get otp button.", $cid);
            return;
        }

        // 4️⃣ Cancel on provider
        $cancelUrl = $api['api_url']
            . "?api_key=" . urlencode($api['api_key'])
            . "&action=setStatus&status=8&id=" . urlencode($order_id);

        $cancelResp = @file_get_contents($cancelUrl);

        if (!$cancelResp) {
            $pdo->rollBack();
            sendAlert("❌ Server not responding.", $cid);
            return;
        }

        if (stripos($cancelResp, 'EARLY') !== false) {
            $pdo->rollBack();
            sendAlert("⏳ Cancellation possible after 2 minutes.", $cid);
            return;
        }

        // 5️⃣ UPDATE with condition (ANTI DOUBLE REFUND)
        $upd = $pdo->prepare(
            "UPDATE otp_history 
             SET status = 'CANCELLED' 
             WHERE order_id = ? AND status = 'WAITING'"
        );
        $upd->execute([$order_id]);

        // If already updated by another click
        if ($upd->rowCount() === 0) {
            $pdo->commit();
            sendAlert("⚠️ Refund already processed.", $cid);
            return;
        }

        // 6️⃣ Refund ONLY ONCE
        add_balance(
            $pdo,
            (int)$order['user_id'],
            (float)$order['price'],
            "Order Cancel Refund"
        );

        $pdo->commit();

        // 7️⃣ Edit message
        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 (Exception $e) {
        $pdo->rollBack();
        sendAlert("❌ Internal error. Please try again.", $cid);
    }
}

function handle_buy_callback(PDO $pdo, string $chat_id, string $data,$cid)
{
    // 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;
    }


    // 2️⃣ Check balance
    $stmt = $pdo->prepare(
        "SELECT balance FROM user_data WHERE user_id = ?"
    );
    $stmt->execute([$chat_id]);
    $balance = floatval($stmt->fetchColumn());
    $price  =$service['price'];
    if ($balance < $price) {
        sendMessage(
            $chat_id,
            "❌ Insufficient balance.\n\n💰 Balance: ₹{$balance}\n💳 Price: ₹{$price}"
        );
        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, $price)) {
          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,
        $price,$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]);
}

?>