// toggle-button.js
var isOpen = false;

// Combo mode state (for action+tile voting like "riichi 7m")
var comboModeEnabled = false;

// Load combo mode state from localStorage
function loadComboModeState() {
    const saved = localStorage.getItem('comboModeEnabled');
    comboModeEnabled = saved === 'true';
    updateComboModeButton();
}

// Update combo mode button appearance (uses glow effect like filter buttons)
function updateComboModeButton() {
    const btn = document.getElementById('comboModeBtn');
    if (btn) {
        btn.classList.toggle('active-glow', comboModeEnabled);
    }
}

// Toggle combo mode
function toggleComboMode() {
    // Prevent changing while poll is open
    if (isOpen) {
        const btn = document.getElementById('comboModeBtn');
        if (btn && typeof showInputError === 'function') {
            showInputError(btn, 'Cannot change while poll is open');
        }
        return;
    }

    comboModeEnabled = !comboModeEnabled;
    localStorage.setItem('comboModeEnabled', comboModeEnabled);
    updateComboModeButton();
    logToConsole(`Combo mode ${comboModeEnabled ? 'enabled' : 'disabled'}`);
}

// Initialize combo mode UI in the toolbar
function initComboModeUI() {
    const widgetContainer2 = document.getElementById('widgetContainer2');
    if (!widgetContainer2) return;

    // Get or create the shared toolbar row
    let toolbarRow = document.getElementById('chartToolbar');
    if (!toolbarRow) {
        toolbarRow = document.createElement('div');
        toolbarRow.id = 'chartToolbar';
        toolbarRow.className = 'd-flex flex-wrap justify-content-center align-items-center gap-1 mb-2 p-2 border rounded bg-body-tertiary';
        widgetContainer2.appendChild(toolbarRow);
    }

    const comboModeDiv = document.createElement('div');
    comboModeDiv.className = 'combo-mode-controls d-flex align-items-center gap-1';
    comboModeDiv.innerHTML = `
        <button class="btn btn-sm btn-outline-secondary combo-toggle-btn" id="comboModeBtn" title="Combo voting (e.g., 'riichi 7m')">
            <i class="fas fa-link"></i>
        </button>
    `;

    toolbarRow.appendChild(comboModeDiv);

    // Set up click listener
    const btn = document.getElementById('comboModeBtn');
    if (btn) {
        btn.addEventListener('click', toggleComboMode);
        // Update button state to match loaded state
        updateComboModeButton();
    }
}

// Expose combo mode state globally via getter/setter
// Use try-catch to handle cases where property might already be defined
try {
    Object.defineProperty(window, 'comboModeEnabled', {
        get: () => comboModeEnabled,
        set: (v) => { comboModeEnabled = v; },
        configurable: true
    });
} catch (e) {
    // Property already exists, just use direct assignment as fallback
    console.warn('comboModeEnabled property already defined, using fallback');
}

// Memory management constants
const MAX_CONSOLE_ENTRIES = 500;
const MAX_CHAT_ENTRIES = 300;

// Trim a container to max N children (removes oldest)
function trimContainer(container, maxEntries) {
    while (container.children.length > maxEntries) {
        container.removeChild(container.firstChild);
    }
}

// Global console logging function
window.logToConsole = function(message) {
    const outputContainer = document.getElementById('outputContainer');
    if (outputContainer) {
        // Format timestamp as hh:mm:ss
        const now = new Date();
        const timestamp = now.toTimeString().slice(0, 8);

        const p = document.createElement('p');
        p.className = 'mb-1';
        p.innerHTML = `<span style="color: #666; font-size: 0.85em;">[${timestamp}]</span> ${message}`;
        outputContainer.appendChild(p);

        // Trim old entries to prevent memory leak
        trimContainer(outputContainer, MAX_CONSOLE_ENTRIES);

        outputContainer.scrollTop = outputContainer.scrollHeight;
    }
    console.log('[JongVoter]', message);
};

// Export trim function for chat containers
window.trimContainer = trimContainer;
window.MAX_CHAT_ENTRIES = MAX_CHAT_ENTRIES;

// Extract YouTube video ID from URL or return as-is if already an ID
function extractYouTubeVideoId(input) {
    if (!input) return null;

    input = input.trim();

    // If it's already just an ID (11 characters, alphanumeric with - and _)
    if (/^[a-zA-Z0-9_-]{11}$/.test(input)) {
        return input;
    }

    // Try to extract from various YouTube URL formats
    const patterns = [
        /(?:youtube\.com\/watch\?v=|youtube\.com\/live\/|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/,
        /[?&]v=([a-zA-Z0-9_-]{11})/
    ];

    for (const pattern of patterns) {
        const match = input.match(pattern);
        if (match) {
            return match[1];
        }
    }

    // Return null if no valid ID found
    return null;
}

// Validate YouTube video ID (must be exactly 11 chars, alphanumeric with - and _)
function isValidYouTubeId(id) {
    return id && /^[a-zA-Z0-9_-]{11}$/.test(id);
}

// Extract Twitch channel name from URL or return as-is if already a channel name
function extractTwitchChannelName(input) {
    if (!input) return null;

    input = input.trim();

    // Try to extract from various Twitch URL formats
    // Handles: twitch.tv/channel, www.twitch.tv/channel, https://twitch.tv/channel/live, etc.
    const urlPattern = /(?:https?:\/\/)?(?:www\.)?twitch\.tv\/([a-zA-Z0-9_]+)/i;
    const match = input.match(urlPattern);
    if (match) {
        return match[1].toLowerCase();
    }

    // If no URL pattern matched, treat as raw channel name
    // Remove any leading @ symbol (common mistake)
    if (input.startsWith('@')) {
        input = input.substring(1);
    }

    return input.toLowerCase();
}

// Validate Twitch channel name (4-25 chars, alphanumeric and underscores, starts with letter or underscore)
function isValidTwitchChannelName(name) {
    return name && /^[a-zA-Z_][a-zA-Z0-9_]{3,24}$/.test(name);
}

// Show error tooltip near an element
function showInputError(inputElement, message) {
    // Remove any existing error tooltip
    hideInputError(inputElement);

    const tooltip = document.createElement('div');
    tooltip.className = 'input-error-tooltip';
    tooltip.textContent = message;
    tooltip.style.cssText = `
        position: absolute;
        background: #dc3545;
        color: white;
        padding: 4px 8px;
        border-radius: 4px;
        font-size: 12px;
        white-space: nowrap;
        z-index: 1000;
        pointer-events: none;
    `;

    // Position near the input
    const rect = inputElement.getBoundingClientRect();
    tooltip.style.top = (rect.bottom + window.scrollY + 5) + 'px';
    tooltip.style.left = (rect.left + window.scrollX) + 'px';

    document.body.appendChild(tooltip);
    inputElement._errorTooltip = tooltip;

    // Auto-hide after 3 seconds
    setTimeout(() => hideInputError(inputElement), 3000);
}

function hideInputError(inputElement) {
    if (inputElement._errorTooltip) {
        inputElement._errorTooltip.remove();
        inputElement._errorTooltip = null;
    }
}

document.addEventListener('DOMContentLoaded', function () {
    const toggleButton = document.getElementById('toggleButton');
    const toggleButton2 = document.getElementById('toggleButton2');
    const outputContainer = document.getElementById('outputContainer');

    // Make sure we load the registry first
    if (typeof loadRegistry === 'function') {
        loadRegistry();
    }

    // Initialize the translate map with the registry
    if (typeof updateTranslateFromRegistry === 'function') {
        updateTranslateFromRegistry();
    }

    // Initialize the stats map with the registry
    if (typeof initializeStats === 'function') {
        initializeStats();
    }

    // Initialize combo mode
    loadComboModeState();

    // Create combo mode button in the toolbar (between + and filter buttons)
    setTimeout(() => {
        initComboModeUI();
    }, 120); // After temp-candidate (105ms), before vote-filters (150ms)

    // Initialize the chart
    if (typeof VoteChart !== 'undefined') {
        VoteChart.setData(stats);
        VoteChart.render();
    }

    // Centralized toggle function that both buttons can use
    function togglePoll() {
        if (isOpen) {
            // Close the poll
            isOpen = false;
            updateButtonStates();

            // Cancel any running simulation
            if (typeof window.debugToolbar !== 'undefined' && window.debugToolbar.cancelSimulation) {
                window.debugToolbar.cancelSimulation();
            }

            // Clear temp candidates when poll closes
            if (typeof clearTempCandidates === 'function') {
                clearTempCandidates();
            }

            // Restore the one-vote-per-user toggle tooltip for current state
            const oneVoteBtn = document.getElementById('oneVoteFilterBtn');
            if (oneVoteBtn && typeof updateOneVoteButtonAppearance === 'function') {
                const currentMode = typeof oneVotePerUserConfig !== 'undefined' ? oneVotePerUserConfig.mode : 'off';
                updateOneVoteButtonAppearance(oneVoteBtn, currentMode);
            }

            // Restore combo mode toggle title when poll closes
            const comboModeBtn = document.getElementById('comboModeBtn');
            if (comboModeBtn) {
                comboModeBtn.title = 'Combo voting (e.g., \'riichi 7m\')';
            }

            // Restore mahjong mode toggle title when poll closes
            const mahjongModeChk = document.getElementById('simMahjongMode');
            if (mahjongModeChk) {
                mahjongModeChk.parentElement.title = 'Simulate votes based on a random 14-tile mahjong hand';
            }

            // Clear mahjong hand
            if (typeof window.debugToolbar !== 'undefined' && window.debugToolbar.clearMahjongHand) {
                window.debugToolbar.clearMahjongHand();
            }
        } else {
            // Open the poll
            isOpen = true;
            updateButtonStates();

            // Mark the one-vote-per-user toggle as locked while poll is open
            // (actual locking is handled by click handler in vote-filters-ui.js which shows popup)
            const oneVoteBtn = document.getElementById('oneVoteFilterBtn');
            if (oneVoteBtn) {
                const mode = typeof oneVotePerUserConfig !== 'undefined' ? oneVotePerUserConfig.mode : 'off';
                const modeLabels = { off: 'OFF', lock: 'LOCK', change: 'CHANGE' };
                oneVoteBtn.setAttribute('data-tooltip', `One vote per user: ${modeLabels[mode] || mode} (locked while poll is open)`);
            }

            // Mark combo mode toggle as locked while poll is open
            const comboModeBtn = document.getElementById('comboModeBtn');
            if (comboModeBtn) {
                comboModeBtn.title = `Combo mode: ${comboModeEnabled ? 'ON' : 'OFF'} (cannot change while poll is open)`;
            }

            // Mark mahjong mode toggle as locked while poll is open
            const mahjongModeChk = document.getElementById('simMahjongMode');
            if (mahjongModeChk) {
                const mahjongEnabled = mahjongModeChk.checked;
                mahjongModeChk.parentElement.title = `Mahjong mode: ${mahjongEnabled ? 'ON' : 'OFF'} (cannot change while poll is open)`;
            }

            // Generate mahjong hand if mahjong mode is enabled
            if (typeof window.debugToolbar !== 'undefined' && window.debugToolbar.initMahjongHand) {
                window.debugToolbar.initMahjongHand();
            }

            // Clean up chart state when opening a new poll
            if (typeof VoteChart !== 'undefined') {
                VoteChart.destroy();
                // Clear any category combinations from previous poll
                VoteChart.clearCombinations();
            }

            // Clear and initialize stats for the current registry
            if (typeof initializeStats === 'function') {
                initializeStats();
            } else {
                // Fallback for backward compatibility
                if (typeof stats !== 'undefined' && typeof translate !== 'undefined') {
                    translate.forEach(function (value, key) {
                        stats.set(value, 0);
                    });
                }
            }

            // Clear dynamic categories from combo voting
            if (typeof window.clearDynamicCategories === 'function') {
                window.clearDynamicCategories();
            }

            // Clear voted users for new poll
            if (typeof clearVotedUsers === 'function') {
                clearVotedUsers();
            }

            // Render a fresh chart
            if (typeof VoteChart !== 'undefined') {
                VoteChart.init('chartjs-chart');
                VoteChart.setData(stats);
                VoteChart.render();
            }
        }

        // Broadcast poll state to pop-out windows
        try {
            if (window._chartBroadcast) {
                window._chartBroadcast.postMessage({ type: 'pollStateUpdate', isOpen: isOpen });
            }
        } catch (e) { }
    }

    // Function to update the visual state of both buttons
    // Note: This will be overridden by auto-close countdown if that's active
    function updateButtonStates() {
        // Check if auto-close is handling button text (has countdown active)
        const hasActiveCountdown = (typeof window.autoClose !== 'undefined' &&
            window.autoClose.isEnabled &&
            window.autoClose.isEnabled() &&
            isOpen &&
            window.autoClose.getRemainingTime &&
            window.autoClose.getRemainingTime() > 0);

        if (!hasActiveCountdown) {
            // Normal button state - no countdown active
            const text = isOpen ? 'OPEN' : 'CLOSED';
            const className = isOpen ? 'button' : 'button off';

            // Update original button
            if (toggleButton) {
                toggleButton.textContent = text;
                toggleButton.className = className;
            }

            // Update redundant button
            if (toggleButton2) {
                toggleButton2.textContent = text;
                toggleButton2.className = className;
            }
        }
        // If countdown is active, let auto-close.js handle the button text
    }

    // Add click listeners to both buttons
    if (toggleButton) {
        toggleButton.addEventListener('click', togglePoll);
    }

    if (toggleButton2) {
        toggleButton2.addEventListener('click', togglePoll);
    }

    // Initialize button states
    updateButtonStates();

    // Make togglePoll available globally for auto-close integration
    window.togglePoll = togglePoll;

    //Youtube Stuff

    //trackbutton begins youtube tracking
    const trackbutton = document.getElementById('trackbutton');

    //YTContainer is where we put youtube chat messages
    const YTContainer = document.getElementById('chatContainerLeft');

    //i dont know why chatpoller has to be a variable, this is a hack solution to something
    var chatPoller;
    if (trackbutton) {
        //when you click the trackbutton, start tracking youtube. also the chatpoller continuously gets new messages.
        trackbutton.addEventListener('click', function () {
            const inputElement = document.getElementById("YTvideoId");
            var rawInput = inputElement.value;
            var YTvideoID = extractYouTubeVideoId(rawInput);

            // Validate the video ID
            if (!isValidYouTubeId(YTvideoID)) {
                showInputError(inputElement, 'invalid youtube id/URL');
                return;
            }

            // Update the input field with the extracted ID for clarity
            inputElement.value = YTvideoID;

            // Save to localStorage for next session
            localStorage.setItem('lastYouTubeVideoId', YTvideoID);

            startTrackingYT(outputContainer);
            chatPoller = example(YTContainer, YTvideoID);
            const stopYTBtn = document.getElementById('stopYT');
            if (stopYTBtn) { stopYTBtn.disabled = false; stopYTBtn.className = 'btn btn-danger mt-2'; }
        });
    }

    // Load saved YouTube video ID if available
    const savedVideoId = localStorage.getItem('lastYouTubeVideoId');
    if (savedVideoId) {
        document.getElementById('YTvideoId').value = savedVideoId;
    }

    // Load saved API key if available
    const savedApiKey = localStorage.getItem('youtubeApiKey');
    if (savedApiKey) {
        document.getElementById('YoutubeApiKey').value = savedApiKey;
    }

    // Allow Enter key to start YouTube tracking
    const ytVideoIdInput = document.getElementById('YTvideoId');
    if (ytVideoIdInput && trackbutton) {
        ytVideoIdInput.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                trackbutton.click();
            }
        });
    }

    // makes the youtube thing stop
    const stopYT = document.getElementById("stopYT");
    if (stopYT) {
        stopYT.addEventListener('click', function () {
            chatPoller.stop();
            logToPage(outputContainer, "stopped tracking YT");
            stopYT.disabled = true;
            stopYT.className = 'btn btn-secondary mt-2';
        })
    }

    // Load saved Twitch channel if available
    const savedTwitchChannel = localStorage.getItem('lastTwitchChannel');
    if (savedTwitchChannel) {
        document.getElementById('TwitchChannel').value = savedTwitchChannel;
    }

    // starts anonymously listening to twitch
    const trackbutton2 = document.getElementById('trackbutton2');

    // Allow Enter key to start Twitch tracking
    const twitchChannelInput = document.getElementById('TwitchChannel');
    if (twitchChannelInput && trackbutton2) {
        twitchChannelInput.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                trackbutton2.click();
            }
        });
    }
    var trackingTwitch = false;
    if (trackbutton2) {
        trackbutton2.addEventListener('click', function () {
            const inputElement = document.getElementById("TwitchChannel");
            var rawInput = inputElement.value;
            var TwitchChannel = extractTwitchChannelName(rawInput);

            // Validate the channel name
            if (!isValidTwitchChannelName(TwitchChannel)) {
                showInputError(inputElement, 'Invalid Twitch channel name/URL');
                return;
            }

            // Update the input field with the extracted channel name for clarity
            inputElement.value = TwitchChannel;

            trackingTwitch = true;

            // Save to localStorage for next session
            localStorage.setItem('lastTwitchChannel', TwitchChannel);

            initTwitchChat('chatContainerRight', TwitchChannel);

            logToPage(outputContainer, `Connected to Twitch chat for channel: ${TwitchChannel}`);
            const stopTWBtn = document.getElementById('stopTwitch');
            if (stopTWBtn) { stopTWBtn.disabled = false; stopTWBtn.className = 'btn btn-danger mt-2'; }
        });
    }

    // stops anonymously listening to twitch
    const stopTwitch = document.getElementById('stopTwitch');
    if (stopTwitch) {
        stopTwitch.addEventListener('click', function () {
            disconnectTwitchChat();
            logToPage(outputContainer, "Closed Twitch connection");
            stopTwitch.disabled = true;
            stopTwitch.className = 'btn btn-secondary mt-2';
        })
    }
});