/**
 * Admin Panel Management Script
 * This script handles the admin panel functionality for the Arma 3 game interface.
 * It provides player management, money operations, messaging, and other admin functions.
 */

//=============================================================================
// #region DATA STRUCTURES AND VARIABLES
//=============================================================================

/**
 * Admin data structure - will be populated from the game
 * Contains player information and payday amount configuration
 */
let adminData = {
    players: [],        // List of all players with their details
    paydayAmounts: {}   // Map of paygrade to bonus amount
};

/**
 * Currently selected player ID for operations that require a player selection
 * @type {string|null}
 */
let selectedPlayerId = null;

// #endregion

//=============================================================================
// #region INITIALIZATION AND DATA REQUESTS
//=============================================================================

/**
 * Initialize the admin panel
 * Sets up the UI, requests initial data from the game engine
 */
function initializeAdmin() {
    updateStats();
    setupFilterListeners();
    requestPlayerData();
    requestPaygradeData();
}

/**
 * Request player data from the game engine
 * Sends an event to fetch current player information
 */
function requestPlayerData() {
    const message = {
        event: "REQUEST::PLAYER::DATA",
        data: {}
    };

    // Send request to the game engine
    A3API.SendAlert(JSON.stringify(message));
}

/**
 * Request paygrade data from the game engine
 * Sends an event to fetch current paygrade configuration
 */
function requestPaygradeData() {
    const message = {
        event: "REQUEST::PAYGRADE::DATA",
        data: {}
    };

    // Send request to the game engine
    A3API.SendAlert(JSON.stringify(message));
}

/**
 * Set up a timer to periodically refresh player data
 * Ensures the UI is updated with the latest information
 */
function setupRefreshTimer() {
    setInterval(requestPlayerData, 30000); // Refresh every 30 seconds
}

// #endregion

//=============================================================================
// #region DATA HANDLERS
//=============================================================================

/**
 * Handle paygrade data received from the game engine
 * Processes the paygrade list and updates the UI accordingly
 * 
 * @param {Array} paygradeList - List of paygrade objects with paygrade and bonus properties
 */
function handlePaygradeDataRequest(paygradeList) {
    try {
        // Convert the paygrade list to a map for easier lookup
        const paygradeMap = {};
        paygradeList.forEach(item => {
            paygradeMap[item.paygrade] = item.bonus;
        });

        adminData.paydayAmounts = paygradeMap;

        // Update the player list if we already have player data
        if (adminData.players.length > 0) {
            updatePlayerList();
        }

        console.log("Paygrade data updated successfully");
    } catch (error) {
        console.error("Error updating paygrade data:", error);
    }
}

/**
 * Handle player data received from the game engine
 * Updates the admin panel with current player information
 * 
 * @param {Array} playerList - List of player objects with their details
 */
function handlePlayerDataRequest(playerList) {
    adminData.players = playerList;
    updateStats();
    updatePlayerList();
}

// #endregion

//=============================================================================
// #region UI UPDATES AND DISPLAY
//=============================================================================

/**
 * Update header statistics
 * Shows counts of online players and staff
 */
function updateStats() {
    const onlinePlayers = adminData.players.length;
    const onlineStaff = adminData.players.filter(p => p.paygrade !== "E1").length;

    document.getElementById('playerCount').textContent = onlinePlayers;
    document.getElementById('staffCount').textContent = onlineStaff;
}

/**
 * Set up filter button listeners
 * Configures the filter buttons and search functionality
 */
function setupFilterListeners() {
    const filterButtons = document.querySelectorAll('.filter-btn');

    // Set up filter button click handlers
    filterButtons.forEach(button => {
        button.addEventListener('click', () => {
            filterButtons.forEach(btn => btn.classList.remove('active'));
            button.classList.add('active');
            filterPlayers(button.dataset.filter);
        });
    });

    // Set up search functionality
    const searchInput = document.getElementById('playerSearch');
    searchInput.addEventListener('input', () => {
        const activeFilter = document.querySelector('.filter-btn.active').dataset.filter;
        filterPlayers(activeFilter, searchInput.value);
    });
}

/**
 * Filter players based on category and search term
 * 
 * @param {string} filter - The filter category (all, staff, blufor, etc.)
 * @param {string} searchTerm - Optional search term to filter by name
 */
function filterPlayers(filter, searchTerm = '') {
    let filteredPlayers = adminData.players;

    // Apply category filter
    if (filter === 'staff') {
        filteredPlayers = filteredPlayers.filter(p => p.paygrade !== "E1");
    } else if (filter === 'blufor') {
        filteredPlayers = filteredPlayers.filter(p => p.side === "WEST");
    } else if (filter === 'opfor') {
        filteredPlayers = filteredPlayers.filter(p => p.side === "EAST");
    } else if (filter === 'independent') {
        filteredPlayers = filteredPlayers.filter(p => p.side === "GUER");
    } else if (filter === 'civilian') {
        filteredPlayers = filteredPlayers.filter(p => p.side === "CIV");
    }

    // Apply search filter
    if (searchTerm) {
        const term = searchTerm.toLowerCase();
        filteredPlayers = filteredPlayers.filter(p =>
            p.name.toLowerCase().includes(term)
        );
    }

    updatePlayerList(filteredPlayers);
}

/**
 * Update the player list display
 * Renders the filtered player list with all relevant information
 * 
 * @param {Array} players - List of player objects to display, defaults to all players
 */
function updatePlayerList(players = adminData.players) {
    const playerList = document.getElementById('playerList');
    playerList.innerHTML = players.map(player => {
        const paydayAmount = adminData.paydayAmounts[player.paygrade] || 1000;
        const rankClass = getRankClass(player.paygrade);

        return `
        <div class="player-item" data-id="${player.uid}">
            <div class="player-info">
                <span class="player-name">${player.name}</span>
                <span class="player-rank rank-${rankClass}">${player.paygrade}</span>
                <span class="player-money">${parseInt(player.funds).toLocaleString()}</span>
                <span class="player-payday">Payday: ${paydayAmount.toLocaleString()}</span>
                <span class="player-side side-${player.side.toLowerCase()}">${player.side}</span>
            </div>
            <div class="player-actions">
                <button class="action-btn promote-btn" onclick="updatePaygrade('${player.uid}', true)">
                    Promote
                </button>
                <button class="action-btn demote-btn" onclick="updatePaygrade('${player.uid}', false)">
                    Demote
                </button>
                <button class="action-btn message-btn" onclick="openMessageModal('${player.uid}', '${player.name}')">Message</button>
                <button class="action-btn" onclick="openMoneyModal('${player.uid}')">Modify Money</button>
            </div>
        </div>
    `}).join('');
}

/**
 * Helper function to determine rank class based on paygrade
 * Used for styling different ranks with appropriate CSS classes
 * 
 * @param {string} paygrade - The player's paygrade code
 * @returns {string} CSS class name for the rank
 */
function getRankClass(paygrade) {
    if (paygrade.startsWith('E')) {
        return 'enlisted';
    } else if (paygrade.startsWith('WO')) {
        return 'warrant';
    } else if (paygrade.startsWith('O') ||
        paygrade.startsWith('1') ||
        paygrade.startsWith('2') ||
        paygrade.startsWith('C') ||
        paygrade.startsWith('M')) {
        return 'officer';
    } else {
        return 'enlisted'; // Default
    }
}

// #endregion

//=============================================================================
// #region RANK MANAGEMENT
//=============================================================================

/**
 * Update a player's paygrade (promote or demote)
 * 
 * @param {string} uid - Player's unique identifier
 * @param {boolean} isPromotion - True for promotion, false for demotion
 */
function updatePaygrade(uid, isPromotion) {
    const player = adminData.players.find(p => p.uid === uid);
    if (!player) return;

    // Use the paygrades from the configuration
    const paygrades = Object.keys(adminData.paydayAmounts);
    paygrades.sort((a, b) => adminData.paydayAmounts[a] - adminData.paydayAmounts[b]); // Sort by payment amount

    const currentIndex = paygrades.indexOf(player.paygrade);

    let newPaygrade;
    if (isPromotion && currentIndex < paygrades.length - 1) {
        newPaygrade = paygrades[currentIndex + 1];
    } else if (!isPromotion && currentIndex > 0) {
        newPaygrade = paygrades[currentIndex - 1];
    } else {
        return; // Can't promote/demote further
    }

    const message = {
        event: "UPDATE::PAYGRADE",
        data: [uid, newPaygrade]
    };

    A3API.SendAlert(JSON.stringify(message));

    // Optimistic update
    player.paygrade = newPaygrade;
    updatePlayerList();
}

// #endregion

//=============================================================================
// #region MONEY MANAGEMENT
//=============================================================================

/**
 * Open the money modification modal for a player
 * 
 * @param {string} uid - Player's unique identifier
 */
function openMoneyModal(uid) {
    selectedPlayerId = uid;
    const modal = document.getElementById('moneyModal');
    modal.style.display = 'block';
}

/**
 * Close the money modification modal
 */
function closeMoneyModal() {
    const modal = document.getElementById('moneyModal');
    modal.style.display = 'none';
    document.getElementById('moneyAmount').value = '';
    selectedPlayerId = null;
}

/**
 * Give money to the selected player
 */
function giveMoney() {
    const amount = parseInt(document.getElementById('moneyAmount').value);
    if (amount && selectedPlayerId) {
        handleTransferFunds("advance", amount, selectedPlayerId);
        closeMoneyModal();
    }
}

/**
 * Give money to all players
 */
function giveAllMoney() {
    const amount = parseInt(document.getElementById('giveAllAmount').value);
    const message = {
        event: "ADVANCE::ALL",
        data: [amount]
    }

    A3API.SendAlert(JSON.stringify(message));

    // Request updated player data after giving money to all players
    setTimeout(requestPlayerData, 500); // Short delay to allow server processing
}

/**
 * Take money from the selected player
 */
function takeMoney() {
    const amount = parseInt(document.getElementById('moneyAmount').value);
    if (amount && selectedPlayerId) {
        handleTransferFunds("deduct", amount, selectedPlayerId);
        closeMoneyModal();
    }
}

/**
 * Handle funds transfer for a player
 * 
 * @param {string} condition - "advance" to give money, "deduct" to take money
 * @param {number} amount - Amount of money to transfer
 * @param {string} uid - Player's unique identifier
 */
function handleTransferFunds(condition, amount, uid) {
    const message = {
        event: "HANDLE::TRANSFER",
        data: [condition, amount, uid]
    };

    A3API.SendAlert(JSON.stringify(message));

    // Optimistic update
    const player = adminData.players.find(p => p.uid === uid);
    if (player) {
        if (condition === "advance") {
            player.funds = parseInt(player.funds) + amount;
        } else if (condition === "deduct") {
            player.funds = Math.max(0, parseInt(player.funds) - amount);
        }
        updatePlayerList();
    }
}

// #endregion

//=============================================================================
// #region MESSAGE SYSTEM
//=============================================================================

/**
 * Open the message modal for a player
 * 
 * @param {string} uid - Player's unique identifier
 * @param {string} playerName - Player's name for display
 */
function openMessageModal(uid, playerName) {
    selectedPlayerId = uid;
    const modal = document.getElementById('messageModal');
    document.getElementById('messagePlayerName').textContent = playerName;
    modal.style.display = 'block';
}

/**
 * Close the message modal
 */
function closeMessageModal() {
    const modal = document.getElementById('messageModal');
    modal.style.display = 'none';
    document.getElementById('messageInput').value = '';
    selectedPlayerId = null;
}

/**
 * Send a message to the selected player
 */
function sendPlayerMessage() {
    const message = document.getElementById('messageInput').value;
    if (message && selectedPlayerId) {
        const messageData = {
            event: "SEND::MESSAGE",
            data: [selectedPlayerId, message]
        };

        A3API.SendAlert(JSON.stringify(messageData));
        closeMessageModal();
    }
}

/**
 * Broadcast a message to all players
 */
function broadcastMessage() {
    const message = document.getElementById('broadcastMessage').value;
    if (message) {
        const messageData = {
            event: "BROADCAST::MESSAGE",
            data: ["", message]
        };

        A3API.SendAlert(JSON.stringify(messageData));
        document.getElementById('broadcastMessage').value = '';
    }
}

// #endregion

//=============================================================================
// #region GLOBAL ACTIONS
//=============================================================================

/**
 * Trigger a payday for all players
 */
function Payday() {
    const message = {
        event: "HANDLE::PAYDAY",
        data: []
    };

    A3API.SendAlert(JSON.stringify(message));

    // Request updated player data after payday
    setTimeout(requestPlayerData, 500); // Short delay to allow server processing
}

// #endregion

//=============================================================================
// #region EVENT LISTENERS
//=============================================================================

/**
 * Initialize when DOM is loaded
 */
document.addEventListener('DOMContentLoaded', () => {
    initializeAdmin();
    setupRefreshTimer();
});

// #endregion