<?php
require_once "config.php";

session_start();
date_default_timezone_set("Asia/Dhaka");

$CONFIG_SHOW_ALL_MODULES = false;   
$CONFIG_ALLOW_STATUS_CHANGE = false; 

if (!isset($conn) || !($conn instanceof mysqli)) {
    die(json_encode(["status" => "error", "message" => "Database connection error"]));
}
$conn->set_charset("utf8mb4");

function session_alive(int $timeout): bool {
    if (empty($_SESSION['auth_logged_in']) || empty($_SESSION['auth_last_activity'])) return false;
    if ((time() - (int)$_SESSION['auth_last_activity']) > $timeout) {
        $_SESSION = [];
        session_destroy();
        return false;
    }
    $_SESSION['auth_last_activity'] = time();
    return true;
}

if (!session_alive(1200)) {
    if (isset($_GET['api'])) die(json_encode(["status" => "unauthorized"]));
    header("Location: admin_login.php");
    exit;
}

if (!function_exists('base64url_encode')) {
    function base64url_encode($data) { 
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
    }
}

if (!function_exists('getAccessToken')) {
    function getAccessToken($jsonFilePath) {
        $credentials = @json_decode(file_get_contents($jsonFilePath), true);
        if (!$credentials || !isset($credentials['private_key'])) return false;
        $clientEmail = $credentials['client_email'];
        $privateKey  = $credentials['private_key'];
        $header = json_encode(['alg' => 'RS256', 'typ' => 'JWT']);
        $now = time();
        $payload = json_encode([
            'iss'   => $clientEmail,
            'scope' => 'https://www.googleapis.com/auth/cloud-platform',
            'aud'   => 'https://oauth2.googleapis.com/token',
            'exp'   => $now + 3600,
            'iat'   => $now
        ]);
        $unsignedJwt = base64url_encode($header) . "." . base64url_encode($payload);
        $signature = '';
        openssl_sign($unsignedJwt, $signature, $privateKey, OPENSSL_ALGO_SHA256);
        $jwt = $unsignedJwt . "." . base64url_encode($signature);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://oauth2.googleapis.com/token');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt]));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        $responseData = json_decode($response, true);
        return $responseData['access_token'] ?? false;
    }
}

function sendFCMByIdentifier($conn, $colName, $colValue, $title, $body) {
    $allowedCols = ['username', 'token', 'uid', 'email'];
    if (!in_array($colName, $allowedCols)) return false;
    
    $stmt = $conn->prepare("SELECT fcm_key FROM users WHERE $colName = ? LIMIT 1");
    $stmt->bind_param("s", $colValue);
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res->fetch_assoc();
    $stmt->close();
    
    if (!$row || empty($row['fcm_key'])) return false;
    $fcm_key = $row['fcm_key'];

    $serviceAccountFile = 'noti.json';
    if (file_exists($serviceAccountFile)) {
        $accessToken = getAccessToken($serviceAccountFile);
        if ($accessToken) {
            $credentials = json_decode(file_get_contents($serviceAccountFile), true);
            $projectId = $credentials['project_id'];
            $url = "https://fcm.googleapis.com/v1/projects/" . $projectId . "/messages:send";
            $notificationMap = ["title" => (string)$title, "body"  => (string)$body];
            $postData = json_encode([
                "message" => [
                    "token" => $fcm_key,
                    "notification" => $notificationMap,
                    "data" => $notificationMap
                ]
            ], JSON_UNESCAPED_UNICODE);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: Bearer ' . $accessToken,
                'Content-Type: application/json; UTF-8'
            ]);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_exec($ch);
            curl_close($ch);
            return true;
        }
    }
    return false;
}

$role = $_SESSION['auth_role'] ?? '';
$sess_username = $_SESSION['auth_username'] ?? '';
$sess_password = $_SESSION['auth_password'] ?? '';

$perm = [
    'addmoney_read' => false, 'addmoney_edit' => false, 'addmoney_delete' => false,
    'withdraw_read' => false, 'withdraw_edit' => false, 'withdraw_delete' => false,
    'shop_read' => false, 'shop_edit' => false, 'shop_delete' => false,
    'topup_read' => false, 'topup_edit' => false, 'topup_delete' => false,
    'gift_read' => false, 'gift_edit' => false, 'gift_delete' => false,
    'match_history_read' => false
];

if ($role === 'admin') {
    foreach ($perm as $k => $v) $perm[$k] = true;
} elseif ($role === 'permission') {
    $stmt = $conn->prepare("SELECT addmoney_history_read, addmoney_history_edit, addmoney_history_delete, withdrawal_history_read, withdrawal_history_edit, withdrawal_history_delete, Shop_Product_Read, Shop_Product_Edit, Shop_Product_Delete, Shop_TopUP_Read, Shop_TopUP_Edit, Shop_TopUP_Delete, Geft_Read, Geft_Edit, Geft_Delete FROM `Zabbar_Admin_Permission` WHERE username = ? AND password = ? LIMIT 1");
    if ($stmt) {
        $stmt->bind_param("ss", $sess_username, $sess_password);
        $stmt->execute();
        $res = $stmt->get_result();
        if ($row = $res->fetch_assoc()) {
            $check = function($val) { return (strtolower(trim($val ?? '')) === 'yes' || $val == 1); };
            $perm['addmoney_read'] = $check($row['addmoney_history_read']);
            $perm['addmoney_edit'] = $check($row['addmoney_history_edit']);
            $perm['addmoney_delete'] = $check($row['addmoney_history_delete']);
            $perm['withdraw_read'] = $check($row['withdrawal_history_read']);
            $perm['withdraw_edit'] = $check($row['withdrawal_history_edit']);
            $perm['withdraw_delete'] = $check($row['withdrawal_history_delete']);
            $perm['shop_read'] = $check($row['Shop_Product_Read']);
            $perm['shop_edit'] = $check($row['Shop_Product_Edit']);
            $perm['shop_delete'] = $check($row['Shop_Product_Delete']);
            $perm['topup_read'] = $check($row['Shop_TopUP_Read']);
            $perm['topup_edit'] = $check($row['Shop_TopUP_Edit']);
            $perm['topup_delete'] = $check($row['Shop_TopUP_Delete']);
            $perm['gift_read'] = $check($row['Geft_Read']);
            $perm['gift_edit'] = $check($row['Geft_Edit']);
            $perm['gift_delete'] = $check($row['Geft_Delete']);
            $perm['match_history_read'] = true;
        }
        $stmt->close();
    }
}

// ----------------------------------------------------
// Type check to prevent Array to String conversion Error
// ----------------------------------------------------
$module = isset($_GET['module']) && is_string($_GET['module']) ? $_GET['module'] : 'addmoney';
$allowed_modules = $CONFIG_SHOW_ALL_MODULES 
    ? ['addmoney', 'withdraw', 'topup', 'shop', 'gift', 'match_history'] 
    : ['addmoney', 'withdraw', 'match_history'];

if (!in_array($module, $allowed_modules)) $module = 'addmoney';
$targetUsername = isset($_GET['username']) && is_string($_GET['username']) ? trim($_GET['username']) : '';

if (isset($_GET['api'])) {
    header('Content-Type: application/json');
    $action = is_string($_GET['api']) ? $_GET['api'] : '';

    if (!$CONFIG_ALLOW_STATUS_CHANGE && in_array($action, ['approve', 'reject', 'process', 'delete'])) {
        echo json_encode(["status" => "error", "message" => "Actions are currently disabled."]); 
        exit;
    }

    if ($module === 'match_history') {
        if (!$perm['match_history_read']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
        
        if ($action === 'fetch') {
            $limit = 50;
            $page = isset($_GET['page']) && is_numeric($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
            $offset = ($page - 1) * $limit;
            
            $targetEmail = '';
            if ($targetUsername !== '') {
                $es = $conn->prepare("SELECT email FROM users WHERE username = ?");
                $es->bind_param("s", $targetUsername);
                $es->execute();
                $targetEmail = $es->get_result()->fetch_assoc()['email'] ?? '---notfound---';
                $es->close();
            }

            $countSql = "SELECT COUNT(s.id) as total FROM statistics s";
            if ($targetUsername !== '') $countSql .= " WHERE s.email = '" . $conn->real_escape_string($targetEmail) . "'";
            $totalRows = $conn->query($countSql)->fetch_assoc()['total'];
            $totalPages = ceil($totalRows / $limit);

            $sql = "SELECT s.*, u.username FROM statistics s LEFT JOIN users u ON s.email = u.email WHERE 1=1";
            $params = [];
            $types = "";

            if ($targetUsername !== '') {
                $sql .= " AND s.email = ?";
                $params[] = $targetEmail;
                $types .= "s";
            }
            $sql .= " ORDER BY s.id DESC LIMIT ? OFFSET ?";
            $params[] = $limit; $params[] = $offset;
            $types .= "ii";

            $stmt = $conn->prepare($sql);
            if ($types) $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
            $data = [];
            while ($row = $res->fetch_assoc()) $data[] = $row;
            $stmt->close();
            
            echo json_encode(["status" => "success", "data" => $data, "totalPages" => $totalPages, "currentPage" => $page]); exit;
        }
    }

    if ($module === 'addmoney' || $module === 'withdraw') {
        if (!$perm[$module.'_read']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
        $table = $module;

        if ($action === 'fetch') {
            $page = isset($_GET['page']) && is_numeric($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
            $limit = 50;
            $offset = ($page - 1) * $limit;
            $filter = isset($_GET['filter']) && is_string($_GET['filter']) ? $_GET['filter'] : 'all';
            
            if (!$CONFIG_ALLOW_STATUS_CHANGE) $filter = 'all';

            $sql = "SELECT id, username, email, method, number, amount, trxid, status, date, time FROM $table WHERE 1=1";
            $params = [];
            $types = "";

            if ($targetUsername !== '') {
                $sql .= " AND username = ?";
                $params[] = $targetUsername;
                $types .= "s";
            }

            if ($filter === 'success') $sql .= " AND LOWER(TRIM(status)) IN ('success', 'approved')";
            elseif ($filter === 'failed') $sql .= " AND LOWER(TRIM(status)) IN ('failed', 'rejected')";
            elseif ($filter === 'pending') $sql .= " AND LOWER(TRIM(status)) NOT IN ('success', 'approved', 'failed', 'rejected')";

            $sql .= " ORDER BY id DESC LIMIT ? OFFSET ?";
            $params[] = $limit; $params[] = $offset;
            $types .= "ii";

            $stmt = $conn->prepare($sql);
            if ($types) $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
            $data = [];
            while ($row = $res->fetch_assoc()) $data[] = $row;
            $stmt->close();
            echo json_encode(["status" => "success", "data" => $data, "page" => $page]); exit;
        }

        if ($action === 'approve' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : 0;
            if (!$perm[$module.'_edit']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
            $conn->begin_transaction();
            try {
                $stmt = $conn->prepare("SELECT username, amount, status FROM $table WHERE id = ? FOR UPDATE");
                $stmt->bind_param("i", $id);
                $stmt->execute();
                $res = $stmt->get_result();
                if ($res->num_rows === 0) throw new Exception("Record not found.");
                $row = $res->fetch_assoc();
                $stmt->close();
                $currentStatus = strtolower(trim($row['status']));
                if ($currentStatus === 'success' || $currentStatus === 'approved') throw new Exception("Already success.");
                
                $username = $row['username'];
                $amount = (float)$row['amount'];
                
                $stmtUpdate = $conn->prepare("UPDATE $table SET status = 'success' WHERE id = ?");
                $stmtUpdate->bind_param("i", $id);
                $stmtUpdate->execute();
                $stmtUpdate->close();
                
                $q = ($module === 'addmoney') ? "UPDATE users SET balance = balance + ? WHERE username = ?" : "UPDATE users SET balance = balance - ? WHERE username = ?";
                $stmtUser = $conn->prepare($q);
                $stmtUser->bind_param("ds", $amount, $username);
                $stmtUser->execute();
                if ($stmtUser->affected_rows === 0) {
                    $stmtCheck = $conn->prepare("SELECT id FROM users WHERE username = ?");
                    $stmtCheck->bind_param("s", $username);
                    $stmtCheck->execute();
                    if ($stmtCheck->get_result()->num_rows === 0) throw new Exception("User not found.");
                    $stmtCheck->close();
                }
                $stmtUser->close();
                $conn->commit();
                
                $notifTitle = ($module === 'addmoney') ? "Add Money Successful" : "Withdraw Successful";
                $notifBody  = "Your request for ৳" . $amount . " has been successfully approved.";
                sendFCMByIdentifier($conn, 'username', $username, $notifTitle, $notifBody);

                echo json_encode(["status" => "success"]);
            } catch (Exception $e) {
                $conn->rollback();
                echo json_encode(["status" => "error", "message" => $e->getMessage()]);
            }
            exit;
        }

        if ($action === 'reject' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : 0;
            if (!$perm[$module.'_edit']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
            $stmt = $conn->prepare("SELECT username, status, amount FROM $table WHERE id = ?");
            $stmt->bind_param("i", $id);
            $stmt->execute();
            $res = $stmt->get_result();
            $row = $res->fetch_assoc();
            $stmt->close();
            
            if ($row) {
                $c = strtolower(trim($row['status']));
                if ($c === 'success' || $c === 'approved') { echo json_encode(["status" => "error", "message" => "Cannot fail successful transaction."]); exit; }
                
                $stmt = $conn->prepare("UPDATE $table SET status = 'failed' WHERE id = ?");
                $stmt->bind_param("i", $id);
                if ($stmt->execute()) {
                    $notifTitle = ($module === 'addmoney') ? "Add Money Failed" : "Withdraw Failed";
                    $notifBody  = "Your request for ৳" . $row['amount'] . " has been rejected.";
                    sendFCMByIdentifier($conn, 'username', $row['username'], $notifTitle, $notifBody);
                    echo json_encode(["status" => "success"]);
                }
                else echo json_encode(["status" => "error", "message" => "Update failed."]);
                $stmt->close();
            }
            exit;
        }

        if ($action === 'delete' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : 0;
            if (!$perm[$module.'_delete']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
            $stmt = $conn->prepare("DELETE FROM $table WHERE id = ?");
            $stmt->bind_param("i", $id);
            if ($stmt->execute()) echo json_encode(["status" => "success"]);
            else echo json_encode(["status" => "error", "message" => "Delete failed."]);
            $stmt->close();
            exit;
        }
    } 
    
    elseif ($module === 'topup' && $CONFIG_SHOW_ALL_MODULES) {
        if (!$perm['topup_read']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
        
        if ($action === 'fetch') {
            $limit = 50;
            $page = isset($_GET['page']) && is_numeric($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
            $offset = ($page - 1) * $limit;
            
            $countSql = "SELECT COUNT(t.id) as total FROM topup_orders t LEFT JOIN users u ON t.user_token = u.token WHERE 1=1";
            if ($targetUsername !== '') {
                $countSql .= " AND (u.username = '" . $conn->real_escape_string($targetUsername) . "' OR t.username = '" . $conn->real_escape_string($targetUsername) . "')";
            }
            $totalRows = $conn->query($countSql)->fetch_assoc()['total'];
            $totalPages = ceil($totalRows / $limit);

            $sql = "SELECT t.*, u.username AS live_username FROM topup_orders t LEFT JOIN users u ON t.user_token = u.token WHERE 1=1";
            $params = [];
            $types = "";
            if ($targetUsername !== '') {
                $sql .= " AND (u.username = ? OR t.username = ?)";
                $params[] = $targetUsername; $params[] = $targetUsername;
                $types .= "ss";
            }
            $sql .= " ORDER BY t.id DESC LIMIT ? OFFSET ?";
            $params[] = $limit; $params[] = $offset;
            $types .= "ii";
            
            $stmt = $conn->prepare($sql);
            if ($types) $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
            $data = [];
            while ($row = $res->fetch_assoc()) $data[] = $row;
            $stmt->close();
            echo json_encode(["status" => "success", "data" => $data, "totalPages" => $totalPages, "currentPage" => $page]); exit;
        }

        if ($action === 'process' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : 0;
            $type = isset($_POST['type']) && is_string($_POST['type']) ? trim($_POST['type']) : '';
            
            if (($type === 'success' || $type === 'failed') && !$perm['topup_edit']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }

            $stmt = $conn->prepare("SELECT status, product_price, user_token FROM topup_orders WHERE id = ? LIMIT 1");
            $stmt->bind_param("i", $id);
            $stmt->execute();
            $row = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            
            if (!$row) { echo json_encode(["status" => "error", "message" => "Not found."]); exit; }
            
            $ostatus = $row['status'];
            $cprice = (float)$row['product_price'];
            $ctoken = $row['user_token'];
            
            if ($ostatus === 'success' && $type === 'failed') { echo json_encode(["status" => "error", "message" => "Cannot change success to failed."]); exit; }
            if ($ostatus === $type) { echo json_encode(["status" => "success"]); exit; }
            
            if ($ostatus === 'pending' && $type === 'failed' && !empty($ctoken)) {
                $uStmt = $conn->prepare("UPDATE users SET balance = balance + ? WHERE token = ?");
                $uStmt->bind_param("ds", $cprice, $ctoken); $uStmt->execute(); $uStmt->close();
                sendFCMByIdentifier($conn, 'token', $ctoken, "TopUp Failed", "Your topup order has been failed and refunded.");
            } elseif ($ostatus === 'failed' && $type === 'success' && !empty($ctoken)) {
                $uStmt = $conn->prepare("UPDATE users SET balance = balance - ? WHERE token = ?");
                $uStmt->bind_param("ds", $cprice, $ctoken); $uStmt->execute(); $uStmt->close();
                sendFCMByIdentifier($conn, 'token', $ctoken, "TopUp Successful", "Your topup order was successful.");
            } elseif ($type === 'success' && !empty($ctoken)) {
                sendFCMByIdentifier($conn, 'token', $ctoken, "TopUp Successful", "Your topup order was successful.");
            }
            
            $stmt = $conn->prepare("UPDATE topup_orders SET status=? WHERE id=?");
            $stmt->bind_param("si", $type, $id);
            if ($stmt->execute()) echo json_encode(["status" => "success", "message" => "Order updated"]);
            else echo json_encode(["status" => "error", "message" => "Update failed."]);
            $stmt->close();
            exit;
        }
    }

    elseif ($module === 'shop' && $CONFIG_SHOW_ALL_MODULES) {
        if (!$perm['shop_read']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }
        
        if ($action === 'fetch') {
            $limit = 50;
            $page = isset($_GET['page']) && is_numeric($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
            $offset = ($page - 1) * $limit;
            
            $countSql = "SELECT COUNT(po.id) as total FROM product_orders po LEFT JOIN users u ON po.user_id = u.token WHERE 1=1";
            if ($targetUsername !== '') {
                $countSql .= " AND u.username = '" . $conn->real_escape_string($targetUsername) . "'";
            }
            $countQuery = $conn->query($countSql);
            $totalRows = $countQuery ? $countQuery->fetch_assoc()['total'] : 0;
            $totalPages = ceil($totalRows / $limit);

            $sql = "SELECT po.id, po.order_id, po.product_title, po.product_image, po.amount, po.address, po.extra_json, po.status, po.created_at, u.username, u.uid FROM product_orders po LEFT JOIN users u ON po.user_id = u.token WHERE 1=1";
            $params = [];
            $types = "";
            if ($targetUsername !== '') {
                $sql .= " AND u.username = ?";
                $params[] = $targetUsername;
                $types .= "s";
            }
            $sql .= " ORDER BY po.id DESC LIMIT ? OFFSET ?";
            $params[] = $limit; $params[] = $offset;
            $types .= "ii";

            $stmt = $conn->prepare($sql);
            if ($types) $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
            $data = [];
            while ($row = $res->fetch_assoc()) $data[] = $row;
            $stmt->close();
            
            echo json_encode(["status" => "success", "data" => $data, "totalPages" => $totalPages, "currentPage" => $page]); exit;
        }

        if ($action === 'process' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : 0;
            $type = isset($_POST['type']) && is_string($_POST['type']) ? strtolower(trim($_POST['type'])) : '';

            if (($type === 'success' || $type === 'failed') && !$perm['shop_edit']) {
                echo json_encode(["status" => "error", "message" => "Edit permission denied."]); exit;
            }

            $conn->begin_transaction();
            try {
                $stmt = $conn->prepare("SELECT user_id, amount, status FROM product_orders WHERE id = ? FOR UPDATE");
                $stmt->bind_param("i", $id);
                $stmt->execute();
                $order = $stmt->get_result()->fetch_assoc();
                $stmt->close();

                if (!$order) throw new Exception("Order not found.");

                $current_status = strtolower(trim($order['status'] ?? 'pending'));
                $user_token = (string)$order['user_id'];
                $amount = (float)$order['amount'];

                if ($type === 'success') {
                    if ($current_status === 'success') throw new Exception("Already success.");
                    $stmt = $conn->prepare("SELECT balance, ban_reason FROM users WHERE token = ? FOR UPDATE");
                    $stmt->bind_param("s", $user_token);
                    $stmt->execute();
                    $userData = $stmt->get_result()->fetch_assoc();
                    $stmt->close();

                    if (!$userData) throw new Exception("User not found.");
                    if (strtolower(trim($userData['ban_reason'] ?? '')) === 'ban') throw new Exception("User is banned.");

                    if ($current_status === 'failed') {
                        if ((float)$userData['balance'] < $amount) throw new Exception("Not enough balance.");
                        $stmt = $conn->prepare("UPDATE users SET balance = balance - ? WHERE token = ?");
                        $stmt->bind_param("ds", $amount, $user_token);
                        if (!$stmt->execute()) throw new Exception("Balance deduction failed.");
                        $stmt->close();
                    }

                    $stmt = $conn->prepare("UPDATE product_orders SET status = 'success' WHERE id = ?");
                    $stmt->bind_param("i", $id);
                    if (!$stmt->execute()) throw new Exception("Status update failed.");
                    $stmt->close();
                    $msg = "Order success.";
                    sendFCMByIdentifier($conn, 'token', $user_token, "Order Successful", "Your shop order was successfully processed.");

                } elseif ($type === 'failed') {
                    if ($current_status === 'success') throw new Exception("Cannot fail success order.");
                    if ($current_status === 'failed') throw new Exception("Already failed.");

                    if ($current_status === 'pending') {
                        $stmt = $conn->prepare("UPDATE users SET balance = balance + ? WHERE token = ?");
                        $stmt->bind_param("ds", $amount, $user_token);
                        if (!$stmt->execute()) throw new Exception("Refund failed.");
                        $stmt->close();
                    }

                    $stmt = $conn->prepare("UPDATE product_orders SET status = 'failed' WHERE id = ?");
                    $stmt->bind_param("i", $id);
                    if (!$stmt->execute()) throw new Exception("Status update failed.");
                    $stmt->close();
                    $msg = "Order failed & refunded.";
                    sendFCMByIdentifier($conn, 'token', $user_token, "Order Failed", "Your shop order failed and balance was refunded.");
                } else throw new Exception("Invalid action.");

                $conn->commit();
                echo json_encode(["status" => "success", "message" => $msg]);
            } catch (Exception $e) {
                $conn->rollback();
                echo json_encode(["status" => "error", "message" => $e->getMessage()]);
            }
            exit;
        }
    }

    elseif ($module === 'gift' && $CONFIG_SHOW_ALL_MODULES) {
        if (!$perm['gift_read']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }

        if ($action === 'fetch') {
            $limit = 50;
            $page = isset($_GET['page']) && is_numeric($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
            $offset = ($page - 1) * $limit;

            $countSql = "SELECT COUNT(gr.id) as total FROM gift_requests gr LEFT JOIN users s ON gr.sender_uid = s.uid LEFT JOIN users r ON gr.receiver_uid = r.uid WHERE 1=1";
            if ($targetUsername !== '') {
                $countSql .= " AND (s.username = '" . $conn->real_escape_string($targetUsername) . "' OR r.username = '" . $conn->real_escape_string($targetUsername) . "')";
            }
            $totalRows = $conn->query($countSql)->fetch_assoc()['total'];
            $totalPages = ceil($totalRows / $limit);

            $sql = "SELECT gr.*, s.username AS sender_username, r.username AS receiver_username 
                    FROM gift_requests gr 
                    LEFT JOIN users s ON gr.sender_uid = s.uid 
                    LEFT JOIN users r ON gr.receiver_uid = r.uid WHERE 1=1";
            $params = [];
            $types = "";
            if ($targetUsername !== '') {
                $sql .= " AND (s.username = ? OR r.username = ?)";
                $params[] = $targetUsername; $params[] = $targetUsername;
                $types .= "ss";
            }
            $sql .= " ORDER BY gr.id DESC LIMIT ? OFFSET ?";
            $params[] = $limit; $params[] = $offset;
            $types .= "ii";
            
            $stmt = $conn->prepare($sql);
            if ($types) $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
            $data = [];
            while ($row = $res->fetch_assoc()) $data[] = $row;
            $stmt->close();
            
            echo json_encode(["status" => "success", "data" => $data, "totalPages" => $totalPages, "currentPage" => $page]); exit;
        }

        if ($action === 'process' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $id = isset($_POST['id']) && is_numeric($_POST['id']) ? (int)$_POST['id'] : 0;
            $type = isset($_POST['type']) && is_string($_POST['type']) ? strtolower(trim($_POST['type'])) : '';

            if ($type === 'success' || $type === 'approve') $type = 'approved';
            if ($type === 'fail' || $type === 'reject') $type = 'failed';

            if (($type === 'approved' || $type === 'failed') && !$perm['gift_edit']) { echo json_encode(["status" => "error", "message" => "Permission denied."]); exit; }

            $conn->begin_transaction();
            try {
                $stmt = $conn->prepare("SELECT * FROM gift_requests WHERE id = ? FOR UPDATE");
                $stmt->bind_param("i", $id);
                $stmt->execute();
                $req = $stmt->get_result()->fetch_assoc();
                $stmt->close();

                if (!$req) throw new Exception("Request not found.");

                $current_status = strtolower(trim($req['status'] ?? 'pending'));
                if ($current_status === 'success') $current_status = 'approved';
                
                $sender_uid = (string)$req['sender_uid'];
                $receiver_uid = (string)$req['receiver_uid'];
                $total = (float)$req['total'];
                $amount = (float)$req['amount'];

                if ($type === 'approved') {
                    if ($current_status === 'approved') throw new Exception("Already approved.");
                    
                    $stmt = $conn->prepare("SELECT ban_reason FROM users WHERE uid = ? FOR UPDATE");
                    $stmt->bind_param("s", $receiver_uid);
                    $stmt->execute();
                    $rxUser = $stmt->get_result()->fetch_assoc();
                    $stmt->close();

                    if (!$rxUser) throw new Exception("Receiver user does not exist.");
                    if (strtolower(trim($rxUser['ban_reason'] ?? '')) === 'ban') throw new Exception("Receiver is banned.");

                    if ($current_status === 'failed') {
                        $stmt = $conn->prepare("SELECT balance FROM users WHERE uid = ? FOR UPDATE");
                        $stmt->bind_param("s", $sender_uid);
                        $stmt->execute();
                        $senderData = $stmt->get_result()->fetch_assoc();
                        $stmt->close();

                        if (!$senderData) throw new Exception("Sender does not exist.");
                        if ((float)$senderData['balance'] < $total) throw new Exception("Sender balance low.");

                        $stmt = $conn->prepare("UPDATE users SET balance = balance - ? WHERE uid = ?");
                        $stmt->bind_param("ds", $total, $sender_uid);
                        if (!$stmt->execute()) throw new Exception("Sender deduct failed.");
                        $stmt->close();
                    }

                    $stmt = $conn->prepare("UPDATE gift_requests SET status = 'approved' WHERE id = ?");
                    $stmt->bind_param("i", $id);
                    if (!$stmt->execute()) throw new Exception("Status update failed.");
                    $stmt->close();

                    $stmt = $conn->prepare("UPDATE users SET balance = balance + ? WHERE uid = ?");
                    $stmt->bind_param("ds", $amount, $receiver_uid);
                    if (!$stmt->execute()) throw new Exception("Receiver balance add failed.");
                    $stmt->close();
                    $msg = "Approved & Sent.";
                    
                    sendFCMByIdentifier($conn, 'uid', $receiver_uid, "Gift Received", "You have successfully received a gift of ৳" . $amount);

                } elseif ($type === 'failed') {
                    if ($current_status === 'approved') throw new Exception("Cannot fail approved.");
                    if ($current_status === 'failed') throw new Exception("Already failed.");

                    $stmt = $conn->prepare("SELECT uid FROM users WHERE uid = ? FOR UPDATE");
                    $stmt->bind_param("s", $sender_uid);
                    $stmt->execute();
                    $senderExists = $stmt->get_result()->fetch_assoc();
                    $stmt->close();

                    if (!$senderExists) throw new Exception("Sender user does not exist.");

                    $stmt = $conn->prepare("UPDATE gift_requests SET status = 'failed' WHERE id = ?");
                    $stmt->bind_param("i", $id);
                    if (!$stmt->execute()) throw new Exception("Status update failed.");
                    $stmt->close();

                    $stmt = $conn->prepare("UPDATE users SET balance = balance + ? WHERE uid = ?");
                    $stmt->bind_param("ds", $total, $sender_uid);
                    if (!$stmt->execute()) throw new Exception("Refund failed.");
                    $stmt->close();
                    $msg = "Failed & Refunded.";

                    sendFCMByIdentifier($conn, 'uid', $sender_uid, "Gift Failed", "Your gift request was rejected and balance refunded.");
                } else throw new Exception("Invalid action.");

                $conn->commit();
                echo json_encode(["status" => "success", "message" => $msg]);

            } catch (Exception $e) {
                $conn->rollback();
                echo json_encode(["status" => "error", "message" => $e->getMessage()]);
            }
            exit;
        }
    }
}

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Management System</title>
    <style>
        :root {
            --slate-50: #f8fafc; --slate-100: #f1f5f9; --slate-200: #e2e8f0; --slate-300: #cbd5e1;
            --slate-400: #94a3b8; --slate-500: #64748b; --slate-600: #475569; --slate-700: #334155; 
            --slate-800: #1e293b; --slate-900: #0f172a;
            --primary: #4f46e5; --primary-light: #eeebff;
            --emerald-500: #10b981; --emerald-600: #059669;
            --rose-500: #f43f5e; --rose-600: #e11d48;
            --amber-500: #f59e0b; --amber-600: #d97706;
            --white: #ffffff;
            --shadow-sm: 0 1px 2px 0 rgba(0,0,0,0.05);
            --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.05), 0 2px 4px -1px rgba(0,0,0,0.03);
            --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05);
            --radius-md: 12px; --radius-lg: 16px;
        }
        * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Inter', system-ui, sans-serif; }
        body { background-color: var(--slate-50); color: var(--slate-900); display: flex; height: 100vh; overflow: hidden; }
        
        .sidebar { width: 280px; background: var(--white); border-right: 1px solid var(--slate-200); display: flex; flex-direction: column; flex-shrink: 0; z-index: 10; }
        .sidebar-brand { padding: 24px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--slate-100); }
        .brand-logo { width: 40px; height: 40px; background: linear-gradient(135deg, var(--primary), #818cf8); border-radius: var(--radius-md); display: grid; place-items: center; color: var(--white); font-weight: 800; font-size: 20px; box-shadow: var(--shadow-sm); }
        .brand-text h2 { font-size: 16px; font-weight: 700; color: var(--slate-800); }
        .brand-text p { font-size: 12px; color: var(--slate-500); }
        .sidebar-menu { padding: 24px 16px; flex-grow: 1; overflow-y: auto; }
        .menu-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; color: var(--slate-600); text-decoration: none; font-weight: 600; font-size: 14px; border-radius: 10px; margin-bottom: 8px; transition: all 0.2s ease; }
        .menu-item.active, .menu-item:hover { background: var(--primary-light); color: var(--primary); }
        .menu-item svg { width: 20px; height: 20px; }
        
        .main-content { flex-grow: 1; display: flex; flex-direction: column; overflow: hidden; background: var(--slate-50); }
        
        .top-nav-wrapper { padding: 24px 40px 0 40px; flex-shrink: 0; }
        .top-nav { background: var(--white); padding: 8px; border-radius: var(--radius-lg); display: flex; align-items: center; gap: 8px; box-shadow: var(--shadow-sm); border: 1px solid var(--slate-200); overflow-x: auto; scrollbar-width: none; }
        .top-nav::-webkit-scrollbar { display: none; }
        .top-nav a { text-decoration: none; padding: 10px 18px; border-radius: var(--radius-md); font-weight: 700; font-size: 13px; color: var(--slate-600); transition: all 0.3s ease; white-space: nowrap; display: flex; align-items: center; gap: 8px; }
        .top-nav a svg { width: 16px; height: 16px; opacity: 0.7; }
        .top-nav a:hover { background: var(--slate-50); color: var(--slate-900); }
        .top-nav a.active { background: var(--primary); color: var(--white); box-shadow: 0 4px 12px rgba(79, 70, 229, 0.3); }
        .top-nav a.active svg { opacity: 1; }

        .header { padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; flex-shrink: 0; }
        .header-title h1 { font-size: 22px; font-weight: 800; color: var(--slate-800); letter-spacing: -0.5px; }
        .header-subtitle { font-size: 13px; color: var(--slate-500); margin-top: 4px; font-weight: 500; background: var(--white); padding: 4px 12px; border-radius: 9999px; border: 1px solid var(--slate-200); display: inline-block; }
        
        .tabs { display: flex; gap: 10px; padding: 0 40px 16px 40px; flex-shrink: 0; }
        .tab-btn { background: var(--white); border: 1px solid var(--slate-200); padding: 6px 14px; font-size: 13px; font-weight: 700; color: var(--slate-600); cursor: pointer; border-radius: 8px; transition: 0.2s; box-shadow: var(--shadow-sm); }
        .tab-btn.active { background: var(--primary-light); color: var(--primary); border-color: var(--primary-light); }
        .tab-btn:hover:not(.active) { background: var(--slate-50); }

        .content-body { padding: 0 40px 32px 40px; overflow: hidden; flex-grow: 1; display: flex; flex-direction: column; }
        .table-container { background: var(--white); border: 1px solid var(--slate-200); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; flex-grow: 1; overflow: hidden; }
        .table-scroll { flex-grow: 1; overflow-y: auto; overflow-x: auto; position: relative; }
        
        table { width: 100%; min-width: 800px; border-collapse: collapse; text-align: left; }
        th { background: var(--slate-50); font-weight: 700; color: var(--slate-600); text-transform: uppercase; font-size: 11px; letter-spacing: 0.8px; padding: 12px 16px; position: sticky; top: 0; z-index: 2; border-bottom: 1px solid var(--slate-200); white-space: nowrap; }
        td { padding: 12px 16px; border-bottom: 1px solid var(--slate-100); font-size: 13px; vertical-align: middle; }
        tbody tr { transition: background-color 0.2s; }
        tbody tr:nth-child(even) { background: #f8fafc; }
        tbody tr:hover { background: #f1f5f9; }
        
        .amount-txt { font-weight: 800; font-size: 14px; }
        .amount-txt.add { color: var(--emerald-600); }
        .amount-txt.sub { color: var(--rose-600); }

        .badge { display: inline-flex; align-items: center; font-size: 12px; font-weight: 700; text-transform: capitalize; padding: 4px 10px; border-radius: 6px; }
        .badge.pending { background: #fef3c7; color: #d97706; border: 1px solid #fde68a; }
        .badge.success, .badge.approved { background: #d1fae5; color: #059669; border: 1px solid #a7f3d0; }
        .badge.failed { background: #ffe4e6; color: #e11d48; border: 1px solid #fecdd3; }

        .action-btns { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
        .btn-action { border: none; cursor: pointer; border-radius: 6px; padding: 8px; transition: all 0.2s ease; display: inline-flex; color: var(--white); box-shadow: var(--shadow-sm); }
        .btn-action svg { width: 16px; height: 16px; }
        .btn-action.success-btn { background: var(--emerald-500); }
        .btn-action.failed-btn { background: var(--rose-500); }
        .btn-action.delete-btn { background: var(--slate-700); }

        .pagination-container { padding: 12px 20px; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid var(--slate-200); background: var(--slate-50); z-index: 2; }
        .pagination-info { font-size: 12px; color: var(--slate-500); font-weight: 600; }
        .pagination-controls { display: flex; gap: 6px; }
        .page-btn { padding: 6px 12px; border: 1px solid var(--slate-200); background: var(--white); color: var(--slate-700); border-radius: 6px; cursor: pointer; font-size: 12px; font-weight: 700; transition: 0.2s; }
        .page-btn:hover:not(:disabled) { background: var(--slate-100); }
        .page-btn:disabled { opacity: 0.5; cursor: not-allowed; }

        .loader { text-align: center; color: var(--slate-500); font-weight: 600; font-size: 13px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; position: absolute; inset: 0; background: rgba(255,255,255,0.8); z-index: 5; backdrop-filter: blur(2px); }
        .loader svg { width: 24px; height: 24px; animation: spin 1s linear infinite; color: var(--primary); }
        @keyframes spin { 100% { transform: rotate(360deg); } }

        .toast-container { position: fixed; bottom: 30px; right: 30px; z-index: 1000; display: flex; flex-direction: column; gap: 10px; }
        .toast { padding: 14px 20px; border-radius: 10px; color: #fff; font-size: 13px; font-weight: 600; box-shadow: var(--shadow-lg); animation: slideIn 0.3s forwards; display: flex; align-items: center; gap: 10px; }
        .toast.success { background: var(--emerald-600); }
        .toast.error { background: var(--rose-600); }
        @keyframes slideIn { from { transform: translateX(120%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }

        @media (max-width: 1024px) { .sidebar { width: 80px; } .brand-text, .menu-item span { display: none; } }
        @media (max-width: 768px) { 
            body { flex-direction: column; } 
            .sidebar { width: 100%; height: auto; border-right: none; flex-direction: row; align-items: center; padding: 0 20px; } 
            .sidebar-menu { display: flex; gap: 10px; padding: 10px 0; overflow-x: auto; } 
            .top-nav-wrapper { padding: 16px 16px 0 16px; }
            .header { padding: 16px; } 
            .tabs { padding: 0 16px 16px 16px; overflow-x: auto; }
            .content-body { padding: 0 16px 24px 16px; } 
        }
    </style>
</head>
<body>

<div class="sidebar">
    <div class="sidebar-brand">
        <div class="brand-logo">Z</div>
        <div class="brand-text">
            <h2>Zabbar Engine</h2>
            <p>Management</p>
        </div>
    </div>
    <div class="sidebar-menu">
        <a href="index.php" class="menu-item">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" /></svg>
            <span>Dashboard</span>
        </a>
        <a href="UserInfo.php" class="menu-item">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" /></svg>
            <span>User Info</span>
        </a>
        <a href="#" class="menu-item active">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 6.878V6a2.25 2.25 0 0 1 2.25-2.25h7.5A2.25 2.25 0 0 1 18 6v.878m-12 0c.235-.083.487-.128.75-.128h10.5c.263 0 .515.045.75.128m-12 0A2.25 2.25 0 0 0 4.5 9v.878m13.5-3A2.25 2.25 0 0 1 19.5 9v.878m0 0a2.246 2.246 0 0 0-.75-.128H5.25c-.263 0-.515.045-.75.128m15 0A2.25 2.25 0 0 1 21 12v6a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18v-6c0-.98.626-1.813 1.5-2.122" /></svg>
            <span>Modules Data</span>
        </a>
    </div>
</div>

<div class="main-content">
    <div class="top-nav-wrapper">
        <div class="top-nav">
            <a href="?module=addmoney&username=<?= urlencode($targetUsername) ?>" class="<?= $module === 'addmoney' ? 'active' : '' ?>">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m-3-2.818.879.659c1.171.879 3.07.879 4.242 0 1.172-.879 1.172-2.303 0-3.182C13.536 12.219 12.768 12 12 12c-.725 0-1.45-.22-2.003-.659-1.106-.879-1.106-2.303 0-3.182s2.9-.879 4.006 0l.415.33M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /></svg>
                Add Money
            </a>
            <a href="?module=withdraw&username=<?= urlencode($targetUsername) ?>" class="<?= $module === 'withdraw' ? 'active' : '' ?>">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0 1 15.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 0 1 3 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 0 0-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 0 1-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 0 0 3 15h-.75M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /></svg>
                Withdraw
            </a>
            <a href="?module=match_history&username=<?= urlencode($targetUsername) ?>" class="<?= $module === 'match_history' ? 'active' : '' ?>">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3v11.25A2.25 2.25 0 0 0 6 16.5h2.25M3.75 3h-1.5m1.5 0h16.5m0 0h1.5m-1.5 0v11.25A2.25 2.25 0 0 1 18 16.5h-2.25m-7.5 0h7.5m-7.5 0-1 3m8.5-3 1 3m0 0 .5 1.5m-.5-1.5h-9.5m0 0-.5 1.5m.75-9 3-3 2.148 2.148A12.061 12.061 0 0 1 16.5 7.605" /></svg>
                Match History
            </a>
            <?php if ($CONFIG_SHOW_ALL_MODULES): ?>
                <a href="?module=topup&username=<?= urlencode($targetUsername) ?>" class="<?= $module === 'topup' ? 'active' : '' ?>">TopUp</a>
                <a href="?module=shop&username=<?= urlencode($targetUsername) ?>" class="<?= $module === 'shop' ? 'active' : '' ?>">Shop</a>
                <a href="?module=gift&username=<?= urlencode($targetUsername) ?>" class="<?= $module === 'gift' ? 'active' : '' ?>">Gift</a>
            <?php endif; ?>
        </div>
    </div>

    <div class="header">
        <div class="header-title">
            <h1>
                <?php 
                    if($module==='addmoney') echo 'Add Money';
                    elseif($module==='withdraw') echo 'Withdraw';
                    elseif($module==='match_history') echo 'Match Statistics';
                    else echo ucfirst((string)$module);
                ?>
            </h1>
            <?php if($targetUsername): ?>
                <div class="header-subtitle">Filtered by: <strong><?= htmlspecialchars($targetUsername) ?></strong></div>
            <?php endif; ?>
        </div>
    </div>
    
    <?php if ($CONFIG_ALLOW_STATUS_CHANGE && ($module === 'addmoney' || $module === 'withdraw')): ?>
        <div class="tabs">
            <button class="tab-btn active" onclick="setFilter('all', this)">All</button>
            <button class="tab-btn" onclick="setFilter('pending', this)">Pending</button>
            <button class="tab-btn" onclick="setFilter('success', this)">Success</button>
            <button class="tab-btn" onclick="setFilter('failed', this)">Failed</button>
        </div>
    <?php endif; ?>

    <div class="content-body">
        <div class="table-container">
            <div class="table-scroll" id="scrollArea">
                <div class="loader" id="loader">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" /></svg>
                    <span>Loading Data...</span>
                </div>
                <table id="dataTable" style="display: none;">
                    <thead id="dataHead"></thead>
                    <tbody id="dataBody"></tbody>
                </table>
            </div>
            <div class="pagination-container" id="paginationControls" style="display: none;">
                <div class="pagination-info" id="pageInfo">Showing Page 1</div>
                <div class="pagination-controls" id="pageBtns"></div>
            </div>
        </div>
    </div>
</div>

<div class="toast-container" id="toastContainer"></div>

<script>
    const currentModule = '<?= addslashes($module) ?>';
    const perm = <?= json_encode($perm) ?>;
    const allowStatusChange = <?= $CONFIG_ALLOW_STATUS_CHANGE ? 'true' : 'false' ?>;
    const targetUsername = '<?= addslashes($targetUsername) ?>';
    let currentPage = 1;
    let currentFilter = 'all';
    let isLoading = false;
    let hasMore = true;

    function showToast(message, type = 'success') {
        const container = document.getElementById('toastContainer');
        const toast = document.createElement('div');
        toast.className = `toast ${type}`;
        toast.innerHTML = type === 'success' 
            ? `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" style="width:20px;height:20px;"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg> <span>${message}</span>` 
            : `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" style="width:20px;height:20px;"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3Z"/></svg> <span>${message}</span>`;
        container.appendChild(toast);
        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(120%)';
            setTimeout(() => toast.remove(), 300);
        }, 3000);
    }

    function buildHeaders() {
        const thead = document.getElementById('dataHead');
        let html = '<tr>';
        
        if (currentModule === 'addmoney' || currentModule === 'withdraw') {
            html += `<th style="width: 5%;">ID</th>
                     <th style="width: 15%;">Username</th>
                     <th style="width: 20%;">Payment Method</th>
                     <th style="width: 15%;">TrxID</th>
                     <th style="width: 10%;">Amount</th>
                     <th style="width: 10%;">Status</th>
                     <th style="width: 15%;">Date</th>`;
            if (allowStatusChange && (perm[`${currentModule}_edit`] || perm[`${currentModule}_delete`])) {
                html += `<th style="width: 10%; text-align: right;">Actions</th>`;
            }
        } else if (currentModule === 'match_history') {
            html += `<th style="width: 5%;">#</th>
                     <th style="width: 30%;">Match Title</th>
                     <th style="width: 15%;">Date</th>
                     <th style="width: 15%;">Match ID</th>
                     <th style="width: 20%;">Won Amount</th>
                     <th style="width: 15%; text-align: right;">Entry Fee</th>`;
        } else {
            html += `<th style="width: 25%;">User Info</th>
                     <th style="width: 40%;">Product / Request</th>
                     <th style="width: 20%;">Status & Date</th>`;
            if (allowStatusChange) html += `<th style="width: 15%; text-align: right;">Actions</th>`;
        }
        
        html += '</tr>';
        thead.innerHTML = html;
    }

    if (currentModule === 'addmoney' || currentModule === 'withdraw') {
        window.setFilter = function(filterType, btnElement) {
            if(!allowStatusChange) return;
            document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
            btnElement.classList.add('active');
            currentFilter = filterType;
            loadData(true);
        };

        function loadData(reset = false) {
            if (isLoading) return;
            if (reset) {
                currentPage = 1;
                hasMore = true;
                document.getElementById('dataBody').innerHTML = '';
            }
            if (!hasMore) return;
            
            isLoading = true;
            document.getElementById('loader').style.display = 'flex';
            document.getElementById('dataTable').style.display = 'none';
            buildHeaders();

            fetch(`?module=${currentModule}&api=fetch&page=${currentPage}&filter=${currentFilter}&username=${encodeURIComponent(targetUsername)}`)
                .then(res => res.json())
                .then(res => {
                    document.getElementById('loader').style.display = 'none';
                    if (res.status === 'success') {
                        renderTable(res.data, reset);
                        document.getElementById('dataTable').style.display = 'table';
                        if (res.data.length < 50) hasMore = false;
                    } else {
                        document.getElementById('loader').style.display = 'flex';
                        document.getElementById('loader').innerHTML = `<span style="color:var(--rose-600)">Error: ${res.message}</span>`;
                    }
                })
                .catch(err => {
                    document.getElementById('loader').style.display = 'flex';
                    document.getElementById('loader').innerHTML = `<span style="color:var(--rose-600)">Connection Error</span>`;
                })
                .finally(() => { isLoading = false; });
        }

        function renderTable(data, reset) {
            const tbody = document.getElementById('dataBody');
            if (reset) tbody.innerHTML = '';
            if (data.length === 0 && tbody.innerHTML === '') {
                let cols = allowStatusChange && (perm[`${currentModule}_edit`] || perm[`${currentModule}_delete`]) ? 8 : 7;
                tbody.innerHTML = `<tr><td colspan="${cols}" style="text-align:center; padding: 40px; color:var(--slate-500); font-weight:600;">No records found.</td></tr>`;
                return;
            }

            let html = '';
            data.forEach(item => {
                let sRaw = (item.status || '').trim().toLowerCase();
                let sClass = 'pending';
                if (sRaw === 'success' || sRaw === 'approved') sClass = 'success';
                else if (sRaw === 'failed' || sRaw === 'rejected') sClass = 'failed';
                
                let tClass = currentModule === 'addmoney' ? 'add' : 'sub';
                let sign = currentModule === 'addmoney' ? '+' : '-';
                
                let actionsHtml = '';
                if (allowStatusChange) {
                    let btnHtml = '';
                    if (perm[`${currentModule}_edit`] && sClass === 'pending') {
                        btnHtml += `
                            <button class="btn-action success-btn" onclick="act('approve', ${item.id})" title="Approve">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/></svg>
                            </button>
                            <button class="btn-action failed-btn" onclick="act('reject', ${item.id})" title="Reject">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
                            </button>`;
                    }
                    if (perm[`${currentModule}_delete`]) {
                        btnHtml += `
                            <button class="btn-action delete-btn" onclick="act('delete', ${item.id})" title="Delete">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"/></svg>
                            </button>`;
                    }
                    if (btnHtml !== '') actionsHtml = `<td style="text-align:right; white-space: nowrap;"><div class="action-btns">${btnHtml}</div></td>`;
                    else actionsHtml = `<td></td>`;
                }

                html += `
                    <tr>
                        <td style="color: var(--slate-500); font-weight: 600; white-space: nowrap;">#${item.id}</td>
                        <td style="font-weight: 700; color: var(--slate-800); white-space: nowrap;">${item.username || 'N/A'}</td>
                        <td style="white-space: nowrap;">
                            <span style="font-weight: 700; color: var(--slate-700); text-transform: capitalize;">${item.method || 'N/A'}</span>
                            <span style="color: var(--slate-500); margin-left: 6px;">${item.number || 'N/A'}</span>
                        </td>
                        <td style="font-family: monospace; color: var(--slate-500); white-space: nowrap;">${item.trxid || 'N/A'}</td>
                        <td style="font-weight: 800; white-space: nowrap;" class="${tClass}">${sign} ৳${item.amount || '0'}</td>
                        <td style="white-space: nowrap;">
                            <span class="badge ${sClass}">${item.status || 'Pending'}</span>
                        </td>
                        <td style="color: var(--slate-500); font-size: 13px; white-space: nowrap;">${item.date || ''} ${item.time || ''}</td>
                        ${actionsHtml}
                    </tr>
                `;
            });
            tbody.innerHTML += html;
        }

        const scrollArea = document.getElementById('scrollArea');
        if (scrollArea) {
            scrollArea.addEventListener('scroll', () => {
                if (scrollArea.scrollTop + scrollArea.clientHeight >= scrollArea.scrollHeight - 50) {
                    if (!isLoading && hasMore) { currentPage++; loadData(false); }
                }
            });
        }

        window.act = function(action, id) {
            if (!allowStatusChange && action !== 'delete') {
                showToast('Actions are currently disabled.', 'error'); return;
            }
            if (!confirm('Are you sure?')) return;
            const fd = new FormData(); fd.append('id', id);
            fetch(`?module=${currentModule}&api=${action}`, { method: 'POST', body: fd })
                .then(r => r.json())
                .then(res => {
                    if (res.status === 'success') { showToast('Action successful'); loadData(true); } 
                    else showToast(res.message, 'error');
                }).catch(() => showToast('Error processing request', 'error'));
        };

        window.onload = () => loadData(true);
    }

    if (currentModule === 'topup' || currentModule === 'shop' || currentModule === 'gift' || currentModule === 'match_history') {
        function loadData(page = 1) {
            currentPage = page;
            const loader = document.getElementById('loader');
            const table = document.getElementById('dataTable');
            const pagination = document.getElementById('paginationControls');
            const scrollArea = document.getElementById('scrollArea');
            
            if(scrollArea) scrollArea.scrollTop = 0;
            loader.style.display = 'flex';
            table.style.display = 'none';
            if(pagination) pagination.style.display = 'none';
            buildHeaders();

            fetch(`?module=${currentModule}&api=fetch&page=${page}&username=${encodeURIComponent(targetUsername)}`)
                .then(res => res.json())
                .then(res => {
                    loader.style.display = 'none';
                    if (res.status === 'success') {
                        if (currentModule === 'match_history') renderMatchHistoryTable(res.data);
                        else renderOtherTables(res.data);
                        
                        renderPagination(res.totalPages, res.currentPage);
                        if(pagination) pagination.style.display = res.totalPages > 1 ? 'flex' : 'none';
                        table.style.display = 'table';
                    } else {
                        loader.style.display = 'flex';
                        loader.innerHTML = `<span style="color:var(--rose-600)">Error: ${res.message}</span>`;
                    }
                })
                .catch(err => {
                    loader.style.display = 'flex';
                    loader.innerHTML = `<span style="color:var(--rose-600)">Connection Error</span>`;
                });
        }

        function renderPagination(totalPages, current) {
            const info = document.getElementById('pageInfo');
            const btns = document.getElementById('pageBtns');
            if(!info || !btns) return;
            info.textContent = `Page ${current} of ${totalPages || 1}`;
            btns.innerHTML = '';
            let prevBtn = document.createElement('button');
            prevBtn.className = 'page-btn'; prevBtn.textContent = 'Previous';
            prevBtn.disabled = (current <= 1); prevBtn.onclick = () => loadData(current - 1);
            btns.appendChild(prevBtn);
            let nextBtn = document.createElement('button');
            nextBtn.className = 'page-btn'; nextBtn.textContent = 'Next';
            nextBtn.disabled = (current >= totalPages || totalPages === 0); nextBtn.onclick = () => loadData(current + 1);
            btns.appendChild(nextBtn);
        }

        function renderMatchHistoryTable(data) {
            const tbody = document.getElementById('dataBody');
            tbody.innerHTML = '';
            if (data.length === 0) {
                tbody.innerHTML = `<tr><td colspan="6" style="text-align:center; padding: 40px; color:var(--slate-500); font-weight:600;">No match history found.</td></tr>`;
                return;
            }

            let html = '';
            data.forEach((item, index) => {
                let title = item.match_title || item.match_name || item.title || item.name || 'Unknown Match';
                let date = item.match_time || item.time || item.date || item.created_at || '-';
                let won = item.winning_money || item.won_amount || item.prize || item.won || '0.0';
                let matchId = item.match_id || item.room_id || item.id || '-';
                let fee = item.entry_fee || item.fee || item.amount || '0.0';
                let actualIndex = (currentPage - 1) * 50 + index + 1;

                html += `
                    <tr>
                        <td style="color: var(--slate-500); font-weight: 600; white-space: nowrap;">${actualIndex}</td>
                        <td style="font-weight: 700; color: var(--emerald-600); font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px;">${title}</td>
                        <td style="color: var(--slate-400); font-size: 13px; white-space: nowrap;">${date}</td>
                        <td style="color: var(--slate-500); font-size: 13px; font-weight: 600; white-space: nowrap;">#${matchId}</td>
                        <td style="color: var(--slate-700); font-weight: 700; font-size: 13px; white-space: nowrap;">Won Amount : ${won} Tk</td>
                        <td style="text-align: right; white-space: nowrap;">
                            <span style="background: var(--slate-800); color: var(--white); padding: 4px 8px; border-radius: 6px; font-weight: 800; font-size: 12px; letter-spacing: 0.5px;">TK ${fee}</span>
                        </td>
                    </tr>
                `;
            });
            tbody.innerHTML = html;
        }

        function renderOtherTables(data) {
            const tbody = document.getElementById('dataBody');
            tbody.innerHTML = '';
            if (data.length === 0) {
                let cols = allowStatusChange ? 4 : 3;
                tbody.innerHTML = `<tr><td colspan="${cols}" style="text-align:center; padding: 40px; color:var(--slate-500); font-weight:600;">No records found.</td></tr>`;
                return;
            }

            let html = '';
            data.forEach(item => {
                let currentStatus = (item.status || 'pending').toLowerCase().trim();
                if (currentStatus === 'success') currentStatus = 'approved';

                let actionsHtml = '';
                if (allowStatusChange && (perm[`${currentModule}_edit`] || perm[`${currentModule}_delete`])) {
                    let btnHtml = '';
                    if (perm[`${currentModule}_edit`]) {
                        if (currentStatus === 'pending') {
                            btnHtml += `
                                <button class="btn-action success-btn" onclick="processAction(${item.id}, 'approved', this)" title="Approve">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/></svg>
                                </button>
                                <button class="btn-action failed-btn" onclick="processAction(${item.id}, 'failed', this)" title="Reject">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
                                </button>`;
                        } else if (currentStatus === 'failed') {
                            btnHtml += `
                                <button class="btn-action success-btn" onclick="processAction(${item.id}, 'approved', this)" title="Approve">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/></svg>
                                </button>`;
                        }
                    }
                    if (perm[`${currentModule}_delete`]) {
                        btnHtml += `
                            <button class="btn-action delete-btn" onclick="processAction(${item.id}, 'delete', this)" title="Delete">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"/></svg>
                            </button>`;
                    }
                    if (btnHtml !== '') actionsHtml = `<td style="text-align:right; white-space:nowrap;"><div class="action-btns">${btnHtml}</div></td>`;
                    else actionsHtml = `<td></td>`;
                }

                let displayUser = item.username || item.live_username || item.sender_username || 'Unknown User';
                let displayUid = item.uid || item.sender_uid || 'N/A';
                
                let detailsHtml = '';
                if (currentModule === 'gift') {
                    detailsHtml = `
                        <div style="font-weight:700; white-space:nowrap;">To: <span style="color:var(--primary);">${item.receiver_username || 'Unknown'}</span> (UID: ${item.receiver_uid || '-'})</div>
                        <div style="font-size:12px; margin-top:2px; white-space:nowrap;">Type: <span style="text-transform:uppercase; font-weight:600;">${item.type || '-'}</span> | Total: ৳${item.total || 0}</div>
                    `;
                } else {
                    let pTitle = item.product_title || 'Unknown Product';
                    let pPrice = currentModule === 'shop' ? item.amount : item.product_price;
                    detailsHtml = `<div style="font-weight:700; color:var(--slate-800); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:250px;">${pTitle} <span style="color:var(--primary); margin-left:4px;">৳${pPrice || 0}</span></div>`;
                    if (item.address) detailsHtml += `<div style="font-size:11px; margin-top:2px; color:var(--slate-600); white-space:nowrap;">Address: ${item.address}</div>`;
                }

                html += `
                    <tr>
                        <td style="white-space:nowrap;">
                            <div style="display:flex; flex-direction:column; gap:2px;">
                                <span style="font-weight:800; color:var(--slate-800); font-size:13px;">${displayUser} <span style="font-size:10px;color:#94a3b8;font-weight:500;">#${item.id}</span></span>
                                <span style="font-family:monospace; font-size:11px; color:var(--slate-500);">UID: ${displayUid}</span>
                            </div>
                        </td>
                        <td>${detailsHtml}</td>
                        <td style="white-space:nowrap;">
                            <div style="display:flex; flex-direction:column; gap:4px; align-items:flex-start;">
                                <span class="badge ${currentStatus}">${currentStatus}</span>
                                <div style="font-size:11px; color:var(--slate-500); font-weight:600;">${item.created_at || item.order_date || '-'}</div>
                            </div>
                        </td>
                        ${actionsHtml}
                    </tr>
                `;
            });
            tbody.innerHTML = html;
        }

        window.processAction = function(id, type, btn) {
            if (!allowStatusChange && type !== 'delete') {
                showToast('Actions are currently disabled.', 'error'); return;
            }
            if (!confirm('Are you sure?')) return;
            if (btn) btn.disabled = true;

            const fd = new FormData();
            fd.append('id', id); fd.append('type', type);

            fetch(`?module=${currentModule}&api=process`, { method: 'POST', body: fd })
            .then(res => res.json())
            .then(res => {
                if (res.status === 'success') { showToast(res.message, 'success'); loadData(currentPage); } 
                else { showToast(res.message, 'error'); if (btn) btn.disabled = false; }
            })
            .catch(() => {
                showToast('Connection error.', 'error'); if (btn) btn.disabled = false;
            });
        };

        window.onload = () => loadData(1);
    }
</script>
</body>
</html>