FlatMMO Data Pages Beautifier

Beautifies FlatMMO mining and woodcutting data pages with complete tool and resource level requirements

// ==UserScript==
// @name         FlatMMO Data Pages Beautifier
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Beautifies FlatMMO mining and woodcutting data pages with complete tool and resource level requirements
// @author       Pizza1337
// @match        https://flatmmo.com/data/mining.html
// @match        https://flatmmo.com/data/woodcutting.html
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Get current page type
    const pageType = window.location.pathname.includes('mining') ? 'mining' : 'woodcutting';
    const toolType = pageType === 'mining' ? 'pickaxe' : 'axe';
    const otherPage = pageType === 'mining' ? 'woodcutting' : 'mining';
    const otherPageUrl = pageType === 'mining' ?
        'https://flatmmo.com/data/woodcutting.html' :
        'https://flatmmo.com/data/mining.html';

    // Define available tools
    const tools = ['bronze', 'iron', 'silver', 'gold', 'promethium', 'titanium', 'ancient'];

    // Define level brackets
    const levelBrackets = [
        {min: 1, max: 9, label: '1-9'},
        {min: 10, max: 19, label: '10-19'},
        {min: 20, max: 29, label: '20-29'},
        {min: 30, max: 39, label: '30-39'},
        {min: 40, max: 49, label: '40-49'},
        {min: 50, max: 59, label: '50-59'},
        {min: 60, max: 69, label: '60-69'},
        {min: 70, max: 79, label: '70-79'},
        {min: 80, max: 89, label: '80-89'},
        {min: 90, max: 99, label: '90-99'},
        {min: 100, max: 100, label: '100'}
    ];

    // Define tool level requirements
    const toolLevelRequirements = {
        mining: {
            'bronze_pickaxe': 1,
            'iron_pickaxe': 10,
            'silver_pickaxe': 20,
            'gold_pickaxe': 30,
            'promethium_pickaxe': 50,
            'titanium_pickaxe': 65,
            'ancient_pickaxe': 101
        },
        woodcutting: {
            'bronze_axe': 1,
            'iron_axe': 10,
            'silver_axe': 20,
            'gold_axe': 30,
            'promethium_axe': 50,
            'titanium_axe': 65,
            'ancient_axe': 101
        }
    };

    const toolReqs = toolLevelRequirements[pageType];

    // Define level requirements for resources
    const resourceLevelRequirements = {
        mining: {
            'coal': 1,
            'copper': 1,
            'iron': 5,
            'silver': 15,
            'gold': 30,
            'promethium': 50,
            'titanium': 65,
            'giant_coal': 1,
            'giant_copper': 1,
            'giant_iron': 5
        },
        woodcutting: {
            'tree': 1,
            'oak_tree': 10,
            'willow_tree': 20,
            'maple_tree': 30,
            'mangrove_tree': 50,
            'haunted_tree': 65
        }
    };

    const levelReqs = resourceLevelRequirements[pageType];

    // Parse the original table data BEFORE clearing the page
    function parseTableData() {
        const data = [];
        const tables = document.getElementsByTagName('table');
        if (tables.length > 0) {
            const table = tables[0];
            const rows = table.getElementsByTagName('tr');
            for (let i = 1; i < rows.length; i++) {
                const cells = rows[i].getElementsByTagName('td');
                if (cells.length >= 7) {
                    const resourceName = cells[0].textContent.trim();
                    const toolName = cells[2].textContent.trim();
                    let xpValue = parseInt(cells[1].textContent.trim()) || 0;
                    if (resourceName === 'giant_coal') xpValue = 10;
                    if (resourceName === 'giant_copper') xpValue = 15;
                    if (resourceName === 'giant_iron') xpValue = 40;
                    const originalTicks = parseInt(cells[4].textContent.trim()) || 0;
                    const actualTicks = originalTicks + 1;
                    const ticksPerHour = 3600 / (actualTicks * 0.5);
                    const actualXpPerHour = xpValue * ticksPerHour;
                    data.push({
                        resource: resourceName,
                        xp: xpValue,
                        tool: toolName,
                        toolLevelRequired: toolReqs[toolName] || 1,
                        level: parseInt(cells[3].textContent.trim()) || 0,
                        ticks: actualTicks,
                        xpPerHour: actualXpPerHour,
                        levelRequired: levelReqs[resourceName] || 1
                    });
                }
            }
        }
        return data;
    }

    // Store the data BEFORE modifying the page
    const tableData = parseTableData();

    if (tableData.length === 0) {
        alert('Error: Could not parse data from the page. Please refresh and try again.');
        return;
    }

    // Store original order of resources
    const resourceOrder = {};
    const uniqueResources = [...new Set(tableData.map(item => item.resource))];
    uniqueResources.forEach((resource, index) => {
        resourceOrder[resource] = index;
    });

    // Fetch user level from hiscores API
    async function fetchUserLevel(username) {
        return new Promise((resolve) => {
            const apiUrl = `https://flatmmo.com/api/hiscores/${pageType}.php`;
            GM_xmlhttpRequest({
                method: 'GET',
                url: apiUrl,
                headers: { 'Accept': 'application/json' },
                onload: function(response) {
                    try {
                        const data = JSON.parse(response.responseText);
                        const searchUsername = username.toLowerCase().trim();
                        for (let i = 0; i < data.length; i++) {
                            const entry = data[i];
                            const entryUsername = entry.username ? entry.username.toLowerCase().trim() : '';
                            if (entryUsername === searchUsername) {
                                const levelField = `${pageType}_level`;
                                const level = parseInt(entry[levelField]);
                                if (!isNaN(level) && level > 0) {
                                    resolve(level);
                                    return;
                                }
                            }
                        }
                        resolve(null);
                    } catch (error) {
                        console.error('Error parsing API response:', error);
                        resolve(null);
                    }
                },
                onerror: function(error) {
                    console.error('Failed to fetch from API:', error);
                    resolve(null);
                }
            });
        });
    }

    // Inject modern styles
    GM_addStyle(`
        @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Poppins', system-ui, -apple-system, sans-serif; background: #0a0e27; color: #e8e6e3; padding: 0; min-height: 100vh; overflow-x: hidden; }
        body::before { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at 20% 50%, rgba(120, 80, 255, 0.15) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(0, 255, 136, 0.1) 0%, transparent 50%), radial-gradient(circle at 40% 20%, rgba(0, 212, 255, 0.1) 0%, transparent 50%); pointer-events: none; z-index: 1; }
        .container { max-width: 1600px; margin: 0 auto; padding: 20px; position: relative; z-index: 2; }
        .header { text-align: center; padding: 60px 20px 40px; position: relative; }
        .header h1 { font-size: 4em; font-weight: 700; margin: 0; background: linear-gradient(135deg, #667eea 0%, #00ff88 50%, #00d4ff 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-transform: uppercase; letter-spacing: 3px; animation: glow 3s ease-in-out infinite; }
        @keyframes glow { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.2); } }
        .header p { margin-top: 10px; color: #8892b0; font-size: 1.2em; }
        .page-switcher { position: absolute; top: 20px; right: 20px; z-index: 10; }
        .page-switcher a { display: inline-flex; align-items: center; gap: 8px; padding: 12px 24px; background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(0, 255, 136, 0.2)); border: 1px solid rgba(0, 255, 136, 0.3); border-radius: 12px; color: #00ff88; text-decoration: none; font-weight: 500; transition: all 0.3s; }
        .page-switcher a:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(0, 255, 136, 0.3); background: linear-gradient(135deg, rgba(102, 126, 234, 0.3), rgba(0, 255, 136, 0.3)); }
        .user-section { background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(20px); border-radius: 25px; padding: 25px; margin-bottom: 30px; border: 1px solid rgba(255, 255, 255, 0.08); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); }
        .user-input-container { display: flex; gap: 15px; align-items: center; justify-content: center; flex-wrap: wrap; }
        .user-input-container label { color: #00ff88; font-weight: 500; }
        .user-input-container input { padding: 10px 15px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 12px; color: white; font-family: inherit; width: 200px; }
        .user-input-container button { padding: 10px 20px; background: linear-gradient(135deg, #667eea, #00ff88); border: none; border-radius: 12px; color: white; font-weight: 600; cursor: pointer; transition: all 0.3s; }
        .user-input-container button:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(0, 255, 136, 0.3); }
        .user-level-display { margin-top: 15px; text-align: center; padding: 15px; background: rgba(0, 255, 136, 0.1); border-radius: 12px; border: 1px solid rgba(0, 255, 136, 0.2); }
        .user-level-display .level-text { font-size: 1.2em; color: #00ff88; font-weight: 600; }
        .tool-selector { background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(20px); border-radius: 25px; padding: 30px; margin-bottom: 40px; border: 1px solid rgba(255, 255, 255, 0.08); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); }
        .tool-selector h2 { margin: 0 0 25px 0; background: linear-gradient(90deg, #00ff88, #00d4ff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 1.5em; font-weight: 600; text-align: center; }
        .tool-grid { display: flex; justify-content: center; flex-wrap: wrap; gap: 15px; margin-bottom: 25px; }
        .tool-option { display: flex; flex-direction: column; align-items: center; padding: 20px; background: rgba(255, 255, 255, 0.05); border: 2px solid transparent; border-radius: 20px; cursor: pointer; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); position: relative; overflow: hidden; min-width: 100px; }
        .tool-option::before { content: ''; position: absolute; top: 50%; left: 50%; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%); transform: translate(-50%, -50%) scale(0); transition: transform 0.5s; }
        .tool-option:hover::before { transform: translate(-50%, -50%) scale(2); }
        .tool-option:hover { transform: translateY(-5px) scale(1.05); box-shadow: 0 15px 40px rgba(0, 255, 136, 0.3); }
        .tool-option.active { background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(0, 255, 136, 0.2)); border-color: #00ff88; box-shadow: 0 0 30px rgba(0, 255, 136, 0.4); transform: scale(1.05); }
        .tool-option img { width: 56px; height: 56px; margin-bottom: 10px; filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.4)); position: relative; z-index: 1; }
        .tool-option span { font-size: 0.95em; font-weight: 500; text-transform: capitalize; position: relative; z-index: 1; }
        .filters { display: flex; gap: 20px; align-items: center; justify-content: center; flex-wrap: wrap; }
        .filter-group { display: flex; align-items: center; gap: 10px; background: rgba(255, 255, 255, 0.05); padding: 10px 20px; border-radius: 15px; }
        .filter-group label { color: #00ff88; font-weight: 500; font-size: 0.9em; }
        .filter-group select { background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); color: white; padding: 8px 12px; border-radius: 10px; font-family: inherit; cursor: pointer; transition: all 0.3s; }
        .filter-group select:hover { background: rgba(255, 255, 255, 0.15); border-color: rgba(0, 255, 136, 0.5); }
        .filter-group select:focus { outline: none; border-color: #00ff88; box-shadow: 0 0 10px rgba(0, 255, 136, 0.3); }
        .filter-group select option { background: #1a1f3a; color: white; }
        .level-brackets { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
        .bracket-btn { padding: 8px 16px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 10px; color: #8892b0; cursor: pointer; transition: all 0.3s; font-weight: 500; font-size: 0.9em; }
        .bracket-btn:hover { background: rgba(255, 255, 255, 0.1); color: white; transform: translateY(-2px); }
        .bracket-btn.active { background: linear-gradient(135deg, #667eea, #00ff88); border-color: transparent; color: white; }
        .bracket-btn.auto-selected { background: linear-gradient(135deg, #00ff88, #00d4ff); border-color: transparent; color: white; box-shadow: 0 0 20px rgba(0, 255, 136, 0.4); }
        .view-toggle { display: flex; gap: 10px; justify-content: center; margin: 30px 0; }
        .view-btn { padding: 12px 24px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 12px; color: white; cursor: pointer; transition: all 0.3s; font-weight: 500; }
        .view-btn.active { background: linear-gradient(135deg, #667eea, #00ff88); border-color: transparent; }
        .view-btn:hover:not(.active) { background: rgba(255, 255, 255, 0.1); }
        .stats-header { display: flex; justify-content: center; margin: 40px 0; }
        .stat-card { background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(0, 255, 136, 0.2)); backdrop-filter: blur(10px); border-radius: 25px; padding: 30px 40px; text-align: center; border: 2px solid rgba(0, 255, 136, 0.3); transition: all 0.3s; position: relative; overflow: hidden; min-width: 400px; box-shadow: 0 20px 60px rgba(0, 255, 136, 0.2); }
        .stat-card::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent); animation: shimmer 3s ease-in-out infinite; }
        @keyframes shimmer { 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); } 50% { transform: translateX(0%) translateY(0%) rotate(45deg); } 100% { transform: translateX(100%) translateY(100%) rotate(45deg); } }
        .stat-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 25px 70px rgba(102, 126, 234, 0.3); }
        .stat-value { font-size: 3em; font-weight: 700; background: linear-gradient(135deg, #ffd700, #00ff88, #00d4ff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 10px; text-shadow: 0 0 30px rgba(0, 255, 136, 0.5); }
        .stat-label { color: #00ff88; font-size: 1.2em; font-weight: 600; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 15px; }
        .stat-sublabel { color: #e8e6e3; font-size: 1.1em; margin-top: 5px; font-weight: 500; }
        .stat-resource { color: #00d4ff; font-size: 1.3em; font-weight: 600; text-transform: capitalize; }
        .stat-level { color: #ffd700; font-weight: 700; }
        .resources-container { margin-top: 40px; }
        .resource-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 25px; animation: fadeIn 0.5s ease-in; }
        @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
        .resource-card { background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(10px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.08); overflow: hidden; transition: all 0.3s; cursor: pointer; }
        .resource-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 20px 50px rgba(0, 255, 136, 0.2); border-color: rgba(0, 255, 136, 0.3); }
        .resource-header { padding: 20px; background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(0, 255, 136, 0.1)); border-bottom: 1px solid rgba(255, 255, 255, 0.08); display: flex; justify-content: space-between; align-items: center; }
        .resource-name { font-size: 1.3em; font-weight: 600; color: #00d4ff; text-transform: capitalize; display: flex; align-items: center; gap: 12px; }
        .resource-icon { width: 40px; height: 40px; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3)); object-fit: contain; }
        .resource-levels { padding: 20px; max-height: 300px; overflow-y: auto; }
        .resource-levels::-webkit-scrollbar { width: 6px; }
        .resource-levels::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); border-radius: 3px; }
        .resource-levels::-webkit-scrollbar-thumb { background: linear-gradient(135deg, #667eea, #00ff88); border-radius: 3px; }
        .level-entry { display: grid; grid-template-columns: auto 1fr auto; gap: 15px; padding: 12px; margin-bottom: 10px; background: rgba(255, 255, 255, 0.02); border-radius: 12px; align-items: center; transition: all 0.3s; }
        .level-entry:hover { background: rgba(255, 255, 255, 0.05); transform: translateX(5px); }
        .level-entry:last-child { margin-bottom: 0; }
        .level-badge { background: linear-gradient(135deg, #ff6b6b, #ff8e53); color: white; padding: 6px 12px; border-radius: 20px; font-weight: 600; font-size: 0.85em; }
        .level-stats { display: flex; gap: 20px; align-items: center; }
        .stat-item { display: flex; flex-direction: column; align-items: center; }
        .stat-item-value { font-weight: 600; color: #00ff88; font-size: 0.95em; }
        .stat-item-label { font-size: 0.75em; color: #8892b0; text-transform: uppercase; letter-spacing: 1px; }
        .xp-hour-badge { background: linear-gradient(135deg, #667eea, #764ba2); padding: 8px 16px; border-radius: 12px; font-weight: 600; font-size: 0.9em; white-space: nowrap; }
        .resource-list { background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(10px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.08); overflow: hidden; animation: fadeIn 0.5s ease-in; }
        .list-header { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1.5fr; padding: 20px; background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(0, 255, 136, 0.1)); border-bottom: 2px solid rgba(0, 255, 136, 0.3); font-weight: 600; color: #00ff88; text-transform: uppercase; font-size: 0.9em; letter-spacing: 1px; }
        .list-item { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1.5fr; padding: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); align-items: center; transition: all 0.3s; cursor: pointer; }
        .list-item:hover { background: rgba(255, 255, 255, 0.05); transform: translateX(10px); }
        .list-item:last-child { border-bottom: none; }
        .list-resource { display: flex; align-items: center; gap: 12px; font-weight: 600; color: #00d4ff; text-transform: capitalize; }
        .list-level { color: #ff6b6b; font-weight: 600; }
        .list-ticks { color: #00ff88; }
        .list-xp { color: #ffd700; font-weight: 500; }
        .sort-indicator { display: inline-block; margin-left: 5px; transition: transform 0.3s; }
        .sort-asc::after { content: '▲'; font-size: 0.8em; }
        .sort-desc::after { content: '▼'; font-size: 0.8em; }
        .hidden { display: none !important; }
        .empty-state { text-align: center; padding: 60px 20px; color: #8892b0; }
        .empty-state h3 { font-size: 1.5em; margin-bottom: 10px; color: #64748b; }
    `);

    // Create new UI
    document.body.innerHTML = '';
    const container = document.createElement('div');
    container.className = 'container';
    const pageSwitcher = document.createElement('div');
    pageSwitcher.className = 'page-switcher';
    pageSwitcher.innerHTML = `<a href="${otherPageUrl}">${otherPage === 'mining' ? '⛏️' : '🪓'} Switch to ${otherPage.charAt(0).toUpperCase() + otherPage.slice(1)}</a>`;
    container.appendChild(pageSwitcher);
    const header = document.createElement('div');
    header.className = 'header';
    header.innerHTML = `<h1>${pageType.charAt(0).toUpperCase() + pageType.slice(1)}</h1><p>Optimize your XP gains with the perfect tool and level combination</p>`;
    container.appendChild(header);
    const userSection = document.createElement('div');
    userSection.className = 'user-section';
    userSection.innerHTML = `<div class="user-input-container"><label>Username:</label><input type="text" id="usernameInput" placeholder="Enter your username"><button id="fetchLevelBtn">Fetch Level</button><button id="clearUserBtn" style="background: linear-gradient(135deg, #ff6b6b, #ff8e53);">Clear</button></div><div id="userLevelDisplay" class="user-level-display hidden"><div class="level-text">Loading...</div></div>`;
    container.appendChild(userSection);
    const toolSelector = document.createElement('div');
    toolSelector.className = 'tool-selector';
    toolSelector.innerHTML = `<h2>⚒️ Select Your Tool</h2><div class="tool-grid" id="toolGrid"></div><div class="filters"><div class="filter-group"><label>Level Range:</label><div class="level-brackets" id="levelBrackets"></div></div><div class="filter-group"><label>Sort by:</label><select id="sortBy"><option value="resource">Resource (Original Order)</option><option value="xpPerHour">XP per Hour</option></select></div></div>`;
    container.appendChild(toolSelector);
    const toolGrid = toolSelector.querySelector('#toolGrid');
    const levelBracketsContainer = toolSelector.querySelector('#levelBrackets');

    tools.forEach(tool => {
        const toolFullName = `${tool}_${toolType}`;
        const toolOption = document.createElement('div');
        toolOption.className = 'tool-option';
        toolOption.dataset.tool = toolFullName;
        const toolLevelReq = toolReqs[toolFullName] || 1;
        toolOption.innerHTML = `<img src="https://flatmmo.com/images/items/${toolFullName}.png" alt="${tool} ${toolType}" onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2256%22 height=%2256%22 viewBox=%220 0 56 56%22><rect width=%2256%22 height=%2256%22 fill=%22%23444%22 rx=%228%22/><text x=%2228%22 y=%2235%22 text-anchor=%22middle%22 fill=%22%23aaa%22 font-size=%2224%22>⚒️</text></svg>'"><span>${tool}</span><span class="tool-level-req" data-req-level="${toolLevelReq}" style="font-size: 0.75em; color: #ff6b6b;">Lvl ${toolLevelReq}</span>`;
        toolOption.addEventListener('click', () => filterByTool(toolFullName));
        toolGrid.appendChild(toolOption);
    });

    const allLevelsBtn = document.createElement('button');
    allLevelsBtn.className = 'bracket-btn active';
    allLevelsBtn.dataset.min = '1';
    allLevelsBtn.dataset.max = '100';
    allLevelsBtn.textContent = 'All Levels';
    allLevelsBtn.addEventListener('click', () => selectLevelBracket({min: 1, max: 100, label: 'All Levels'}));
    levelBracketsContainer.appendChild(allLevelsBtn);

    levelBrackets.forEach(bracket => {
        const bracketBtn = document.createElement('button');
        bracketBtn.className = 'bracket-btn';
        bracketBtn.dataset.min = bracket.min;
        bracketBtn.dataset.max = bracket.max;
        bracketBtn.textContent = bracket.label;
        bracketBtn.addEventListener('click', () => selectLevelBracket(bracket));
        levelBracketsContainer.appendChild(bracketBtn);
    });

    const viewToggle = document.createElement('div');
    viewToggle.className = 'view-toggle';
    viewToggle.innerHTML = `<button class="view-btn active" data-view="cards">📊 Card View</button><button class="view-btn" data-view="list">📋 List View</button>`;
    container.appendChild(viewToggle);
    const statsHeader = document.createElement('div');
    statsHeader.className = 'stats-header';
    statsHeader.id = 'statsHeader';
    container.appendChild(statsHeader);
    const resourcesContainer = document.createElement('div');
    resourcesContainer.className = 'resources-container';
    resourcesContainer.id = 'resourcesContainer';
    container.appendChild(resourcesContainer);
    document.body.appendChild(container);

    // State management
    let currentTool = GM_getValue('flatmmo_last_tool_' + pageType, 'all');
    let minLevelFilter = 1;
    let maxLevelFilter = 100;
    let currentView = 'cards';
    let sortBy = 'resource';
    let sortOrder = 'asc';
    let currentUsername = GM_getValue('flatmmo_username', '');
    let currentUserLevel = null;

    function selectLevelBracket(bracket) {
        minLevelFilter = bracket.min;
        maxLevelFilter = bracket.max;
        document.querySelectorAll('.bracket-btn').forEach(btn => {
            btn.classList.remove('active', 'auto-selected');
            if (btn.dataset.min == bracket.min && btn.dataset.max == bracket.max) {
                btn.classList.add('active');
            }
        });
        applyFilters();
    }

    function filterByTool(tool) {
        document.querySelectorAll('.tool-option').forEach(opt => {
            opt.classList.toggle('active', opt.dataset.tool === tool);
        });
        if (currentTool === tool) {
            currentTool = 'all';
            document.querySelectorAll('.tool-option').forEach(opt => opt.classList.remove('active'));
        } else {
            currentTool = tool;
        }
        GM_setValue('flatmmo_last_tool_' + pageType, currentTool);
        applyFilters();
    }

    function findBestBracketForLevel(level) {
        for (let bracket of levelBrackets) {
            if (level >= bracket.min && level <= bracket.max) {
                return bracket;
            }
        }
        return {min: 1, max: 100, label: 'All Levels'};
    }

    function updateToolLevelColors() {
        document.querySelectorAll('.tool-option').forEach(option => {
            const levelSpan = option.querySelector('.tool-level-req');
            if (levelSpan) {
                const requiredLevel = parseInt(levelSpan.dataset.reqLevel, 10);
                if (currentUserLevel && currentUserLevel >= requiredLevel) {
                    levelSpan.style.color = '#00ff88';
                } else {
                    levelSpan.style.color = '#ff6b6b';
                }
            }
        });
    }

    async function fetchAndSetUserLevel(username) {
        const levelDisplay = document.getElementById('userLevelDisplay');
        const levelText = levelDisplay.querySelector('.level-text');
        levelDisplay.classList.remove('hidden');
        levelText.textContent = 'Fetching level...';
        const level = await fetchUserLevel(username);
        if (level !== null && level > 0) {
            currentUserLevel = level;
            levelText.innerHTML = `<strong style="color: #00d4ff;">${username}</strong><span style="color: #8892b0;">•</span> ${pageType.charAt(0).toUpperCase() + pageType.slice(1)} Lvl: <strong style="color: #ffd700;">${level}</strong>`;
            const bestBracket = findBestBracketForLevel(level);
            minLevelFilter = bestBracket.min;
            maxLevelFilter = bestBracket.max;
            document.querySelectorAll('.bracket-btn').forEach(btn => {
                btn.classList.remove('active', 'auto-selected');
                if (btn.dataset.min == bestBracket.min && btn.dataset.max == bestBracket.max) {
                    btn.classList.add('auto-selected');
                }
            });
            updateToolLevelColors();
            applyFilters();
        } else {
            levelText.innerHTML = `<span style="color: #ff6b6b;">⚠️ Username not found in hiscores</span><br><span style="color: #8892b0; font-size: 0.9em;">Make sure the username exists in the ${pageType} hiscores</span>`;
            currentUserLevel = null;
            updateToolLevelColors();
            applyFilters(); // Re-apply filters to update colors in summary card
        }
    }

    function updateStats(data) {
        const statsHeader = document.getElementById('statsHeader');
        if (data.length === 0) {
            statsHeader.innerHTML = `<div class="stat-card"><div class="stat-label">⚠️ No Data Available</div><div class="stat-sublabel">Try adjusting your filters or check level requirements</div></div>`;
            return;
        }
        const bestXp = Math.max(...data.map(d => d.xpPerHour));
        const bestItem = data.find(d => d.xpPerHour === bestXp);

        // Determine colors based on user level
        const resourceReqColor = (currentUserLevel && currentUserLevel >= bestItem.levelRequired) ? '#00ff88' : '#ff6b6b';
        const toolReqColor = (currentUserLevel && currentUserLevel >= bestItem.toolLevelRequired) ? '#00ff88' : '#ff6b6b';

        statsHeader.innerHTML = `
            <div class="stat-card">
                <div class="stat-label">🏆 Best XP Per Hour</div>
                <div class="stat-value">${Math.round(bestXp).toLocaleString()}</div>
                <div class="stat-sublabel">
                    <span class="stat-resource">${bestItem.resource.replace(/_/g, ' ')}</span> at <span class="stat-level">Lvl ${bestItem.level}</span>
                </div>
                <div class="stat-sublabel" style="margin-top: 5px;">
                    <span style="color: ${resourceReqColor};">Resource requires Lvl ${bestItem.levelRequired}</span>
                    <span style="color: #8892b0;"> • </span>
                    <span style="color: ${toolReqColor};">Tool requires Lvl ${bestItem.toolLevelRequired}</span>
                </div>
                <div class="stat-sublabel" style="margin-top: 10px; opacity: 0.8;">
                    ${bestItem.tool.replace(/_/g, ' ')} • ${bestItem.ticks} ticks • ${bestItem.xp} XP per resource
                </div>
            </div>`;
    }

    function getResourceImage(resource) {
        if (pageType === 'woodcutting') {
            const treeImages = { 'tree': 'https://flatmmo.wiki/images/7/76/Normal_tree.png', 'oak_tree': 'https://flatmmo.wiki/images/c/cf/Oak_tree.png', 'willow_tree': 'https://flatmmo.wiki/images/1/19/Willow_tree.png', 'maple_tree': 'https://flatmmo.wiki/images/4/4b/Maple_tree.png', 'mangrove_tree': 'https://flatmmo.wiki/images/6/67/Mangrove_tree.png', 'haunted_tree': 'https://flatmmo.wiki/images/a/a7/Haunted_tree.png' };
            return treeImages[resource] || `https://flatmmo.com/images/items/${resource}.png`;
        } else if (pageType === 'mining') {
            const rockImages = { 'giant_coal': 'https://flatmmo.wiki/images/f/f8/Coal_rock.png', 'giant_copper': 'https://flatmmo.wiki/images/8/89/Copper_rock.png', 'giant_iron': 'https://flatmmo.wiki/images/d/db/Iron_rock.png' };
            return rockImages[resource] || `https://flatmmo.com/images/items/${resource}.png`;
        }
        return `https://flatmmo.com/images/items/${resource}.png`;
    }

    function renderCardView(data) {
        const container = document.getElementById('resourcesContainer');
        if (data.length === 0) {
            container.innerHTML = `<div class="empty-state"><h3>No resources found</h3><p>Try adjusting your filters or selecting a different tool</p><p style="color: #ff6b6b; margin-top: 10px;">Note: Resources and tools you can't use at your level are hidden</p></div>`;
            return;
        }
        const groupedData = {};
        data.forEach(item => { if (!groupedData[item.resource]) { groupedData[item.resource] = []; } groupedData[item.resource].push(item); });
        Object.keys(groupedData).forEach(resource => groupedData[resource].sort((a, b) => a.level - b.level));
        const sortedResources = Object.keys(groupedData).sort((a, b) => { if (sortBy === 'xpPerHour') { const maxA = Math.max(...groupedData[a].map(item => item.xpPerHour)); const maxB = Math.max(...groupedData[b].map(item => item.xpPerHour)); return sortOrder === 'asc' ? maxA - maxB : maxB - maxA; } return resourceOrder[a] - resourceOrder[b]; });
        const cardsHtml = sortedResources.map(resource => {
            const levels = groupedData[resource];
            const levelReq = levels[0].levelRequired;
            const levelReqColor = (currentUserLevel && currentUserLevel >= levelReq) ? '#00ff88' : '#ff6b6b';
            return `<div class="resource-card"><div class="resource-header"><div class="resource-name"><img src="${getResourceImage(resource)}" class="resource-icon" onerror="this.style.display='none'">${resource.replace(/_/g, ' ')}</div><div style="color: ${levelReqColor}; font-size: 0.9em;">Requires Lvl ${levelReq}</div></div><div class="resource-levels">${levels.map(level => `<div class="level-entry"><div class="level-badge">Lvl ${level.level}</div><div class="level-stats"><div class="stat-item"><span class="stat-item-value">${level.ticks}</span><span class="stat-item-label">Ticks</span></div><div class="stat-item"><span class="stat-item-value">${level.xp}</span><span class="stat-item-label">XP</span></div></div><div class="xp-hour-badge">${Math.round(level.xpPerHour).toLocaleString()} xp/h</div></div>`).join('')}</div></div>`;
        }).join('');
        container.innerHTML = `<div class="resource-cards">${cardsHtml}</div>`;
    }

    function renderListView(data) {
        const container = document.getElementById('resourcesContainer');
        if (data.length === 0) {
            container.innerHTML = `<div class="empty-state"><h3>No resources found</h3><p>Try adjusting your filters or selecting a different tool</p><p style="color: #ff6b6b; margin-top: 10px;">Note: Resources and tools you can't use at your level are hidden</p></div>`;
            return;
        }
        const sortedData = [...data].sort((a, b) => { if (sortBy === 'xpPerHour') { return sortOrder === 'asc' ? a.xpPerHour - b.xpPerHour : b.xpPerHour - a.xpPerHour; } const orderDiff = resourceOrder[a.resource] - resourceOrder[b.resource]; if (orderDiff !== 0) return orderDiff; return a.level - b.level; });
        const listHtml = `<div class="resource-list"><div class="list-header"><div class="sortable" data-sort="resource">Resource <span class="sort-indicator ${sortBy === 'resource' ? `sort-${sortOrder}` : ''}"></span></div><div>Req. Lvl</div><div>Your Lvl</div><div>Ticks</div><div>XP</div><div class="sortable" data-sort="xpPerHour">XP/Hour <span class="sort-indicator ${sortBy === 'xpPerHour' ? `sort-${sortOrder}` : ''}"></span></div></div>${sortedData.map(item => `<div class="list-item"><div class="list-resource"><img src="${getResourceImage(item.resource)}" class="resource-icon" onerror="this.style.display='none'">${item.resource.replace(/_/g, ' ')}</div><div class="list-level" style="color: #ff6b6b;">${item.levelRequired}</div><div class="list-level">${item.level}</div><div class="list-ticks">${item.ticks}</div><div class="list-xp">${item.xp}</div><div class="xp-hour-badge">${Math.round(item.xpPerHour).toLocaleString()} xp/h</div></div>`).join('')}</div>`;
        container.innerHTML = listHtml;
        container.querySelectorAll('.sortable').forEach(header => {
            header.style.cursor = 'pointer';
            header.addEventListener('click', () => {
                const newSortBy = header.dataset.sort;
                if (sortBy === newSortBy) { sortOrder = sortOrder === 'asc' ? 'desc' : 'asc'; } else { sortBy = newSortBy; sortOrder = sortBy === 'xpPerHour' ? 'desc' : 'asc'; }
                document.getElementById('sortBy').value = sortBy;
                applyFilters();
            });
        });
    }

    function applyFilters() {
        let filteredData = tableData;
        if (currentTool !== 'all') {
            filteredData = filteredData.filter(row => row.tool === currentTool);
        }
        filteredData = filteredData.filter(row => {
            const isInBracket = row.level >= minLevelFilter && row.level <= maxLevelFilter;
            const isResourceAvailable = row.levelRequired <= maxLevelFilter;
            const isToolAvailable = row.toolLevelRequired <= maxLevelFilter;
            return isInBracket && isResourceAvailable && isToolAvailable;
        });
        updateStats(filteredData);
        if (currentView === 'cards') {
            renderCardView(filteredData);
        } else {
            renderListView(filteredData);
        }
    }

    // Event listeners
    document.getElementById('fetchLevelBtn').addEventListener('click', async () => {
        const username = document.getElementById('usernameInput').value.trim();
        if (username) {
            GM_setValue('flatmmo_username', username);
            currentUsername = username;
            await fetchAndSetUserLevel(username);
        } else {
            alert('Please enter a username');
        }
    });

    document.getElementById('clearUserBtn').addEventListener('click', () => {
        GM_setValue('flatmmo_username', '');
        currentUsername = '';
        currentUserLevel = null;
        updateToolLevelColors();
        document.getElementById('usernameInput').value = '';
        document.getElementById('userLevelDisplay').classList.add('hidden');
        selectLevelBracket({min: 1, max: 100, label: 'All Levels'});
    });

    document.getElementById('usernameInput').addEventListener('keypress', async (e) => {
        if (e.key === 'Enter') {
            const username = e.target.value.trim();
            if (username) {
                GM_setValue('flatmmo_username', username);
                currentUsername = username;
                await fetchAndSetUserLevel(username);
            }
        }
    });

    document.getElementById('sortBy').addEventListener('change', (e) => {
        sortBy = e.target.value;
        sortOrder = sortBy === 'xpPerHour' ? 'desc' : 'asc';
        applyFilters();
    });

    document.querySelectorAll('.view-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active'));
            btn.classList.add('active');
            currentView = btn.dataset.view;
            applyFilters();
        });
    });

    // Initialize UI and load saved data
    function initialize() {
        if (currentTool !== 'all') {
            const lastSelectedToolEl = document.querySelector(`.tool-option[data-tool="${currentTool}"]`);
            if (lastSelectedToolEl) {
                lastSelectedToolEl.classList.add('active');
            }
        }
        if (currentUsername) {
            document.getElementById('usernameInput').value = currentUsername;
            fetchAndSetUserLevel(currentUsername);
        } else {
            applyFilters();
        }
    }

    initialize();

})();