BW WAR Tracker (PDA Debug Mode)

Chain Queue & Enemy Faction Tracker

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         BW WAR Tracker (PDA Debug Mode)
// @namespace    http://tampermonkey.net/
// @version      11.6
// @description  Chain Queue & Enemy Faction Tracker
// @author       Tu
// @match        https://www.torn.com/*
// @icon         https://www.torn.com/favicon.ico
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @connect      api.torn.com
// @connect      bw-war-tracker-default-rtdb.europe-west1.firebasedatabase.app
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    const ADMIN_ID = 3946434; // ID-ul tau
    const DB_URL = "https://bw-war-tracker-default-rtdb.europe-west1.firebasedatabase.app";

    let currentUser = null;
    let targetsList = [];
    let queueList = [];
    let lastTargetsJson = "";
    let lastQueueJson = "";
    let isPolling = false;
    let pollingInterval = null;
    let statusInterval = null;

    function initScript() {
        if (document.body) {
            try { setupScript(); } catch (e) { console.error("Init Error:", e); }
        } else { setTimeout(initScript, 100); }
    }

    function setupScript() {
        GM_addStyle(`
            #bw-war-button { position: fixed !important; bottom: 20px !important; left: 20px !important; background-color: #000 !important; color: #fff !important; border: 2px solid #fff !important; padding: 12px 24px !important; font-size: 14px !important; font-weight: bold; cursor: pointer; border-radius: 5px; z-index: 2147483647 !important; box-shadow: 0 2px 10px rgba(0,0,0,0.5) !important; transition: all 0.3s !important; }
            #bw-war-button:hover { background-color: #333 !important; transform: translateY(-2px) !important; }
            #bw-war-modal, #bw-settings-modal { display: none !important; position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; width: 90% !important; max-width: 1200px !important; height: 85% !important; background-color: rgba(20, 20, 20, 0.98) !important; border: 2px solid #444 !important; border-radius: 10px !important; z-index: 2147483647 !important; box-shadow: 0 10px 40px rgba(0,0,0,0.9) !important; color: #fff !important; font-family: Arial, sans-serif !important; }
            #bw-war-modal.active, #bw-settings-modal.active { display: flex !important; flex-direction: column !important; overflow: hidden !important; }
            #bw-war-overlay { display: none !important; position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; background-color: rgba(0,0,0,0.85) !important; z-index: 2147483646 !important; backdrop-filter: blur(2px) !important; }
            #bw-war-overlay.active { display: block !important; }
            .bw-modal-header { background: #000 !important; padding: 15px !important; border-bottom: 1px solid #333 !important; display: flex !important; flex-direction: column !important; align-items: center !important; position: relative !important; }
            .bw-modal-title { font-size: 22px !important; font-weight: 900 !important; text-transform: uppercase !important; letter-spacing: 1px !important; margin-top: 10px !important; }
            .bw-header-buttons { position: absolute !important; top: 15px !important; right: 15px !important; display: flex !important; gap: 10px !important; }
            .bw-settings-button, .bw-close-button, .bw-back-button { background: transparent !important; border: 1px solid #fff !important; color: #fff !important; width: 30px !important; height: 30px !important; border-radius: 50% !important; cursor: pointer !important; display: flex !important; align-items: center !important; justify-content: center !important; font-size: 14px !important; }
            .bw-back-button { position: absolute !important; left: 15px !important; top: 15px !important; font-size: 18px !important; border: none !important; width: auto !important; }
            .bw-user-info { position: absolute !important; left: 15px !important; top: 50% !important; transform: translateY(-50%) !important; display: flex !important; align-items: center !important; gap: 15px !important; width: 100%; }
            .bw-user-details { display: flex; flex-direction: column; }
            .bw-user-stats { font-size: 11px !important; color: #888 !important; }
            .bw-user-name { color: #fff !important; font-weight: bold !important; text-decoration: none !important; }
            
            .bw-header-queue { 
                color: #fff !important; 
                border: 1px solid #fff !important; 
                padding: 1px 6px !important; 
                border-radius: 4px; 
                font-size: 10px !important; 
                margin-top: 4px !important; 
                width: fit-content !important;
                font-weight: bold;
            }

            .bw-tabs { display: flex !important; background: #111 !important; border-bottom: 1px solid #333 !important; }
            .bw-tab { flex: 1 !important; padding: 15px !important; background: #111 !important; color: #666 !important; border: none !important; cursor: pointer !important; font-weight: bold !important; text-transform: uppercase !important; transition: 0.2s !important; }
            .bw-tab:hover { color: #fff !important; background: #222 !important; }
            .bw-tab.active { background: #000 !important; color: #fff !important; border-bottom: 3px solid #fff !important; }
            .bw-tab-content { display: none !important; padding: 20px !important; overflow-y: auto !important; flex: 1 !important; }
            .bw-tab-content.active { display: block !important; }
            .bw-target-item, .bw-queue-item { background: #0a0a0a !important; border: 1px solid #333 !important; padding: 8px 15px !important; margin-bottom: 6px !important; border-radius: 4px !important; display: flex !important; justify-content: space-between !important; align-items: center !important; }
            .bw-target-name { color: #fff !important; font-weight: bold !important; text-decoration: none !important; font-size: 15px !important; pointer-events: auto !important; }
            .bw-target-name:hover { text-decoration: underline !important; color: #ccc !important; }
            .bw-input-section { display: flex !important; gap: 10px !important; margin-bottom: 10px !important; align-items: center !important; }
            .bw-input-field { flex: 1 !important; padding: 10px !important; background: #000 !important; border: 1px solid #444 !important; color: #fff !important; border-radius: 4px !important; }
            .bw-btn { background: #000 !important; color: #fff !important; border: 1px solid #fff !important; padding: 6px 15px !important; border-radius: 3px !important; cursor: pointer !important; font-weight: bold !important; font-size: 11px !important; text-transform: uppercase !important; }
            .bw-btn:hover { background: #fff !important; color: #000 !important; }
            
            /* DONE Button Style */
            .bw-btn-done { background: #1a1a1a !important; color: #bbb !important; border: 1px solid #555 !important; }
            .bw-btn-done:hover { background: #333 !important; color: #fff !important; border-color: #fff !important; }

            .bw-btn-disabled { background: #333 !important; color: #888 !important; border-color: #555 !important; cursor: not-allowed !important; }
            .bw-btn-error { background: #ff0000 !important; border-color: #ff0000 !important; color: white !important; }
            .stat-red { color: #ff4444 !important; } .stat-orange { color: #ffbb33 !important; } .stat-yellow { color: #ffeb3b !important; } .stat-green { color: #00c851 !important; } .stat-lightgreen { color: #69f0ae !important; } .stat-blue { color: #33b5e5 !important; } .stat-white { color: #fff !important; }
            .bw-status-text { font-size: 10px !important; font-weight: bold !important; margin-left: 5px !important; }
            .bw-loading { color: #666 !important; text-align: center !important; padding: 40px !important; font-style: italic !important; }
            .bw-queue-toggle { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #333; }
            .bw-queue-count { font-size: 12px; color: #888; }
            .bw-queue-info { font-size: 11px; color: #888; margin-top: 5px; }
            .bw-stats-input { background: #222; border: 1px solid #444; color: #fff; padding: 3px 5px; font-size: 11px; width: 80px; margin-right: 5px; border-radius: 3px; }
            .bw-icon-btn { background: transparent; border: none; cursor: pointer; color: #888; padding: 0 4px; font-size: 14px; transition: color 0.2s; }
            .bw-icon-btn:hover { color: #fff; }
            .bw-stats-wrapper { font-size: 12px; margin-top: 3px; display: flex; align-items: center; height: 20px; }
        `);

        const button = document.createElement('button');
        button.id = 'bw-war-button';
        button.textContent = 'BW WAR';
        document.body.appendChild(button);

        const overlay = document.createElement('div');
        overlay.id = 'bw-war-overlay';
        document.body.appendChild(overlay);

        const modal = document.createElement('div');
        modal.id = 'bw-war-modal';
        modal.innerHTML = `
            <div class="bw-modal-header">
                <div class="bw-user-info">
                    <div class="bw-user-details">
                        <a href="#" target="_blank" class="bw-user-name" id="user-name-link">Loading...</a>
                        <span class="bw-user-stats" id="user-total-stats">Loading...</span>
                        <span id="header-queue-status" class="bw-header-queue">Q: 0/15</span>
                    </div>
                </div>
                <div class="bw-header-buttons"><button class="bw-settings-button">⚙️</button><button class="bw-close-button">✕</button></div>
                <img src="https://factionimages.torn.com/08099e78-0a69-4424-8ccd-5219338250ad-40039.png" style="max-width: 200px; height: 50px; margin-bottom: 10px;">
                <div class="bw-modal-title">Black & White War Manager</div>
            </div>
            <div class="bw-tabs">
                <button class="bw-tab active" data-tab="targets">Enemy Faction</button>
                <button class="bw-tab" data-tab="queue">Chain Queue</button>
            </div>
            <div class="bw-tab-content active" id="targets-content">
                <div class="bw-input-section" id="admin-import-section" style="display:none;">
                    <button id="clear-faction-btn" class="bw-btn">Clear</button>
                    <input type="text" id="faction-import-input" class="bw-input-field" placeholder="Faction ID">
                    <button id="import-faction-btn" class="bw-btn">Add</button>
                </div>
                <div id="targets-list"></div>
            </div>
            <div class="bw-tab-content" id="queue-content" style="position:relative;">
                <div class="bw-queue-toggle">
                    <span style="color:#fff;font-weight:bold;">CHAIN QUEUE</span>
                    <span class="bw-queue-count" id="queue-count" style="display:none;margin-left:10px;">0/15</span>
                </div>
                <div id="queue-active-area">
                    <div id="queue-current-display"></div>
                    <div style="color:#888;font-size:12px;margin:10px 0 5px;">Upcoming:</div>
                    <div id="queue-list"></div>
                </div>
            </div>
        `;
        document.body.appendChild(modal);

        const settingsModal = document.createElement('div');
        settingsModal.id = 'bw-settings-modal';
        settingsModal.innerHTML = `
            <div class="bw-modal-header">
                <button class="bw-back-button">←</button>
                <div class="bw-header-buttons"><button class="bw-close-button settings-close">✕</button></div>
                <div class="bw-modal-title">Settings</div>
            </div>
            <div style="padding: 40px; display: flex; flex-direction: column; align-items: center;">
                <label style="color: #fff; margin-bottom: 10px; font-weight: bold;">Torn API Key (Limited/Full)</label>
                <div style="display: flex; width: 100%; max-width: 300px; gap: 10px;">
                    <input type="text" id="api-key-input" class="bw-input-field" placeholder="Enter Key" style="text-align: center;">
                    <button id="save-api-key" class="bw-btn">Save</button>
                </div>
                <div style="color:#666;font-size:10px;margin-top:10px;">Requires Limited Access for Stats</div>
            </div>
        `;
        document.body.appendChild(settingsModal);

        // HELPERS
        function getApiKey() { return GM_getValue('torn_api_key', ''); }
        function formatBigNumber(num) { if (!num) return '0'; if (num >= 1e9) return (num / 1e9).toFixed(2) + 'B'; if (num >= 1e6) return (num / 1e6).toFixed(2) + 'M'; if (num >= 1e3) return (num / 1e3).toFixed(2) + 'K'; return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }
        function convertToK(num) { return Math.round(num / 1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }
        function formatStatsDisplay(valInK) { if (!valInK || valInK === "N/A") return "???"; let num = parseFloat(valInK.toString().replace(/,/g, '')); if (num >= 1000000) return (num / 1000000).toFixed(1).replace('.0', '') + 'B'; if (num >= 1000) return (num / 1000).toFixed(1).replace('.0', '') + 'M'; return Math.round(num) + 'k'; }
        function getStatusHtml(status) { if (!status) return ''; let color = '#fff'; let text = status.state; if (status.state === 'Okay') { color = '#00ff00'; text = 'OK'; } else if (status.state === 'Hospital') { color = '#ff4444'; if (status.until) { let remaining = status.until - (Date.now() / 1000); let mins = Math.max(0, Math.floor(remaining / 60)); text = `H (${mins}m)`; } else text = 'Hosp'; } else if (status.state === 'Traveling' || status.state === 'Abroad') { color = '#00ccff'; text = 'Abroad'; } return `<span class="bw-status-text" style="color:${color}">[${text}]</span>`; }
        function tornApiCall(endpoint) { return new Promise((resolve, reject) => { const key = getApiKey(); if (!key) { reject('No API Key'); return; } GM_xmlhttpRequest({ method: 'GET', url: `https://api.torn.com/${endpoint}&key=${key}`, onload: (res) => { try { const d = JSON.parse(res.responseText); if (d.error) reject(d.error.error); else resolve(d); } catch (e) { reject(e); } }, onerror: () => reject('Network Error') }); }); }

        // DATA
        function fetchData() {
            if (isPolling) return;
            isPolling = true;
            GM_xmlhttpRequest({
                method: "GET", url: `${DB_URL}/targets.json`, onload: (res) => {
                    if (res.status === 200) {
                        const newData = res.responseText ? Object.entries(JSON.parse(res.responseText) || {}).map(([k, v]) => ({ ...v, firebaseId: k })) : [];
                        if (JSON.stringify(newData) !== lastTargetsJson) { targetsList = newData; lastTargetsJson = JSON.stringify(newData); renderTargets(); }
                    }
                    GM_xmlhttpRequest({
                        method: "GET", url: `${DB_URL}/queue.json`, onload: (res2) => {
                            isPolling = false;
                            if (res2.status === 200) {
                                const qData = JSON.parse(res2.responseText) || {};
                                const list = qData.list ? Object.values(qData.list).sort((a, b) => a.timestamp - b.timestamp) : [];
                                
                                const headerQ = document.getElementById('header-queue-status');
                                if(headerQ) { headerQ.textContent = `Q: ${list.length}/15`; }
                                const countEl = document.getElementById('queue-count');
                                if(countEl) { countEl.textContent = `${list.length}/15`; countEl.style.display = 'inline'; }

                                if (JSON.stringify(list) !== lastQueueJson) { queueList = list; lastQueueJson = JSON.stringify(list); renderQueue(); }
                            }
                        }, onerror: () => isPolling = false
                    });
                }, onerror: () => isPolling = false
            });
        }

        function startPolling() { if (pollingInterval) clearInterval(pollingInterval); if (statusInterval) clearInterval(statusInterval); fetchData(); pollingInterval = setInterval(fetchData, 3000); if (currentUser && currentUser.player_id === ADMIN_ID) statusInterval = setInterval(refreshFactionStatus, 60000); }
        function bulkWriteDB(dataObj) { return new Promise((resolve) => { GM_xmlhttpRequest({ method: "PUT", url: `${DB_URL}/targets.json`, data: JSON.stringify(dataObj), headers: { "Content-Type": "application/json" }, onload: () => { fetchData(); resolve(); } }); }); }
        function clearNodeDB(node) { return new Promise(resolve => GM_xmlhttpRequest({ method: "DELETE", url: `${DB_URL}/${node}.json`, onload: () => { fetchData(); resolve(); } })); }
        function joinQueueDB(entry) { return new Promise((resolve) => GM_xmlhttpRequest({ method: "POST", url: `${DB_URL}/queue/list.json`, data: JSON.stringify(entry), headers: { "Content-Type": "application/json" }, onload: () => { fetchData(); resolve(); } })); }
        
        // OLD RELIABLE REMOVE FUNCTION (No changes here, it works on PC)
        function removeFromQueueDB(id) { 
            GM_xmlhttpRequest({ 
                method: "GET", url: `${DB_URL}/queue/list.json`, 
                onload: (res) => { 
                    const data = JSON.parse(res.responseText); 
                    for (let k in data) { 
                        if (data[k].timestamp == id) { 
                            GM_xmlhttpRequest({ method: "DELETE", url: `${DB_URL}/queue/list/${k}.json`, onload: () => fetchData() }); 
                            break; 
                        } 
                    } 
                } 
            }); 
        }
        
        function updateTargetStatsDB(firebaseId, newStats) { GM_xmlhttpRequest({ method: "PATCH", url: `${DB_URL}/targets/${firebaseId}.json`, data: JSON.stringify({ customStats: newStats }), headers: { "Content-Type": "application/json" } }); }

        let trackedFactionId = GM_getValue('bw_tracked_faction_id', null);
        async function refreshFactionStatus() { if (!trackedFactionId || !currentUser || currentUser.player_id !== ADMIN_ID) return; try { const d = await tornApiCall(`faction/${trackedFactionId}?selections=basic`); if (!d.members) return; const updates = {}; let hasUpdates = false; for (let target of targetsList) { const pid = target.player_id || target.id; if (d.members[pid]) { const newStatus = d.members[pid].status; if (!target.status || target.status.state !== newStatus.state || Math.abs((target.status.until || 0) - (newStatus.until || 0)) > 60) { updates[`${target.firebaseId}/status`] = newStatus; hasUpdates = true; } } } if (hasUpdates) GM_xmlhttpRequest({ method: "PATCH", url: `${DB_URL}/targets.json`, data: JSON.stringify(updates), headers: { "Content-Type": "application/json" } }); } catch (e) { } }

        function renderQueue() {
            const current = queueList.length > 0 ? queueList[0] : null;
            const nextList = queueList.slice(1);
            const currDisplay = document.getElementById('queue-current-display');
            if (currDisplay) {
                if (current) {
                    const isMe = currentUser && current.attackerId === currentUser.player_id;
                    const isAdmin = currentUser && currentUser.player_id === ADMIN_ID;
                    
                    // --- MODIFICARE AICI: BUTOANELE ---
                    let buttonsHtml = '';
                    
                    // Buton 1: ATTACK (Standard PC, Timer 15s)
                    if (isMe) {
                        buttonsHtml += `<button class="bw-btn bw-queue-attack-btn" data-ts="${current.timestamp}" data-tid="${current.targetId}" style="margin-right:5px;">ATTACK</button>`;
                    }
                    
                    // Buton 2: DONE (Manual, pentru PDA sau Admin, sterge fara sa deschida link)
                    if (isMe || isAdmin) {
                        buttonsHtml += `<button class="bw-btn bw-btn-done bw-queue-done-btn" data-ts="${current.timestamp}">DONE</button>`;
                    }

                    let atkStats = current.attackerStats ? `<div style="font-size:11px;color:#fff;">${current.attackerStats}</div>` : '';
                    let defStats = current.targetStats ? `<div class="stat-white" style="font-size:11px;">${formatStatsDisplay(current.targetStats)} Stats</div>` : '';
                    currDisplay.innerHTML = `<div style="background:#111; border:2px solid #fff; padding:15px; margin-bottom:20px; text-align:center; border-radius:5px;"><div style="font-size:16px;font-weight:bold;color:#fff;">CURRENT ATTACKER</div>${atkStats}<div style="font-size:14px;color:#00ff00;margin:5px 0;">${current.attackerName}</div><div style="color:#888;">vs</div><div style="font-size:14px;color:#ff4444;margin-bottom:10px;">${current.targetName}</div>${defStats}<div style="margin-top:10px;">${buttonsHtml}</div></div>`;
                } else { currDisplay.innerHTML = '<div style="text-align:center;color:#444;padding:20px;">Queue Empty</div>'; }
            }
            const listContainer = document.getElementById('queue-list');
            if (listContainer) { listContainer.innerHTML = nextList.map((item, idx) => `<div class="bw-queue-item"><div><span style="color:#888;">${idx + 1}.</span> ${item.attackerName} <span style="color:#666;">vs</span> ${item.targetName}</div></div>`).join(''); }
            renderTargets();
        }

        function renderTargets() {
            const container = document.getElementById('targets-list');
            if (!container || targetsList.length === 0) { if (container) container.innerHTML = '<div class="bw-loading">No targets</div>'; return; }
            targetsList.sort((a, b) => (parseFloat((b.customStats || "0").replace(/,/g, '')) - parseFloat((a.customStats || "0").replace(/,/g, ''))));
            const isAdmin = currentUser && currentUser.player_id === ADMIN_ID;
            const isUserInQueue = currentUser && queueList.some(q => q.attackerId == currentUser.player_id);

            container.innerHTML = targetsList.map(item => {
                const targetId = item.player_id || item.id || "Unknown";
                const displayStats = item.customStats && item.customStats !== "N/A" ? formatStatsDisplay(item.customStats) : "???";
                const rawStats = item.customStats || "";
                let statsHtml = "";
                if (isAdmin) {
                    statsHtml = `<div class="bw-stats-wrapper" id="stats-wrapper-${item.firebaseId}"><span class="stats-display-mode" style="color:#fff;">${displayStats} Stats <button class="bw-icon-btn bw-edit-mode-btn" data-fid="${item.firebaseId}">✎</button></span><span class="stats-edit-mode" style="display:none;"><input type="text" class="bw-stats-input" id="input-${item.firebaseId}" value="${rawStats}"><button class="bw-icon-btn bw-save-stats" data-fid="${item.firebaseId}">💾</button><button class="bw-icon-btn bw-cancel-stats" data-fid="${item.firebaseId}">✕</button></span></div>`;
                } else {
                    statsHtml = `<div style="color:#fff;font-size:12px;margin-top:3px;">${displayStats} Stats</div>`;
                }
                let statusHtml = getStatusHtml(item.status);
                let actionHtml = '';
                if (isUserInQueue) {
                    actionHtml = '<span style="color:#666;font-size:11px;font-style:italic;">In Queue</span>';
                } else {
                    actionHtml = `<button class="bw-btn bw-attack-and-join" data-tid="${targetId}" data-tname="${item.name}" data-tstats="${item.customStats || 'N/A'}">Join Queue</button>`;
                }
                return `<div class="bw-target-item"><div><a href="https://www.torn.com/profiles.php?XID=${targetId}" target="_blank" class="bw-target-name">${item.name} [${targetId}] <span style="color:#444;font-size:10px;">Lvl ${item.level || '?'}</span></a>${statusHtml}${statsHtml}</div><div style="display:flex;align-items:center;">${actionHtml}</div></div>`;
            }).join('');
        }

        function attachGlobalListeners() {
            document.body.addEventListener('click', async (e) => {
                if (e.target.classList.contains('bw-attack-and-join')) {
                    const btn = e.target;
                    const tid = btn.dataset.tid; const tname = btn.dataset.tname; const tstats = btn.dataset.tstats;
                    if (queueList.length >= 15) {
                        const originalText = btn.textContent; btn.classList.add('bw-btn-error'); btn.textContent = "Queue Full!!!";
                        setTimeout(() => { btn.classList.remove('bw-btn-error'); btn.textContent = originalText; }, 2000); return;
                    }
                    const myStats = formatStatsDisplay(convertToK(currentUser.totalStats));
                    await joinQueueDB({ attackerName: currentUser.name, attackerId: currentUser.player_id, attackerStats: myStats, targetName: tname, targetId: tid, targetStats: tstats, timestamp: Date.now() });
                    const queueTabBtn = document.querySelector('.bw-tab[data-tab="queue"]'); if(queueTabBtn) queueTabBtn.click();
                }
                if (e.target.classList.contains('bw-edit-mode-btn')) { const fid = e.target.dataset.fid; const wrapper = document.getElementById(`stats-wrapper-${fid}`); if (wrapper) { wrapper.querySelector('.stats-display-mode').style.display = 'none'; wrapper.querySelector('.stats-edit-mode').style.display = 'flex'; wrapper.querySelector('.bw-stats-input').focus(); } }
                if (e.target.classList.contains('bw-save-stats')) { const fid = e.target.dataset.fid; const wrapper = document.getElementById(`stats-wrapper-${fid}`); const input = document.getElementById(`input-${fid}`); if (wrapper && input) { const newVal = input.value.trim(); updateTargetStatsDB(fid, newVal); const displayEl = wrapper.querySelector('.stats-display-mode'); displayEl.innerHTML = `${formatStatsDisplay(newVal)} Stats <button class="bw-icon-btn bw-edit-mode-btn" data-fid="${fid}">✎</button>`; wrapper.querySelector('.stats-display-mode').style.display = 'block'; wrapper.querySelector('.stats-edit-mode').style.display = 'none'; } }
                if (e.target.classList.contains('bw-cancel-stats')) { const fid = e.target.dataset.fid; const wrapper = document.getElementById(`stats-wrapper-${fid}`); if (wrapper) { wrapper.querySelector('.stats-display-mode').style.display = 'block'; wrapper.querySelector('.stats-edit-mode').style.display = 'none'; } }
                
                // AUTOMATIC BUTTON (15s Timer) - For PC
                if (e.target.classList.contains('bw-queue-attack-btn')) { 
                    const btn = e.target; 
                    window.open(`https://www.torn.com/loader.php?sid=attack&user2ID=${btn.dataset.tid}`, '_blank'); 
                    btn.disabled = true; 
                    let countdown = 15; 
                    btn.textContent = `${countdown}s...`; 
                    const timer = setInterval(() => { 
                        countdown--; 
                        btn.textContent = `${countdown}s...`; 
                        if (countdown <= 0) { 
                            clearInterval(timer); 
                            removeFromQueueDB(btn.dataset.ts); 
                        } 
                    }, 1000); 
                }

                // MANUAL DONE BUTTON (For PDA/Mobile)
                if (e.target.classList.contains('bw-queue-done-btn')) {
                    const btn = e.target;
                    btn.disabled = true;
                    btn.textContent = "...";
                    removeFromQueueDB(btn.dataset.ts); // Functioneaza sigur cu GM_xmlhttpRequest
                }
            });
        }

        const importBtn = document.getElementById('import-faction-btn'); if (importBtn) importBtn.addEventListener('click', async () => { const fid = document.getElementById('faction-import-input').value.trim(); if (!fid) return; GM_setValue('bw_tracked_faction_id', fid); trackedFactionId = fid; try { const d = await tornApiCall(`faction/${fid}?selections=basic`); if (!d.members) throw "Empty"; const bulkData = {}; for (const [id, details] of Object.entries(d.members)) { if (details.name) { bulkData[id] = { player_id: id, name: details.name, level: details.level, status: details.status, customStats: "" }; } } await bulkWriteDB(bulkData); document.getElementById('faction-import-input').value = ''; } catch (e) { alert('Error: ' + e); } });
        const clearBtn = document.getElementById('clear-faction-btn'); if (clearBtn) clearBtn.addEventListener('click', async () => { await clearNodeDB('targets'); });

        function openModal() { document.getElementById('bw-war-modal').classList.add('active'); document.getElementById('bw-war-overlay').classList.add('active'); loadUserInfo(); startPolling(); }
        function closeModals() { document.querySelectorAll('.active').forEach(el => el.classList.remove('active')); }
        document.querySelector('.bw-settings-button').addEventListener('click', () => { document.getElementById('bw-war-modal').classList.remove('active'); document.getElementById('bw-settings-modal').classList.add('active'); document.getElementById('api-key-input').value = getApiKey(); });
        document.querySelector('.bw-back-button').addEventListener('click', () => { document.getElementById('bw-settings-modal').classList.remove('active'); document.getElementById('bw-war-modal').classList.add('active'); });
        document.getElementById('bw-war-button').addEventListener('click', openModal);
        document.getElementById('bw-war-overlay').addEventListener('click', closeModals);
        document.querySelectorAll('.bw-close-button').forEach(b => b.addEventListener('click', closeModals));
        document.getElementById('save-api-key').addEventListener('click', () => { const k = document.getElementById('api-key-input').value.trim(); if (k) { GM_setValue('torn_api_key', k); alert('Saved'); } });
        const tabs = document.querySelectorAll('.bw-tab'); tabs.forEach(t => t.addEventListener('click', () => { document.querySelectorAll('.active').forEach(e => { if (e.classList.contains('bw-tab') || e.classList.contains('bw-tab-content')) e.classList.remove('active'); }); t.classList.add('active'); document.getElementById(`${t.dataset.tab}-content`).classList.add('active'); }));

        attachGlobalListeners();

        // CACHED USER INFO
        async function loadUserInfo() {
            const cachedUser = GM_getValue('bw_cached_user', null);
            if (cachedUser) {
                currentUser = cachedUser;
                const adminDiv = document.getElementById('admin-import-section'); if (adminDiv) adminDiv.style.display = (cachedUser.player_id === ADMIN_ID) ? 'flex' : 'none';
                document.getElementById('user-total-stats').textContent = formatBigNumber(cachedUser.totalStats);
                const userLink = document.getElementById('user-name-link'); userLink.href = `https://www.torn.com/profiles.php?XID=${cachedUser.player_id}`; userLink.textContent = `${cachedUser.name} [${cachedUser.player_id}]`;
            }
            try {
                const data = await tornApiCall('user/?selections=profile,battlestats');
                const total = (data.strength || 0) + (data.defense || 0) + (data.speed || 0) + (data.dexterity || 0);
                if (total <= 0 && cachedUser) { console.log("BW Tracker: API didn't return stats, using cache."); return; }
                data.totalStats = total; currentUser = data; GM_setValue('bw_cached_user', currentUser);
                const adminDiv = document.getElementById('admin-import-section'); if (adminDiv) adminDiv.style.display = (data.player_id === ADMIN_ID) ? 'flex' : 'none';
                document.getElementById('user-total-stats').textContent = formatBigNumber(total);
                const userLink = document.getElementById('user-name-link'); userLink.href = `https://www.torn.com/profiles.php?XID=${data.player_id}`; userLink.textContent = `${data.name} [${data.player_id}]`;
            } catch (e) { if (!cachedUser) { document.getElementById('user-total-stats').textContent = 'Stats Error (Check Key)'; } }
        }
    }
    initScript();
})();