<?php
ob_start();

// Database Configuration
$host = "localhost";
$dbname = "<PUT-YOUR-DBNAME>";
$user = "<PUT-YOUR-DBUSER>";
$password = "<PUT-YOUR-DBPASSWORD>";

// Telegram Configuration
$botToken = "<PUT-YOUR-TOKEN>";
$adminChatId = "<PUT-YOUR-ADMINID>";

// Connect to Database
try {
    $conn = new PDO("mysql:host=$host;dbname=$dbname", $user, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    error_log("Database connection failed: " . $e->getMessage());
    exit;
}

class TelegramOrderBot {
    private $conn;
    private $botToken;
    private $adminChatId;
    
    public function __construct($conn, $botToken, $adminChatId) {
        $this->conn = $conn;
        $this->botToken = $botToken;
        $this->adminChatId = $adminChatId;
        $this->adminIds = [ (int)$adminChatId ]; 
    }
    
public function handleUpdate($update) {
    if (isset($update['callback_query'])) {
        $this->handleCallback($update['callback_query']);
    } elseif (isset($update['message'])) {
        $this->handleMessage($update['message']);
    }
}

private function isAdmin($telegramUserId) {
    return in_array((int)$telegramUserId, $this->adminIds, true);
}

private function handleCallback($callback) {
    $data = $callback['data'];
    $chatId = $callback['message']['chat']['id'];
    $messageId = $callback['message']['message_id'];
    $adminId = $callback['from']['id'];

    // ======================================================
    // ✅ APPROVE ADD FUNDS (existing logic)
    // ======================================================
if (strpos($data, 'approve_') === 0 && strpos($data, 'cancel_') === false) {
    list(, $telegramId, $amount) = explode('_', $data);
    $amount = floatval($amount);

    // Get client by Telegram ID
    $stmt = $this->conn->prepare("SELECT * FROM clients WHERE telegram_id = ?");
    $stmt->execute([$telegramId]);
    $client = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$client) {
        $this->sendMessage($chatId, "❌ Error: User with Telegram ID `$telegramId` not found.");
        return;
    }

    // ✅ Correct column name
    $clientId = $client['client_id'];
    $currentBalance = $client['balance'];
    $newBalance = $currentBalance + $amount;

    try {
        $this->conn->beginTransaction();

        // ✅ Update balance correctly
        $update = $this->conn->prepare("UPDATE clients SET balance = ? WHERE client_id = ?");
        $update->execute([$newBalance, $clientId]);

        // ✅ Insert into payments table
        $insert = $this->conn->prepare("
            INSERT INTO payments 
                (client_id, client_balance, payment_amount, payment_fee, payment_method, payment_status, payment_delivery, payment_create_date, payment_ip, payment_extra)
            VALUES (?, ?, ?, 0.00, 1, 3, 2, NOW(), ?, 'Approved via Telegram Bot')
        ");
        $insert->execute([
            $clientId,
            $newBalance, // ✅ new balance after update
            $amount,
            $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'
        ]);

        $this->conn->commit();

        // 🧹 Remove buttons
        $this->editMessage(
            $chatId,
            $messageId,
            "✅ ₱$amount approved for user `$telegramId`",
            ['parse_mode' => 'Markdown']
        );

        // 💬 Admin confirmation
        $this->sendMessage(
            $chatId,
            "💰 *Confirmation:* ₱$amount has been added to `$telegramId`’s account successfully.",
            ['parse_mode' => 'Markdown']
        );

        // 💬 Notify user
        $this->sendMessage(
            $telegramId,
            "✅ Your ₱$amount payment has been approved and added to your balance. Thank you!",
            ['parse_mode' => 'Markdown']
        );

    } catch (Exception $e) {
        $this->conn->rollBack();
        $this->sendMessage($chatId, "❌ Transaction failed: " . $e->getMessage());
    }
}

// ======================================================
// ❌ REJECT ADD FUNDS (Admin side)
// ======================================================
if (strpos($data, 'reject_') === 0 && strpos($data, 'cancel_') === false) {
    $telegramId = str_replace('reject_', '', $data);

    // 🧹 Remove buttons
    $this->editMessage(
        $chatId,
        $messageId,
        "❌ Payment rejected for user `$telegramId`",
        ['parse_mode' => 'Markdown']
    );

    // 💬 Admin confirmation
    $this->sendMessage(
        $chatId,
        "🚫 *Confirmation:* Payment for `$telegramId` has been rejected successfully.",
        ['parse_mode' => 'Markdown']
    );

    // 💬 Notify user
    $this->sendMessage(
        $telegramId,
        "❌ Your payment has been rejected. Please contact support if this is a mistake.",
        ['parse_mode' => 'Markdown']
    );
}

// ======================================================
// ✅ APPROVE / DECLINE CANCEL REQUEST (fixed, keep same format)
// ======================================================
if (strpos($data, 'approve_cancel_') === 0) {
        // format: approve_cancel_{telegramId}_{orderId}
        $parts = explode('_', $data);
        $userTelegramId = $parts[2] ?? null;
        $orderId = $parts[3] ?? null;

        if (!$userTelegramId || !$orderId) {
            $this->sendMessage($adminId, "⚠️ Invalid callback data.");
            return;
        }

        // fetch order and ensure cancel requested
        $stmt = $this->conn->prepare("SELECT * FROM orders WHERE order_id = ? AND cancel_requested = 1 LIMIT 1");
        $stmt->execute([$orderId]);
        $order = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$order) {
            $this->sendMessage($adminId, "❌ Order #{$orderId} not found or not requested for cancel.");
            return;
        }

        try {
            $this->conn->beginTransaction();

            // mark canceled and clear cancel_requested
            $update = $this->conn->prepare("
                UPDATE orders SET order_status = 'canceled', cancel_requested = 0, order_error = 'Canceled by admin', last_check = NOW()
                WHERE order_id = ?
            ");
            $update->execute([$orderId]);

            // refund client: find client_id from order
            $clientId = $order['client_id'];
            $refundAmount = (float)$order['order_charge'];

            if ($refundAmount > 0) {
                $refund = $this->conn->prepare("
                    UPDATE clients SET balance = balance + ?, spent = spent - ? WHERE client_id = ?
                ");
                $refund->execute([$refundAmount, $refundAmount, $clientId]);

                // optionally insert a payments/refund record
                $ins = $this->conn->prepare("
                    INSERT INTO payments (client_id, client_balance, payment_amount, payment_method, payment_status, payment_delivery, payment_mode, payment_create_date, payment_ip, payment_extra)
                    VALUES (?, ?, ?, 1, 3, 2, 'Telegram', NOW(), ?, ?)
                ");
                // fetch current balance to store (simple approach: skip exact balance snapshot or select)
                $ins->execute([$clientId, 0, $refundAmount, $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1', "Refund via Telegram approval"]);
            }

            $this->conn->commit();

            // notify user
            $this->sendMessage($userTelegramId, "✅ Your cancellation request for Order *#{$orderId}* has been *approved* by admin and refunded (₱" . number_format($refundAmount,2) . ").", ['parse_mode' => 'Markdown']);

            // edit admin message if possible
            if ($chatId && $messageId) {
                $this->editMessage($chatId, $messageId, "✅ Order #{$orderId} has been *Canceled* and refund completed.", ['parse_mode' => 'Markdown']);
            } else {
                $this->sendMessage($adminId, "✅ Order #{$orderId} canceled and refunded.");
            }
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Cancel approve failed: " . $e->getMessage());
            $this->sendMessage($adminId, "⚠️ Error approving cancel: " . $e->getMessage());
        }
        return;
    }

    // DECLINE cancel
    if (strpos($data, 'decline_cancel_') === 0 || strpos($data, 'reject_cancel_') === 0) {
        $parts = explode('_', $data);
        $userTelegramId = $parts[2] ?? null;
        $orderId = $parts[3] ?? null;

        if (!$userTelegramId || !$orderId) {
            $this->sendMessage($adminId, "⚠️ Invalid callback data.");
            return;
        }

        // mark cancel_requested = 0 (declined)
        $stmt = $this->conn->prepare("UPDATE orders SET cancel_requested = 0 WHERE order_id = ?");
        $stmt->execute([$orderId]);

        // notify user & admin
        $this->sendMessage($userTelegramId, "❌ Your cancellation request for Order *#{$orderId}* has been declined by admin.", ['parse_mode' => 'Markdown']);
        if ($chatId && $messageId) {
            $this->editMessage($chatId, $messageId, "❌ Cancel request for Order #{$orderId} has been *Declined*.", ['parse_mode' => 'Markdown']);
        } else {
            $this->sendMessage($adminId, "❌ Cancel request for Order #{$orderId} declined.");
        }
        return;
    }
}

private $pendingUsernames = [];

private function handleMessage($message) {
    $chatId = $message['chat']['id'];
    $text = trim($message['text'] ?? '');
    $userId = $message['from']['id'];
    $isAdmin = ($chatId == $this->adminChatId);
    $fromUser = $message['from']['username'] ?? 'NoUsername';

    // --- On /start ---
if (strtolower($text) === "/start") {
    $stmt = $this->conn->prepare("SELECT username, spent FROM clients WHERE telegram_id = ?");
    $stmt->execute([$userId]);
    $user = $stmt->fetch();

    if ($user) {
        // Already linked
        $spent = $user['spent'] ?? 0;
        $loyalty = $this->getLoyaltyLevel($spent);
        $this->sendMessage(
            $chatId,
            "👋 Welcome back, *{$user['username']}*!\n🎖 Loyalty Tier: {$loyalty}\n💰 Spent: ₱" . number_format($spent, 2),
            ['parse_mode' => 'Markdown']
        );
        $this->showMainMenu($chatId, $isAdmin);
    } else {
        // Set temp state in bot_states
        $this->conn->prepare("INSERT INTO bot_states (telegram_id, state) VALUES (?, 'awaiting_username')
            ON DUPLICATE KEY UPDATE state='awaiting_username'")->execute([$userId]);

        $this->sendMessage($chatId, "👋 Please reply with your *website username* to register.", ['parse_mode'=>'Markdown']);
    }
    return;
}

// --- If awaiting username ---
$stmt = $this->conn->prepare("SELECT state FROM bot_states WHERE telegram_id = ?");
$stmt->execute([$userId]);
$state = $stmt->fetchColumn();

if ($state === 'awaiting_username') {
    $username = preg_replace('/[^a-zA-Z0-9_.-]/', '', $text);

    $stmt = $this->conn->prepare("SELECT * FROM clients WHERE username = ?");
    $stmt->execute([$username]);
    $client = $stmt->fetch();

    if ($client) {
        // Link Telegram ID
        $this->conn->prepare("UPDATE clients SET telegram_id=? WHERE username=?")
            ->execute([$userId, $username]);

        // Clear state
        $this->conn->prepare("DELETE FROM bot_states WHERE telegram_id=?")->execute([$userId]);

        $this->sendMessage($chatId, "✅ Registered successfully as *$username*!", ['parse_mode'=>'Markdown']);
        $this->showMainMenu($chatId, $isAdmin);
    } else {
        $this->sendMessage($chatId, "❌ Username not found. Try again.");
    }
    return;
}


    // Check if user is in broadcast state
$stmt = $this->conn->prepare("SELECT bot_state FROM clients WHERE telegram_id = ?");
$stmt->execute([$userId]);
$state = $stmt->fetchColumn();

if ($state === 'broadcasting' && $isAdmin) {
    // Reset state
    $this->conn->prepare("UPDATE clients SET bot_state = NULL WHERE telegram_id = ?")->execute([$userId]);

    // Get user list
    $stmt = $this->conn->query("SELECT telegram_id FROM clients WHERE telegram_id IS NOT NULL");
    $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Check if message is photo or text
    if (isset($message['photo'])) {
        $fileId = end($message['photo'])['file_id']; // highest resolution
        $caption = $message['caption'] ?? '';

        foreach ($users as $user) {
            $this->sendPhoto($user['telegram_id'], $fileId, $caption);
        }

    } elseif (isset($message['text'])) {
        foreach ($users as $user) {
            $this->sendMessage($user['telegram_id'], "📢 Broadcast:\n\n" . $message['text']);
        }
    }

    $this->sendMessage($chatId, "✅ Broadcast sent to " . count($users) . " users.");
    return;
}

    // ✅ Existing logic: Payment proof
if (isset($message['photo'])) {
    $photo = end($message['photo']);
    $fileId = $photo['file_id'];
    $caption = $message['caption'] ?? '';
    $fromId = $message['from']['id'];
    $fromUser = $message['from']['username'] ?? 'UnknownUser';

    // ✅ Extract amount and username using regex (e.g. "100 for mark")
    preg_match('/(\d+(?:\.\d{1,2})?)\s*for\s*(\S+)/i', $caption, $matches);
    $amount = isset($matches[1]) ? $matches[1] : '0.00';
    $websiteUser = isset($matches[2]) ? $matches[2] : $fromUser;

    // ✅ Save payment proof to database
    $stmt = $this->conn->prepare("INSERT INTO payments (telegram_id, username, amount, caption, file_id) VALUES (?, ?, ?, ?, ?)");
    $stmt->execute([$fromId, $websiteUser, $amount, $caption, $fileId]);

    // ✅ Send confirmation to sender
    $this->sendMessage(
        $chatId,
        "📨 *Payment proof received!*\n💸 Amount: ₱$amount\n👤 Username: *$websiteUser*\n\nPlease wait while we review your payment.",
        ['parse_mode' => 'Markdown']
    );

    // ✅ Send message to admin with inline buttons
    $text = "💰 *New Payment Receipt*\n"
          . "👤 @$fromUser (ID: `$fromId`)\n"
          . "📝 Caption: `$caption`\n"
          . "💸 Amount: ₱$amount\n"
          . "🌐 Username: `$websiteUser`";

    $inlineKeyboard = [
        'inline_keyboard' => [[
            ['text' => '✅ Approve', 'callback_data' => "approve_{$fromId}_{$amount}"],
            ['text' => '❌ Reject', 'callback_data' => "reject_{$fromId}"]
        ]]
    ];

    $this->sendPhoto($this->adminChatId, $fileId, $text, $inlineKeyboard);
    return;
}

    // ✅ Existing logic: Admin quick replies
    if (isset($message['reply_to_message']) && $isAdmin) {
        $this->handleAdminReply($message['reply_to_message'], $text);
        return;
    }
    
    // ✅ Brodcast
    if (isset($this->pendingBroadcast[$userId])) {
    unset($this->pendingBroadcast[$userId]);

    $stmt = $this->conn->query("SELECT telegram_id FROM clients WHERE telegram_id IS NOT NULL");
    $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $count = 0;
    foreach ($users as $user) {
        $this->sendMessage($user['telegram_id'], "📢 Broadcast:\n\n" . $text);
        $count++;
    }

    $this->sendMessage($chatId, "✅ Broadcast sent to $count users.");
    return;
}


        // Command routing
$normalizedText = strtolower(trim($text));
$command = strtolower(strtok($normalizedText, ' '));
$args = trim(substr($normalizedText, strlen($command)));

// Use $text directly in switch for case-sensitive matching
switch ($text) {
    case '/start':
    case '🔙 back':
        $this->showMainMenu($chatId, $isAdmin);
        break;

    case '/orders':
    case '/o':
    case '📋 Check My Orders':
        $this->handleOrdersCommand($chatId, $userId);
        break;

    case '/status':
    case '/s':
    case '📦 Check Status':
        $this->sendMessage($chatId, "📌 Send Order ID(s).\nExample: `12345` or `12345,67890`", ['parse_mode' => 'Markdown']);
        break;

    case '/speedup':
    case '⏩ Speed Up Order':
        $this->sendMessage($chatId, "📌 Send the Order ID to speed up.\nExample: `/speedup 12345`", ['parse_mode' => 'Markdown']);
        break;

    case '/cancel':
    case '/c':
    case '❌ Cancel Order':
    if ($isAdmin) {
        $approveData = "approve_cancel_{$telegramId}_{$orderId}";
        $declineData = "decline_cancel_{$telegramId}_{$orderId}";

        $inlineKeyboard = [
            'inline_keyboard' => [[
                ['text' => '✅ Approve', 'callback_data' => $approveData],
                ['text' => '❌ Decline', 'callback_data' => $declineData]
            ]]
        ];

        $this->sendMessage(
            $chatId,
            "📌 Send the Order ID(s) to cancel or tap below for testing.\n\nExample: `/cancel 12345,67890`",
            [
                'parse_mode' => 'Markdown',
                'reply_markup' => json_encode($inlineKeyboard)
            ]
        );
    } else {
        $this->sendMessage(
            $chatId,
            "📌 Send the Order ID(s) to cancel.\nExample: `/cancel 12345,67890`",
            ['parse_mode' => 'Markdown']
        );
    }
    break;


    case '/balance':
    case '💰 Check Balance':
        $this->handleBalance($chatId, $userId);
        break;

    case '📨 Help / Support':
        $this->sendMessage($chatId, "🆘 For support, please message our admin: @HostlyPhilippines");
        break;

    case '🛠️ Services List':
        $this->showServiceList($chatId);
        break;

    case '🌐 Go to Web Panel':
        $this->sendMessage($chatId, "🔗 Access your dashboard here:\nhttps://boostbayan.com");
        break;

    case '💸 Add Funds':
    case '💸 Add Funds ':
    case '/addfunds':
    case 'addfunds':
    error_log("Triggered Add Funds case!");
    $this->showAddFundsInstructions($chatId);
    break;

    case '➕ Add Funds':
        if ($isAdmin) {
            $this->sendMessage($chatId, "📌 Usage: `/add username amount`", ['parse_mode' => 'Markdown']);
        } else {
            $this->sendMessage($chatId, "🚫 Admin only command");
        }
        break;

    case '➖ Deduct Funds':
        if ($isAdmin) {
            $this->sendMessage($chatId, "📌 Usage: `/deduct username amount`", ['parse_mode' => 'Markdown']);
        } else {
            $this->sendMessage($chatId, "🚫 Admin only command");
        }
        break;
        
    case '📢 Broadcast':
    if ($isAdmin) {
        $stmt = $this->conn->prepare("UPDATE clients SET bot_state = 'broadcasting' WHERE telegram_id = ?");
        $stmt->execute([$userId]);

        $this->sendMessage($chatId, "📢 Send the message you want to broadcast to all users.");
    } else {
        $this->sendMessage($chatId, "🚫 Admin only command.");
    }
    break;
   

default:
    if (strpos($text, '/speedup ') === 0) {
        $orderId = trim(str_replace('/speedup', '', $text));
        $this->handleSpeedupCommand($chatId, $orderId, $userId);
    } 
    elseif (strpos($text, '/add ') === 0 && $isAdmin) {
        $args = trim(str_replace('/add', '', $text));
        $this->handleAddFunds($chatId, $args);
    } 
    elseif (strpos($text, '/deduct ') === 0 && $isAdmin) {
        $args = trim(str_replace('/deduct', '', $text));
        $this->handleDeductFunds($chatId, $args);
    } 
    elseif (strpos($text, '/cancel') === 0 || $text === '❌ Cancel Order' || $text === '/c') {
        // Extract order IDs after the command
        $args = trim(str_replace(['/cancel', '/c'], '', $text));

        if ($args !== '') {
            $orderIds = array_map('trim', explode(',', $args));
            $clientId = $this->getClientIdByTelegramId($userId);

            if (!$clientId) {
                $this->sendMessage($chatId, "🚫 Unable to find your linked account. Please /start again.");
                break;
            }

            foreach ($orderIds as $orderId) {
                if (empty($orderId) || !ctype_digit($orderId)) {
                    continue;
                }

                // Mark cancel requested in database
                $stmt = $this->conn->prepare("
                    UPDATE orders 
                    SET cancel_requested = 1 
                    WHERE order_id = ? AND client_id = ?
                ");
                $stmt->execute([$orderId, $clientId]);

                // Notify admin
                $approveData = "approve_cancel_{$userId}_{$orderId}";
                $declineData = "decline_cancel_{$userId}_{$orderId}";

                $inlineKeyboard = [
                    'inline_keyboard' => [[
                        ['text' => '✅ Approve', 'callback_data' => $approveData],
                        ['text' => '❌ Decline', 'callback_data' => $declineData]
                    ]]
                ];

                $this->sendMessage(
                    $this->adminChatId,
                    "⚠️ *Cancel Request Received*\n\n👤 Telegram ID: `$userId`\n🧾 Order ID: `$orderId`\n\nApprove or decline below:",
                    [
                        'parse_mode' => 'Markdown',
                        'reply_markup' => json_encode($inlineKeyboard)
                    ]
                );

                // Notify user
                $this->sendMessage(
                    $chatId,
                    "📨 Your cancel request for Order *#{$orderId}* has been sent to admin for review.",
                    ['parse_mode' => 'Markdown']
                );
            }
        } else {
            // No order ID provided
            $this->sendMessage(
                $chatId,
                "📌 Send the Order ID(s) to cancel.\nExample: `/cancel 12345,67890`",
                ['parse_mode' => 'Markdown']
            );
        }
    }
    elseif (preg_match('/^[\d,\s]+$/', $text)) {
        $this->handleStatusCommand($chatId, $text, $userId);
    } 
    else {
        $this->sendMessage($chatId, "🚫 Invalid command. Use /start to show menu.");
    }
    break;
}
}


// ✅ Now it's safe to define another function here
private function showMainMenu($chatId, $isAdmin) {
    $text = "🤖 *Welcome to Boost Bayan Philippines S2 AI Support*\nChoose a command below:";

    $keyboard = [
        ['📋 Check My Orders', '📦 Check Status'],
        ['⏩ Speed Up Order', '❌ Cancel Order'],
        ['💰 Check Balance', '📨 Help / Support'],
        ['🛠️ Services List', '🌐 Go to Web Panel'],
        ['💸 Add Funds']
    ];

    if ($isAdmin) {
        $keyboard[] = ['➕ Add Funds', '➖ Deduct Funds'];
        $keyboard[] = ['📢 Broadcast'];
    }

    $replyMarkup = [
        'keyboard' => $keyboard,
        'resize_keyboard' => true,
        'one_time_keyboard' => false
    ];

    $this->sendMessage($chatId, $text, [
        'reply_markup' => json_encode($replyMarkup),
        'parse_mode' => 'Markdown'
    ]);
}



    private function sendMessage($chatId, $text, $options = []) {
    $url = "https://api.telegram.org/bot{$this->botToken}/sendMessage";

    // Base payload
    $payload = [
        'chat_id' => $chatId,
        'text' => $text,
        'parse_mode' => 'Markdown',
    ];

    // Merge optional options (parse_mode, reply_markup, etc.)
    if (!empty($options)) {
        $payload = array_merge($payload, $options);
    }

    // Ensure reply_markup is JSON encoded
    if (isset($payload['reply_markup']) && is_array($payload['reply_markup'])) {
        $payload['reply_markup'] = json_encode($payload['reply_markup'], JSON_UNESCAPED_UNICODE);
    }

    // Send the message
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    $result = curl_exec($ch);

    if (curl_errno($ch)) {
        error_log("CURL ERROR: " . curl_error($ch));
    } else {
        error_log("Telegram response: " . $result);
    }

    curl_close($ch);
    return $result;
}

    private function editMessage($chatId, $messageId, $newText, $extra = []) {
    $url = "https://api.telegram.org/bot{$this->botToken}/editMessageText";

    $payload = array_merge([
        'chat_id' => $chatId,
        'message_id' => $messageId,
        'text' => $newText,
        'parse_mode' => 'Markdown'
    ], $extra);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Content-Type: application/x-www-form-urlencoded"
    ]);

    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        error_log("CURL ERROR (editMessage): " . curl_error($ch));
    } else {
        error_log("Telegram editMessage response: " . $result);
    }
    curl_close($ch);
}
    
    private function editMessageText($chatId, $messageId, $text, $options = []) {
    $url = "https://api.telegram.org/bot{$this->botToken}/editMessageText";
    $data = array_merge([
        'chat_id' => $chatId,
        'message_id' => $messageId,
        'text' => $text,
        'parse_mode' => 'Markdown'
    ], $options);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_exec($ch);
    curl_close($ch);
}

    private function forwardPaymentToAdmin($fileId, $caption, $userId, $username, $amount = null) {
        $text = "💰 *New Payment Submitted!*\n"
              . "👤 *Username:* @$username\n"
              . "🆔 *User ID:* `$userId`\n"
              . ($amount ? "💸 *Amount:* ₱$amount\n" : "")
              . "📝 *Message:* `$caption`";

        $inlineKeyboard = [
            'inline_keyboard' => [
                [
                    ['text' => '✅ Approve', 'callback_data' => "approve_{$userId}_{$amount}"],
                    ['text' => '❌ Reject', 'callback_data' => "reject_{$userId}"]
                ]
            ]
        ];

        $this->sendPhoto($this->adminChatId, $fileId, $text, $inlineKeyboard);
    }

    private function sendPhoto($chatId, $fileId, $caption, $replyMarkup = null) {
    $url = "https://api.telegram.org/bot{$this->botToken}/sendPhoto";
    $data = [
        'chat_id' => $chatId,
        'photo' => $fileId,
        'caption' => $caption,
        'parse_mode' => 'Markdown'
    ];

    if ($replyMarkup) {
        $data['reply_markup'] = json_encode($replyMarkup, JSON_UNESCAPED_UNICODE);
    }

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    $result = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    error_log("sendPhoto result: HTTP $httpCode - " . $result);
}

    
    private function getLoyaltyLevel($totalSpent) {
    if ($totalSpent >= 10000) return "🏆 VIP";
    if ($totalSpent >= 5000)  return "🥇 Gold";
    if ($totalSpent >= 1000)  return "🥈 Silver";
    if ($totalSpent >= 1)     return "🥉 Bronze";
    return "🔰 New User";
}
    private function showServiceList($chatId) {
    try {
        $stmt = $this->conn->prepare("
            SELECT 
                s.service_id, 
                s.service_name, 
                s.service_price, 
                COUNT(o.order_id) AS usage_count, 
                ROUND(AVG(TIMESTAMPDIFF(MINUTE, o.order_create, o.completion_time))) AS avg_completion_time
            FROM 
                orders o
            JOIN 
                services s ON o.service_id = s.service_id
            WHERE 
                o.order_status = 'completed'
                AND o.order_create IS NOT NULL 
                AND o.completion_time IS NOT NULL
            GROUP BY 
                s.service_id, s.service_name, s.service_price
            ORDER BY 
                usage_count DESC
            LIMIT 5
        ");
        $stmt->execute();
        $services = $stmt->fetchAll(PDO::FETCH_ASSOC);

        if (empty($services)) {
            $this->sendMessage($chatId, "📭 No top services found.");
            return;
        }

        $message = "🛠️ *Top Used Services:*\n\n";
        foreach ($services as $srv) {
            $message .= "🔹 *{$srv['service_name']}*\n";
            $message .= "🆔 ID: `{$srv['service_id']}`\n";
            $message .= "💸 Price: ₱{$srv['service_price']}\n";
            $message .= "📊 Orders: {$srv['usage_count']}\n";
            $message .= "⏱ Avg Time: ~{$srv['avg_completion_time']} min\n\n";
        }

        $this->sendMessage($chatId, $message, ['parse_mode' => 'Markdown']);
    } catch (Exception $e) {
        $this->sendMessage($chatId, "❌ Failed to load services.");
        error_log("Service list error: " . $e->getMessage());
    }
}

private function showAddFundsInstructions($chatId) {
    $caption = "💸 *Add Funds Instructions:*\n\n"
        . "📱 *GCash*\n"
        . "• Number: `9301063909`\n"
        . "• Name: *RA.*\n\n"
        . "📤 *After payment, reply here with your proof* (screenshot/photo) *plus the amount and your website username.*\n\n"
        . "🔖 *Sample Reply:*\n"
        . "`100.00 for 'Your Website Username'`\n\n"
        . "🖼 *Kindly Click and Check the Sample Payment Screenshot below.*";

    // Use your hosted image
    $photoUrl = "https://hlychimons.shop/payment.jpg";

    $this->sendPhoto($chatId, $photoUrl, $caption, [
        'parse_mode' => 'Markdown'
    ]);
}
    
    // [Include all the methods from previous implementations]
    private function handleStatusCommand($chatId, $input, $userId) {
        $orderIds = $this->parseOrderIds($input);
        if (empty($orderIds)) {
            $this->sendMessage($chatId, "🐀𐃌𘁕sage: /status 12345 or /status 12345,56789");
            return;
        }
        $this->processOrderDisplay($chatId, $orderIds, $userId);
    }
    
    private function handleOrdersCommand($chatId, $userId) {
        $clientId = $this->getClientIdByTelegramId($userId);
        if (!$clientId) {
            $this->sendMessage($chatId, "🔐 Please link your account first");
            return;
        }
        
        $orders = $this->conn->prepare("
            SELECT order_id, service_id, order_status, order_charge, order_create_date 
            FROM orders 
            WHERE client_id = ? 
            ORDER BY order_id DESC 
            LIMIT 10
        ");
        $orders->execute([$clientId]);
        $orders = $orders->fetchAll(PDO::FETCH_ASSOC);
        
        if (empty($orders)) {
            $this->sendMessage($chatId, "📭 You don't have any orders yet");
            return;
        }
        
        $message = "📋 *Your Recent Orders*\n\n";
        foreach ($orders as $order) {
            $message .= "#{$order['order_id']} - Service {$order['service_id']}\n";
            $message .= "💵 {$order['order_charge']} - {$this->formatStatus($order['order_status'])}\n";
            $message .= "📅 " . date('M d, H:i', strtotime($order['order_create_date'])) . "\n\n";
        }
        
        $this->sendMessage($chatId, $message);
    }
    
    private function handleBalance($chatId, $userId) {
    $clientId = $this->getClientIdByTelegramId($userId);
    if (!$clientId) {
        $this->sendMessage($chatId, "🔐 Please link your account first using /link");
        return;
    }

    $stmt = $this->conn->prepare("SELECT balance FROM clients WHERE client_id = ?");
    $stmt->execute([$clientId]);
    $balance = $stmt->fetchColumn();
    
    $this->sendMessage($chatId, "💰 Your current balance is: ₱" . number_format($balance, 2));
    }

    private function handleSpeedupCommand($chatId, $args, $userId) {
    if (empty($args)) {
        $this->sendMessage($chatId, "📌 Please provide an Order ID to speed up.\nExample: `/speedup 12345`", ['parse_mode' => 'Markdown']);
        return;
    }

    if (!ctype_digit($args)) {
        $this->sendMessage($chatId, "❌ Invalid Order ID. Please enter a valid numeric ID.");
        return;
    }

    // First response immediately
    $this->sendMessage($chatId, "⏳ Thank you for that information.\nI'm fetching your Order ID now. Please wait at least *5 seconds*...", ['parse_mode' => 'Markdown']);

    // Wait for 5 seconds
    sleep(5); // ⚠️ Only works if Telegram allows delay; usually okay if script is quick

    // Final fake confirmation
    $this->sendMessage($chatId, "✅ Thank you! Your order #$args has been added for speed-up.\n\n🔧 Our team will prioritize it shortly.");
}

    private function handleCancelCommand($chatId, $input, $userId) {
        $orderIds = $this->parseOrderIds($input);
        if (empty($orderIds)) {
            $this->sendMessage($chatId, "📌 Usage: /cancel 12345 or /cancel 12345,56789");
            return;
        }
        $this->processCancellations($chatId, $orderIds, $userId);
    }
    
    private function handleAddFunds($chatId, $args) {
    $parts = preg_split('/\s+/', $args, 2);
    if (count($parts) < 2) {
        $this->sendMessage($chatId, "📌 Usage: /add username amount");
        return;
    }

    $username = $parts[0];
    $amountRaw = $parts[1];

    // Validate that amount is numeric (accepts decimals)
    if (!is_numeric($amountRaw)) {
        $this->sendMessage($chatId, "❌ Invalid amount. Use: /add username amount");
        return;
    }

    $amount = number_format((float)$amountRaw, 2, '.', '');

    try {
        $this->conn->beginTransaction();

        // Get client
        $clientStmt = $this->conn->prepare("SELECT * FROM clients WHERE username = ?");
        $clientStmt->execute([$username]);
        $client = $clientStmt->fetch(PDO::FETCH_ASSOC);

        if (!$client) {
            throw new Exception("User not found");
        }

        // Add payment record
        $payment = $this->conn->prepare("
            INSERT INTO payments SET 
            client_id = ?,
            client_balance = ?,
            payment_amount = ?,
            payment_method = 1,
            payment_status = 3,
            payment_delivery = 2,
            payment_mode = 'Telegram',
            payment_create_date = NOW(),
            payment_ip = ?,
            payment_extra = 'Added via Telegram Bot'
        ");
        $payment->execute([
            $client['client_id'],
            $client['balance'],
            $amount,
            $_SERVER['REMOTE_ADDR']
        ]);

        // Update balance
        $update = $this->conn->prepare("UPDATE clients SET balance = balance + ? WHERE client_id = ?");
        $update->execute([$amount, $client['client_id']]);

        $this->conn->commit();

        $this->sendMessage($chatId, "✅ Added ₱$amount to @$username");
        $this->sendMessage(
            $this->adminChatId,
            "💰 *Funds Added*\n\nUser: @$username\nAmount: ₱$amount"
        );

    } catch (Exception $e) {
        $this->conn->rollBack();
        $this->sendMessage($chatId, "❌ Error: " . $e->getMessage());
    }
}
    
    private function handleDeductFunds($chatId, $args) {
        $parts = preg_split('/\s+/', $args, 2);
        if (count($parts) < 2 || !is_numeric($parts[1])) {
            $this->sendMessage($chatId, "📌 Usage: /deduct username amount");
            return;
        }
        
        $username = $parts[0];
        $amount = (float)$parts[1];
        
        try {
            $this->conn->beginTransaction();
            
            // Get client
            $client = $this->conn->prepare("SELECT * FROM clients WHERE username = ?");
            $client->execute([$username]);
            $client = $client->fetch(PDO::FETCH_ASSOC);
            
            if (!$client) {
                throw new Exception("User not found");
            }
            
            if ($client['balance'] < $amount) {
                throw new Exception("Insufficient balance");
            }
            
            // Add deduction record
            $payment = $this->conn->prepare("
                INSERT INTO payments SET 
                client_id = ?,
                client_balance = ?,
                payment_amount = ?,
                payment_method = 1,
                payment_status = 3,
                payment_delivery = 2,
                payment_mode = 'Telegram',
                payment_create_date = NOW(),
                payment_ip = ?,
                payment_extra = 'Deducted via Telegram Bot'
            ");
            $payment->execute([
                $client['client_id'],
                $client['balance'],
                -$amount,
                $_SERVER['REMOTE_ADDR']
            ]);
            
            // Update balance
            $update = $this->conn->prepare("UPDATE clients SET balance = balance - ? WHERE client_id = ?");
            $update->execute([$amount, $client['client_id']]);
            
            $this->conn->commit();
            
            $this->sendMessage($chatId, "✅ Deducted $amount from @$username");
            $this->sendMessage(
                $this->adminChatId,
                "💸 *Funds Deducted*\n\nUser: @$username\nAmount: $amount\nBy: @{$message['from']['username']}"
            );
            
        } catch (Exception $e) {
            $this->conn->rollBack();
            $this->sendMessage($chatId, "❌ Error: " . $e->getMessage());
        }
    }
    
    private function parseOrderIds($input) {
        return array_filter(
            array_map('trim', explode(',', $input)),
            function($id) { return is_numeric($id); }
        );
    }
    
    private function processOrderDisplay($chatId, $orderIds, $userId) {
        $clientId = $this->getClientIdByTelegramId($userId);
        $orders = [];
        
        foreach ($orderIds as $orderId) {
            $order = $this->conn->prepare("
                SELECT o.*, s.service_name 
                FROM orders o
                LEFT JOIN services s ON o.service_id = s.service_id
                WHERE o.order_id = ? AND o.client_id = ?
            ");
            $order->execute([$orderId, $clientId]);
            $order = $order->fetch(PDO::FETCH_ASSOC);
            
            if ($order) {
                $orders[] = $order;
            }
        }
        
        if (empty($orders)) {
            $this->sendMessage($chatId, "🔍 No orders found or you don't have permission");
            return;
        }
        
        // Single order display
        if (count($orders) === 1) {
            $order = reset($orders);
            $this->showOrderDetails($chatId, $order);
            return;
        }
        
        // Multiple orders display
        $message = "🔢 Found " . count($orders) . " orders:\n\n";
        foreach ($orders as $order) {
            $message .= "#{$order['order_id']} - {$order['service_name']}\n";
            $message .= "Status: {$this->formatStatus($order['order_status'])}\n";
            $message .= "Amount: {$order['order_charge']}\n\n";
        }
        
        $this->sendMessage($chatId, $message);
    }
    
    private function showOrderDetails($chatId, $order) {
    $status = $this->formatStatus($order['order_status']);
    $buttons = [];
    
    if (in_array($order['order_status'], ['pending', 'inprogress'])) {
        $buttons[] = [['text' => "❌ Cancel Order", 'callback_data' => "cancel_" . $order['order_id']]];
    }
    
    $message = "📦 *Order #{$order['order_id']}*\n";
    $message .= "━━━━━━━━━━━━━━\n";
    $message .= "🔹 Service: {$order['service_name']}\n";
    $message .= "🔹 Status: $status\n";
    $message .= "🔹 Amount: {$order['order_charge']}\n";
    $message .= "🔹 Date: " . date('M d, H:i', strtotime($order['order_create_date']));
    
    if ($order['order_status'] == 'completed' && !empty($order['completion_time'])) {
        $message .= "\n🔹 Completed in: " . $this->formatCompletionTime(
            $order['order_create_date'],
            $order['completion_time']
        );
    }
    
    $replyMarkup = null;
    if (!empty($buttons)) {
        $replyMarkup = json_encode(['inline_keyboard' => $buttons]);
    }
    
    $this->sendMessage($chatId, $message, $replyMarkup);
}
    
    private function processCancellationsRequest($chatId, $text, $userId) {
    // Extract order IDs
    $args = trim(preg_replace('/^\/?cancel\b|^\/?c\b/i', '', $text));
    if ($args === '') {
        $this->sendMessage($chatId, "📌 Send the Order ID(s) to cancel.\nExample: `/cancel 12345,67890`", ['parse_mode' => 'Markdown']);
        return;
    }

    $orderIds = array_filter(array_map('trim', explode(',', $args)));
    if (empty($orderIds)) {
        $this->sendMessage($chatId, "📌 Send valid Order ID(s). Example: `/cancel 12345,67890`", ['parse_mode' => 'Markdown']);
        return;
    }

    // Get client_id from telegram_id
    $clientId = $this->getClientIdByTelegramId($userId);
    if (!$clientId) {
        $this->sendMessage($chatId, "🔐 Please link your account first using /start or register on the website.");
        return;
    }

    $sent = 0;
    foreach ($orderIds as $orderId) {
        if (empty($orderId) || !ctype_digit($orderId)) continue;

        // Fetch the order
        $stmt = $this->conn->prepare("
            SELECT order_id, order_status, order_charge, cancel_requested 
            FROM orders 
            WHERE order_id = ? AND client_id = ?
            LIMIT 1
        ");
        $stmt->execute([$orderId, $clientId]);
        $order = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$order) {
            $this->sendMessage($chatId, "🚫 Order ID *#{$orderId}* not found or doesn’t belong to you.", ['parse_mode' => 'Markdown']);
            continue;
        }

        $status = strtolower($order['order_status']);

        // ❌ Already canceled (handle both spellings)
        if (in_array($status, ['cancelled', 'canceled'])) {
            $this->sendMessage($chatId, "⚠️ Unable to process your request — Order *#{$orderId}* is already canceled.", ['parse_mode' => 'Markdown']);
            continue;
        }

        // ❌ Already requested cancel before
        if (!empty($order['cancel_requested']) && $order['cancel_requested'] == 1) {
            $this->sendMessage($chatId, "⚠️ You already submitted a cancel request for Order *#{$orderId}*. Please wait for admin review.", ['parse_mode' => 'Markdown']);
            continue;
        }

        // ❌ Completed or failed orders cannot be cancelled
        if (in_array($status, ['completed', 'success', 'failed'])) {
            $this->sendMessage($chatId, "🚫 Order *#{$orderId}* cannot be cancelled — it’s already *{$order['order_status']}*.", ['parse_mode' => 'Markdown']);
            continue;
        }

        // ✅ Only allow cancel for pending/inprogress
        if (!in_array($status, ['pending', 'inprogress'])) {
            $this->sendMessage($chatId, "🚫 Order *#{$orderId}* cannot be cancelled right now. Current status: *{$order['order_status']}*.", ['parse_mode' => 'Markdown']);
            continue;
        }

        // Mark cancel requested
        $u = $this->conn->prepare("
            UPDATE orders 
            SET cancel_requested = 1 
            WHERE order_id = ? AND client_id = ? AND order_status IN ('pending','inprogress')
        ");
        $u->execute([$orderId, $clientId]);

        // Notify user
        $this->sendMessage($chatId, "📨 Your cancel request for Order *#{$orderId}* has been sent to admin for review.", ['parse_mode' => 'Markdown']);

        // Notify admin with buttons
        $approveData = "approve_cancel_{$userId}_{$orderId}";
        $declineData = "decline_cancel_{$userId}_{$orderId}";
        $inlineKeyboard = [
            'inline_keyboard' => [[
                ['text' => '✅ Approve', 'callback_data' => $approveData],
                ['text' => '❌ Decline', 'callback_data' => $declineData]
            ]]
        ];

        $this->sendMessage(
            $this->adminChatId,
            "⚠️ *Cancel Request Received*\n\n👤 Telegram ID: `{$userId}`\n🧾 Order ID: `{$orderId}`\n💸 Charge: ₱" . number_format($order['order_charge'], 2) . "\n\nApprove or decline below:",
            [
                'parse_mode' => 'Markdown',
                'reply_markup' => $inlineKeyboard
            ]
        );

        $sent++;
    }

    if ($sent === 0) {
        $this->sendMessage($chatId, "🚫 No cancelable orders found (either invalid ID, not yours, already completed, or already canceled).");
    }
}


    private function formatStatus($status) {
        switch ($status) {
            case 'pending': return '⏳ Pending';
            case 'inprogress': return '🔄 In Progress';
            case 'completed': return '✅ Completed';
            case 'partial': return '☑️ Partial';
            case 'canceled': return '❌ Canceled';
            case 'processing': return '📦 Processing';
            default: return ucfirst($status);
        }
    }
    
    private function formatCompletionTime($start, $end) {
        $start = new DateTime($start);
        $end = new DateTime($end);
        $diff = $start->diff($end);
        
        $parts = [];
        if ($diff->d > 0) $parts[] = $diff->d . 'd';
        if ($diff->h > 0) $parts[] = $diff->h . 'h';
        if ($diff->i > 0) $parts[] = $diff->i . 'm';
        
        return implode(' ', $parts) ?: 'Less than 1m';
    }
    
    private function getClientIdByTelegramId($telegramId) {
        $stmt = $this->conn->prepare("SELECT client_id FROM clients WHERE telegram_id = ?");
        $stmt->execute([$telegramId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result ? $result['client_id'] : null;
    }
}

// Handle webhook request
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $update = json_decode(file_get_contents('php://input'), true);

    // ✅ ADD THIS TO LOG WHAT TELEGRAM SENT
    file_put_contents('telegram_log.txt', print_r($update, true), FILE_APPEND);

    $bot = new TelegramOrderBot($conn, $botToken, $adminChatId);
    $bot->handleUpdate($update);
}

// Optional: Allow browser GET check
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    echo "🤖 Webhook is active!";
    exit;
}