// ==UserScript==
// @name         cams
// @namespace    http://tampermonkey.net/
// @version      1.3.1
// @description  Set maxDockedCamsForUser, keep-alive, and multi-poke
// @author       You
// @match        https://chat.fabswingers.com/*
// @updateURL    https://git.upto.im/geekery/scripts/raw/branch/main/meta.js
// @downloadURL  https://git.upto.im/geekery/scripts/raw/branch/main/cams.user.js
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    const BUTTON_ID = 'maxDockedCamsButton_SINGLETON';
    const KEEPALIVE_BUTTON_ID = 'keepAliveButton_SINGLETON';
    const MULTIPOKE_BUTTON_ID = 'multiPokeButton_SINGLETON';
    const RESET_BUTTON_ID = 'resetPositionsButton_SINGLETON';
    const ROOM_BUTTON_PREFIX = 'roomJoinButton_';

    const CHAT_ROOMS = [
        { id: 'c4c53fde-7697-490b-9217-4522012d96ed', name: 'Directing Room' },
        { id: '68fbfee8-9f16-4add-b5ff-1937444b444d', name: 'Directing Room #2' },
        { id: '5ec55d32-d09b-4636-b624-4c2256710137', name: 'Directing Room #3' },
        { id: 'a57172a0-551c-4dc4-a392-f3393a1f0830', name: 'Directing Room #4' },
        { id: '8cb23926-283d-417d-8a6d-fa6221d0ca89', name: 'Directing Room #5' },
        { id: '33f1c6b5-7d04-40a4-89ae-7a8e4f06e3f4', name: 'Directing Room #6' }
    ];
    const LOCK_KEY = 'maxDockedCams_scriptLock';
    const KEEPALIVE_SETTINGS_KEY = 'keepAlive_settings';
    const MULTIPOKE_SETTINGS_KEY = 'multiPoke_settings';
    const BUTTON_POSITIONS_KEY = 'buttonPositions';

    // Default button positions (centered at top)
    const DEFAULT_POSITIONS = {
        [BUTTON_ID]: { left: 'calc(50% + 60px)', top: '10px' },
        [KEEPALIVE_BUTTON_ID]: { left: 'calc(50% - 70px)', top: '10px' },
        [MULTIPOKE_BUTTON_ID]: { left: 'calc(50% - 170px)', top: '10px' }
    };

    // Load saved button positions
    function loadButtonPositions() {
        try {
            const saved = localStorage.getItem(BUTTON_POSITIONS_KEY);
            if (saved) {
                return JSON.parse(saved);
            }
        } catch (e) {
            console.log('Error loading button positions', e);
        }
        return {};
    }

    function saveButtonPosition(buttonId, x, y) {
        const positions = loadButtonPositions();
        positions[buttonId] = { x, y };
        localStorage.setItem(BUTTON_POSITIONS_KEY, JSON.stringify(positions));
    }

    function resetButtonPositions() {
        localStorage.removeItem(BUTTON_POSITIONS_KEY);

        // Reset each button to default position
        const maxDockedBtn = document.getElementById(BUTTON_ID);
        const keepAliveBtn = document.getElementById(KEEPALIVE_BUTTON_ID);
        const multiPokeBtn = document.getElementById(MULTIPOKE_BUTTON_ID);

        if (maxDockedBtn) {
            maxDockedBtn.style.right = 'auto';
            maxDockedBtn.style.left = DEFAULT_POSITIONS[BUTTON_ID].left;
            maxDockedBtn.style.top = DEFAULT_POSITIONS[BUTTON_ID].top;
        }
        if (keepAliveBtn) {
            keepAliveBtn.style.right = 'auto';
            keepAliveBtn.style.left = DEFAULT_POSITIONS[KEEPALIVE_BUTTON_ID].left;
            keepAliveBtn.style.top = DEFAULT_POSITIONS[KEEPALIVE_BUTTON_ID].top;
        }
        if (multiPokeBtn) {
            multiPokeBtn.style.right = 'auto';
            multiPokeBtn.style.left = DEFAULT_POSITIONS[MULTIPOKE_BUTTON_ID].left;
            multiPokeBtn.style.top = DEFAULT_POSITIONS[MULTIPOKE_BUTTON_ID].top;
        }

        CHAT_ROOMS.forEach((room, index) => {
            const roomBtn = document.getElementById(ROOM_BUTTON_PREFIX + index);
            if (roomBtn) {
                roomBtn.style.right = 'auto';
                roomBtn.style.left = 'calc(50% + 230px)';
                roomBtn.style.top = (10 + index * 36) + 'px';
            }
        });

        console.log('Button positions reset to defaults');
    }

    function makeDraggable(button) {
        let isDragging = false;
        let wasDragged = false;
        let startX, startY, initialX, initialY;

        button.style.cursor = 'move';

        button.addEventListener('mousedown', function(e) {
            if (e.button !== 0) return; // Only left click
            isDragging = true;
            wasDragged = false;
            startX = e.clientX;
            startY = e.clientY;
            initialX = button.offsetLeft;
            initialY = button.offsetTop;
            e.preventDefault();
        });

        document.addEventListener('mousemove', function(e) {
            if (!isDragging) return;

            const deltaX = e.clientX - startX;
            const deltaY = e.clientY - startY;

            // Only count as drag if moved more than 5px
            if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
                wasDragged = true;
            }

            let newX = initialX + deltaX;
            let newY = initialY + deltaY;

            // Keep within viewport
            newX = Math.max(0, Math.min(newX, window.innerWidth - button.offsetWidth));
            newY = Math.max(0, Math.min(newY, window.innerHeight - button.offsetHeight));

            button.style.left = newX + 'px';
            button.style.top = newY + 'px';
            button.style.right = 'auto';
        });

        document.addEventListener('mouseup', function(e) {
            if (isDragging) {
                isDragging = false;
                if (wasDragged) {
                    saveButtonPosition(button.id, button.offsetLeft, button.offsetTop);
                }
            }
        });

        // Prevent click event if we were dragging
        button.addEventListener('click', function(e) {
            if (wasDragged) {
                e.preventDefault();
                e.stopPropagation();
                wasDragged = false;
            }
        }, true);

        // Apply saved position if exists
        const positions = loadButtonPositions();
        if (positions[button.id]) {
            button.style.left = positions[button.id].x + 'px';
            button.style.top = positions[button.id].y + 'px';
            button.style.right = 'auto';
        }
    }

    // Public room names to match against
    const PUBLIC_ROOMS = [
        'General Chat',
        'Directing Room',
        'Directing Room #2',
        'Directing Room #3',
        'Directing Room #4',
        'Directing Room #5',
        'Directing Room #6',
        'Site Supporters',
        'Verified Users',
        'Scotland Swingers',
        'Northern Swingers',
        'South East Swing',
        'South West Swing',
        'Midlands Swing',
        'East Anglia',
        'Ireland Swingers',
        'London Swingers',
        'Wales Swingers',
        'USA Swingers',
        'Canadian Swingers',
        'Bisexual Chat',
        'Bi Directing Room'
    ];

    const DEFAULT_INTERVAL = 10; // minutes
    const DEFAULT_POKE_COUNT = 10;
    const POKE_DELAY = 150; // ms between pokes

    let keepAliveInterval = null;
    let isKeepAliveRunning = false;
    let keepAliveSettings = loadKeepAliveSettings();

    let multiPokeEnabled = loadMultiPokeSettings();

    function loadMultiPokeSettings() {
        return localStorage.getItem(MULTIPOKE_SETTINGS_KEY) !== 'false';
    }

    function saveMultiPokeSettings() {
        localStorage.setItem(MULTIPOKE_SETTINGS_KEY, multiPokeEnabled.toString());
    }

    function loadKeepAliveSettings() {
        try {
            const saved = localStorage.getItem(KEEPALIVE_SETTINGS_KEY);
            if (saved) {
                return JSON.parse(saved);
            }
        } catch (e) {
            console.log('KeepAlive: Error loading settings', e);
        }
        return { intervalMinutes: DEFAULT_INTERVAL };
    }

    function saveKeepAliveSettings() {
        localStorage.setItem(KEEPALIVE_SETTINGS_KEY, JSON.stringify(keepAliveSettings));
    }

    // Try to acquire lock.
    // The lock value is a timestamp that a live instance refreshes on a heartbeat.
    // If a crash / power-cut kills the tab, beforeunload never fires and the key is
    // left behind; a new load treats a lock older than LOCK_STALE_MS as dead and
    // takes over, instead of exiting forever (which required clearing site data).
    const LOCK_STALE_MS = 90 * 1000;      // reclaim a lock not refreshed within 90s
    const LOCK_HEARTBEAT_MS = 30 * 1000;  // refresh our lock every 30s while alive
    let ourLockValue = Date.now().toString();

    const existingLock = localStorage.getItem(LOCK_KEY);
    if (existingLock) {
        const lockAge = Date.now() - parseInt(existingLock, 10);
        if (isNaN(lockAge) || lockAge < LOCK_STALE_MS) {
            console.log('MaxDockedCams: Another instance already running, exiting');
            return;
        }
        console.log(`MaxDockedCams: Reclaiming stale lock (${Math.round(lockAge / 1000)}s old)`);
    }

    localStorage.setItem(LOCK_KEY, ourLockValue);

    // Keep our lock fresh so a live instance is never mistaken for a crashed one.
    setInterval(function() {
        if (localStorage.getItem(LOCK_KEY) === ourLockValue) {
            ourLockValue = Date.now().toString();
            localStorage.setItem(LOCK_KEY, ourLockValue);
        }
    }, LOCK_HEARTBEAT_MS);

    window.addEventListener('beforeunload', function() {
        if (localStorage.getItem(LOCK_KEY) === ourLockValue) {
            localStorage.removeItem(LOCK_KEY);
        }
    });

    // Find a public room that the user has joined
    function findPublicRoom() {
        // Try multiple selectors for chat windows
        const chatWindows = document.querySelectorAll('[id^="CHATWINDOW"], [id^="ChatWindow"], [id^="chatwindow"], .x-window');

        for (const win of chatWindows) {
            // Try multiple selectors for the title
            const titleEl = win.querySelector('.x-window-header-text') ||
                           win.querySelector('.x-window-header span') ||
                           win.querySelector('[class*="header"] span');
            if (titleEl) {
                const title = titleEl.textContent.trim();
                for (const publicRoom of PUBLIC_ROOMS) {
                    // Use startsWith to match "General Chat" in "General Chat (45)"
                    if (title.startsWith(publicRoom)) {
                        // Extract room ID from window ID (format: CHATWINDOW08967111-b7ae-496c-...)
                        const roomId = win.id.replace(/^CHATWINDOW/i, '').replace(/^ChatWindow_?/i, '');
                        if (roomId) {
                            console.log(`KeepAlive: Found public room "${title}" with ID ${roomId}`);
                            return { roomId, title, windowId: win.id };
                        }
                    }
                }
            }
        }

        // Fallback: check RoomListStore
        if (typeof RoomListStore !== 'undefined' && RoomListStore.data) {
            const rooms = RoomListStore.data.items || [];
            for (const room of rooms) {
                const roomData = room.data || room;
                const name = roomData.Name || '';
                for (const publicRoom of PUBLIC_ROOMS) {
                    if (name.startsWith(publicRoom)) {
                        console.log(`KeepAlive: Found public room "${name}" with ID ${roomData.ID}`);
                        return { roomId: roomData.ID, title: name };
                    }
                }
            }
        }

        // Debug: log what windows we can find
        console.log('KeepAlive: Debug - searching for windows...');
        document.querySelectorAll('.x-window').forEach(w => {
            console.log('KeepAlive: Found window:', w.id, w.querySelector('.x-window-header-text')?.textContent);
        });

        return null;
    }

    function getUserId() {
        if (typeof userID !== 'undefined') return userID;
        if (typeof window.userID !== 'undefined') return window.userID;
        if (typeof _currentUserID !== 'undefined') return _currentUserID;
        if (typeof currentUserID !== 'undefined') return currentUserID;
        return null;
    }

    function getAuthCode() {
        if (typeof auth_code !== 'undefined') return auth_code;
        if (typeof window.auth_code !== 'undefined') return window.auth_code;
        if (typeof _authCode !== 'undefined') return _authCode;
        if (typeof authCode !== 'undefined') return authCode;
        return null;
    }

    function sendKeepAlive() {
        const room = findPublicRoom();
        if (!room) {
            console.log('KeepAlive: No public room found');
            return false;
        }

        // Find the chat input field for this room
        // Look for input field within the chat window
        const chatWindow = room.windowId ? document.getElementById(room.windowId) :
                          document.getElementById('CHATWINDOW' + room.roomId) ||
                          document.getElementById('ChatWindow_' + room.roomId) ||
                          document.querySelector(`[id*="${room.roomId}"].x-window`);

        if (!chatWindow) {
            console.log('KeepAlive: Could not find chat window element');
            return sendKeepAliveViaAPI(room);
        }

        // Find the text input field - usually a textarea or input within the window
        const inputField = chatWindow.querySelector('textarea') ||
                          chatWindow.querySelector('input[type="text"]') ||
                          chatWindow.querySelector('.x-form-text');

        if (!inputField) {
            console.log('KeepAlive: Could not find input field, trying API method');
            return sendKeepAliveViaAPI(room);
        }

        // Store current value, set our message, trigger submit, restore
        const originalValue = inputField.value;
        inputField.value = ' ';
        inputField.focus();

        // Trigger input event
        inputField.dispatchEvent(new Event('input', { bubbles: true }));
        inputField.dispatchEvent(new Event('change', { bubbles: true }));

        // Simulate Enter key press to submit
        const enterEvent = new KeyboardEvent('keydown', {
            key: 'Enter',
            code: 'Enter',
            keyCode: 13,
            which: 13,
            bubbles: true
        });
        inputField.dispatchEvent(enterEvent);

        const enterPress = new KeyboardEvent('keypress', {
            key: 'Enter',
            code: 'Enter',
            keyCode: 13,
            which: 13,
            bubbles: true
        });
        inputField.dispatchEvent(enterPress);

        const enterUp = new KeyboardEvent('keyup', {
            key: 'Enter',
            code: 'Enter',
            keyCode: 13,
            which: 13,
            bubbles: true
        });
        inputField.dispatchEvent(enterUp);

        console.log(`KeepAlive: Simulated input to "${room.title}" at ${new Date().toLocaleTimeString()}`);
        return true;
    }

    function sendKeepAliveViaAPI(room) {
        const userId = getUserId();
        if (!userId) {
            console.log('KeepAlive: User ID not found');
            return false;
        }

        const authCodeVal = getAuthCode();

        if (typeof Coolite !== 'undefined' && Coolite.AjaxMethods && Coolite.AjaxMethods.AddChatLine) {
            Coolite.AjaxMethods.AddChatLine(
                room.roomId,
                ' ',
                userId,
                window._ipaddress,
                window._urlwebchatid,
                window._urlwebchatkey,
                false,
                false,
                false,
                '',
                authCodeVal,
                {
                    success: function() {
                        console.log(`KeepAlive: Sent via API to "${room.title}" at ${new Date().toLocaleTimeString()}`);
                    },
                    failure: function(error) {
                        console.log('KeepAlive: Failed to send message', error);
                    }
                }
            );
            return true;
        } else {
            console.log('KeepAlive: Coolite.AjaxMethods.AddChatLine not available');
            return false;
        }
    }

    function startKeepAlive() {
        if (isKeepAliveRunning) return;

        const intervalMs = keepAliveSettings.intervalMinutes * 60 * 1000;
        keepAliveInterval = setInterval(sendKeepAlive, intervalMs);
        isKeepAliveRunning = true;
        updateKeepAliveButtonState();
        console.log(`KeepAlive: Started with ${keepAliveSettings.intervalMinutes} minute interval`);

        sendKeepAlive();
    }

    function stopKeepAlive() {
        if (keepAliveInterval) {
            clearInterval(keepAliveInterval);
            keepAliveInterval = null;
        }
        isKeepAliveRunning = false;
        updateKeepAliveButtonState();
        console.log('KeepAlive: Stopped');
    }

    function updateKeepAliveButtonState() {
        const button = document.getElementById(KEEPALIVE_BUTTON_ID);
        if (button) {
            if (isKeepAliveRunning) {
                button.style.backgroundColor = '#f44336';
                button.textContent = `Keep Alive ON (${keepAliveSettings.intervalMinutes}m)`;
            } else {
                button.style.backgroundColor = '#2196F3';
                button.textContent = 'Keep Alive OFF';
            }
        }
    }

    function showKeepAliveDialog() {
        const overlay = document.createElement('div');
        overlay.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 9999999; display: flex; align-items: center; justify-content: center;';

        const dialog = document.createElement('div');
        dialog.style.cssText = 'background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.5); min-width: 300px;';

        dialog.innerHTML = `
            <div style="font-family: Arial, sans-serif;">
                <h3 style="margin: 0 0 15px 0; color: #333;">Keep Alive Settings</h3>
                <p style="margin: 0 0 10px 0; color: #666;">Interval (minutes):</p>
                <input type="number" id="keepAliveIntervalInput" value="${keepAliveSettings.intervalMinutes}" min="1" max="30" style="width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; box-sizing: border-box;" />
                <p style="margin: 10px 0; color: #888; font-size: 12px;">Status: ${isKeepAliveRunning ? 'Running' : 'Stopped'}</p>
                <div style="margin-top: 15px; display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap;">
                    <button id="keepAliveCancelBtn" style="padding: 8px 15px; background: #ccc; color: #333; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">Cancel</button>
                    <button id="keepAliveToggleBtn" style="padding: 8px 15px; background: ${isKeepAliveRunning ? '#f44336' : '#4CAF50'}; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">${isKeepAliveRunning ? 'Stop' : 'Start'}</button>
                    <button id="keepAliveSaveBtn" style="padding: 8px 15px; background: #2196F3; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">Save</button>
                </div>
            </div>
        `;

        overlay.appendChild(dialog);
        document.body.appendChild(overlay);

        const input = document.getElementById('keepAliveIntervalInput');
        const saveBtn = document.getElementById('keepAliveSaveBtn');
        const cancelBtn = document.getElementById('keepAliveCancelBtn');
        const toggleBtn = document.getElementById('keepAliveToggleBtn');

        setTimeout(() => input.focus(), 100);

        saveBtn.onclick = function() {
            const value = parseInt(input.value, 10);
            if (value >= 1 && value <= 30) {
                keepAliveSettings.intervalMinutes = value;
                saveKeepAliveSettings();

                if (isKeepAliveRunning) {
                    stopKeepAlive();
                    startKeepAlive();
                }

                updateKeepAliveButtonState();
                overlay.remove();
            } else {
                alert('Please enter a number between 1 and 30');
            }
        };

        cancelBtn.onclick = function() {
            overlay.remove();
        };

        toggleBtn.onclick = function() {
            if (isKeepAliveRunning) {
                stopKeepAlive();
            } else {
                const value = parseInt(input.value, 10);
                if (value >= 1 && value <= 30) {
                    keepAliveSettings.intervalMinutes = value;
                    saveKeepAliveSettings();
                }
                startKeepAlive();
            }
            overlay.remove();
        };

        input.onkeypress = function(e) {
            if (e.key === 'Enter') {
                saveBtn.click();
            }
        };

        overlay.onkeydown = function(e) {
            if (e.key === 'Escape') {
                cancelBtn.click();
            }
        };
    }

    // ==================== MULTI-POKE FUNCTIONALITY ====================

    function performMultiPoke(roomId, userId, buttonElement) {
        const originalText = buttonElement.textContent;
        let pokeCount = 0;
        const totalPokes = DEFAULT_POKE_COUNT;

        // Disable the button during multi-poke
        buttonElement.style.opacity = '0.5';
        buttonElement.style.pointerEvents = 'none';

        function sendPoke() {
            if (pokeCount < totalPokes) {
                try {
                    if (typeof window.PK === 'function') {
                        window.PK(roomId, userId);
                    } else if (typeof Coolite !== 'undefined' && Coolite.AjaxMethods && Coolite.AjaxMethods.Poke) {
                        Coolite.AjaxMethods.Poke(roomId, '', userId, '', '');
                    } else {
                        const tempPokeLink = document.createElement('a');
                        tempPokeLink.href = `javascript:PK('${roomId}','${userId}')`;
                        tempPokeLink.style.display = 'none';
                        document.body.appendChild(tempPokeLink);
                        tempPokeLink.click();
                        document.body.removeChild(tempPokeLink);
                    }
                } catch (error) {
                    console.log('Poke error:', error);
                }

                pokeCount++;
                buttonElement.textContent = `${totalPokes - pokeCount}x`;

                if (pokeCount < totalPokes) {
                    setTimeout(sendPoke, POKE_DELAY);
                } else {
                    setTimeout(() => {
                        buttonElement.textContent = originalText;
                        buttonElement.style.opacity = '';
                        buttonElement.style.pointerEvents = '';
                    }, 500);
                }
            }
        }

        sendPoke();
    }

    function addMissingPokeButtons() {
        if (!multiPokeEnabled) return;

        // Find all user rows
        const userRows = document.querySelectorAll('.ur');

        userRows.forEach(userRow => {
            const allDiv = userRow.querySelector('.all');
            if (!allDiv) return;
            if (allDiv.innerHTML.trim() === '') return;

            // Check if this user already has a poke button
            if (allDiv.querySelector('a[href*="PK("]')) return;

            // Try to get room ID and user ID from block button
            const blockButton = allDiv.querySelector('a[href*="BU("]');
            if (!blockButton) return;

            const blockHref = blockButton.getAttribute('href');
            const userIdMatch = blockHref.match(/BU\('[^']+','([^']+)'\)/);
            const roomIdMatch = blockHref.match(/BU\('([^']+)'/);

            if (!userIdMatch || !roomIdMatch) return;

            const odlUserId = userIdMatch[1];
            const roomId = roomIdMatch[1];

            // Find insertion point (before block button)
            const insertionPoint = blockButton;

            // Add Poke button
            const pokeLink = document.createElement('a');
            pokeLink.className = 'ula';
            pokeLink.href = `javascript:PK('${roomId}','${odlUserId}')`;
            pokeLink.textContent = 'poke';
            pokeLink.setAttribute('data-added-by-script', 'true');

            allDiv.insertBefore(pokeLink, insertionPoint);
            const pokeSpace = document.createTextNode('\u00A0');
            allDiv.insertBefore(pokeSpace, insertionPoint);

            console.log(`Added poke button for user ${odlUserId}`);
        });
    }

    function addMultiPokeButtons() {
        if (!multiPokeEnabled) return;

        // First add missing poke buttons
        addMissingPokeButtons();

        console.log('Adding/updating multi-poke buttons...');

        // Find ALL poke buttons on the page
        const pokeButtons = document.querySelectorAll('a[href*="PK("]');

        pokeButtons.forEach(pokeButton => {
            // Check if multi-poke button already exists next to this poke button
            const parent = pokeButton.parentNode;
            if (!parent) return;

            // Skip if already has a multi-poke button nearby
            let nextSib = pokeButton.nextSibling;
            while (nextSib) {
                if (nextSib.nodeType === Node.ELEMENT_NODE && nextSib.classList && nextSib.classList.contains('multi-poke-btn')) {
                    return; // Already has one
                }
                // Only check immediate siblings (skip text nodes)
                if (nextSib.nodeType === Node.ELEMENT_NODE) break;
                nextSib = nextSib.nextSibling;
            }

            const pokeHref = pokeButton.getAttribute('href');
            const match = pokeHref.match(/PK\('([^']+)','([^']+)'\)/);
            if (!match) return;

            const roomId = match[1];
            const odlUserId = match[2];

            const multiPokeBtn = document.createElement('a');
            multiPokeBtn.className = 'multi-poke-btn';
            multiPokeBtn.href = 'javascript:void(0)';
            multiPokeBtn.textContent = '10x';
            multiPokeBtn.title = 'Send 10 pokes';
            multiPokeBtn.setAttribute('data-multi-poke', 'true');
            multiPokeBtn.setAttribute('data-user-id', odlUserId);

            multiPokeBtn.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                performMultiPoke(roomId, odlUserId, this);
            });

            const space = document.createTextNode('\u00A0');
            pokeButton.parentNode.insertBefore(space, pokeButton.nextSibling);
            pokeButton.parentNode.insertBefore(multiPokeBtn, space.nextSibling);

            console.log(`Added multi-poke button for user ${odlUserId}`);
        });
    }

    function removeMultiPokeButtons() {
        const multiPokeElements = document.querySelectorAll('.multi-poke-btn, [data-multi-poke="true"]');
        multiPokeElements.forEach(element => {
            if (element.previousSibling && element.previousSibling.nodeType === Node.TEXT_NODE) {
                element.previousSibling.remove();
            }
            element.remove();
        });
    }

    function toggleMultiPoke() {
        multiPokeEnabled = !multiPokeEnabled;
        saveMultiPokeSettings();
        updateMultiPokeButtonState();

        if (multiPokeEnabled) {
            addMultiPokeButtons();
        } else {
            removeMultiPokeButtons();
        }

        console.log('Multi-poke', multiPokeEnabled ? 'enabled' : 'disabled');
    }

    function updateMultiPokeButtonState() {
        const button = document.getElementById(MULTIPOKE_BUTTON_ID);
        if (button) {
            if (multiPokeEnabled) {
                button.style.backgroundColor = '#ff6b35';
                button.textContent = '10x ON';
            } else {
                button.style.backgroundColor = '#6c757d';
                button.textContent = '10x OFF';
            }
        }
    }

    function observeUserList() {
        const targetNode = document.querySelector('div[id*="CHATUSERLABEL"]') ||
                          document.querySelector('.x-panel-body') ||
                          document.body;

        const observer = new MutationObserver(function(mutations) {
            let shouldUpdate = false;
            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList') {
                    mutation.addedNodes.forEach(node => {
                        if (node.nodeType === Node.ELEMENT_NODE &&
                            (node.classList && node.classList.contains('ur') || node.querySelector && node.querySelector('.ur'))) {
                            shouldUpdate = true;
                        }
                    });
                }
                if (mutation.type === 'childList' && mutation.target.classList && mutation.target.classList.contains('ur')) {
                    shouldUpdate = true;
                }
            });

            if (shouldUpdate && multiPokeEnabled) {
                clearTimeout(window.multiPokeUpdateDebounce);
                window.multiPokeUpdateDebounce = setTimeout(() => {
                    addMultiPokeButtons();
                }, 200);
            }
        });

        observer.observe(targetNode, {
            childList: true,
            subtree: true
        });
    }

    // ==================== END MULTI-POKE ====================

    // Create custom dialog for MaxDockedCams
    function showCustomPrompt() {
        const overlay = document.createElement('div');
        overlay.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 9999999; display: flex; align-items: center; justify-content: center;';

        const dialog = document.createElement('div');
        dialog.style.cssText = 'background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.5); min-width: 300px;';

        dialog.innerHTML = `
            <div style="font-family: Arial, sans-serif;">
                <h3 style="margin: 0 0 15px 0; color: #333;">Set MaxDockedCams</h3>
                <p style="margin: 0 0 10px 0; color: #666;">Enter a number:</p>
                <input type="number" id="maxDockedInput" style="width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; box-sizing: border-box;" placeholder="Enter number" />
                <div style="margin-top: 15px; text-align: right;">
                    <button id="cancelBtn" style="padding: 8px 15px; margin-right: 10px; background: #ccc; color: #333; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">Cancel</button>
                    <button id="okBtn" style="padding: 8px 15px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">OK</button>
                </div>
            </div>
        `;

        overlay.appendChild(dialog);
        document.body.appendChild(overlay);

        const input = document.getElementById('maxDockedInput');
        const okBtn = document.getElementById('okBtn');
        const cancelBtn = document.getElementById('cancelBtn');

        setTimeout(() => input.focus(), 100);

        okBtn.onclick = function() {
            const value = input.value;
            if (value === '') {
                alert('Please enter a number');
                return;
            }

            const number = parseInt(value, 10);
            if (!isNaN(number)) {
                window.maxDockedCamsForUser = number;
                console.log(`maxDockedCamsForUser set to: ${number}`);
                overlay.remove();
                alert(`maxDockedCamsForUser successfully set to ${number}`);
            } else {
                alert('Please enter a valid number');
            }
        };

        cancelBtn.onclick = function() {
            console.log('User cancelled');
            overlay.remove();
        };

        input.onkeypress = function(e) {
            if (e.key === 'Enter') {
                okBtn.click();
            }
        };

        overlay.onkeydown = function(e) {
            if (e.key === 'Escape') {
                cancelBtn.click();
            }
        };
    }

    // Wait and create buttons
    setTimeout(function() {
        // Cleanup existing buttons
        document.querySelectorAll(`[id^="maxDockedCamsButton"]`).forEach(btn => btn.remove());
        document.querySelectorAll(`[id^="keepAliveButton"]`).forEach(btn => btn.remove());

        // MaxDockedCams button
        const maxDockedButton = document.createElement('button');
        maxDockedButton.id = BUTTON_ID;
        maxDockedButton.textContent = 'Set MaxDockedCams';
        maxDockedButton.type = 'button';
        maxDockedButton.style.cssText = 'position: fixed; top: 10px; left: calc(50% + 60px); z-index: 999999; padding: 8px 12px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.3);';

        maxDockedButton.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            showCustomPrompt();
        });

        document.body.appendChild(maxDockedButton);
        makeDraggable(maxDockedButton);
        console.log('MaxDockedCams button created');

        // Keep Alive button
        const keepAliveButton = document.createElement('button');
        keepAliveButton.id = KEEPALIVE_BUTTON_ID;
        keepAliveButton.type = 'button';
        keepAliveButton.style.cssText = 'position: fixed; top: 10px; left: calc(50% - 70px); z-index: 999999; padding: 8px 12px; background-color: #2196F3; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.3);';

        keepAliveButton.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            showKeepAliveDialog();
        });

        document.body.appendChild(keepAliveButton);
        makeDraggable(keepAliveButton);
        updateKeepAliveButtonState();
        console.log('KeepAlive button created');

        // Multi-Poke toggle button
        document.querySelectorAll(`[id^="multiPokeButton"]`).forEach(btn => btn.remove());
        const multiPokeButton = document.createElement('button');
        multiPokeButton.id = MULTIPOKE_BUTTON_ID;
        multiPokeButton.type = 'button';
        multiPokeButton.style.cssText = 'position: fixed; top: 10px; left: calc(50% - 170px); z-index: 999999; padding: 8px 12px; background-color: #ff6b35; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.3);';

        multiPokeButton.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            toggleMultiPoke();
        });

        document.body.appendChild(multiPokeButton);
        makeDraggable(multiPokeButton);
        updateMultiPokeButtonState();
        console.log('MultiPoke button created');

        // Reset positions button (small, top-left)
        document.querySelectorAll(`#${RESET_BUTTON_ID}`).forEach(btn => btn.remove());
        const resetButton = document.createElement('button');
        resetButton.id = RESET_BUTTON_ID;
        resetButton.textContent = 'R';
        resetButton.title = 'Reset button positions';
        resetButton.type = 'button';
        resetButton.style.cssText = 'position: fixed; top: 5px; left: 5px; z-index: 999999; padding: 2px 6px; background-color: #888; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 10px; font-weight: bold; opacity: 0.5;';

        resetButton.addEventListener('mouseenter', function() {
            this.style.opacity = '1';
        });
        resetButton.addEventListener('mouseleave', function() {
            this.style.opacity = '0.5';
        });
        resetButton.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            resetButtonPositions();
        });

        document.body.appendChild(resetButton);
        console.log('Reset button created');

        // Room join buttons (stacked vertically to the right of MaxDockedCams)
        document.querySelectorAll(`[id^="${ROOM_BUTTON_PREFIX}"]`).forEach(btn => btn.remove());
        CHAT_ROOMS.forEach((room, index) => {
            const roomBtnId = ROOM_BUTTON_PREFIX + index;
            const roomButton = document.createElement('button');
            roomButton.id = roomBtnId;
            roomButton.textContent = room.name;
            roomButton.type = 'button';
            roomButton.title = `Join ${room.name}`;
            roomButton.style.cssText = `position: fixed; top: ${10 + index * 36}px; left: calc(50% + 230px); z-index: 999999; padding: 6px 10px; background-color: #9C27B0; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 12px; box-shadow: 0 2px 5px rgba(0,0,0,0.3); white-space: nowrap;`;

            roomButton.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                if (typeof createRoomJoinWindow === 'function') {
                    createRoomJoinWindow(room.id, room.name);
                } else {
                    console.log(`Room join: createRoomJoinWindow not available`);
                }
            });

            document.body.appendChild(roomButton);
            makeDraggable(roomButton);
            console.log(`Room button created: ${room.name}`);
        });

        // Initialize multi-poke if enabled
        setTimeout(function() {
            if (multiPokeEnabled) {
                addMultiPokeButtons();
            }
            observeUserList();

            // Periodic check for new users
            setInterval(() => {
                if (multiPokeEnabled) {
                    addMultiPokeButtons();
                }
            }, 2000);
        }, 1000);

        // Cleanup duplicate buttons periodically
        setInterval(function() {
            const maxDockedButtons = document.querySelectorAll(`#${BUTTON_ID}`);
            if (maxDockedButtons.length > 1) {
                for (let i = 1; i < maxDockedButtons.length; i++) {
                    maxDockedButtons[i].remove();
                }
            }

            const keepAliveButtons = document.querySelectorAll(`#${KEEPALIVE_BUTTON_ID}`);
            if (keepAliveButtons.length > 1) {
                for (let i = 1; i < keepAliveButtons.length; i++) {
                    keepAliveButtons[i].remove();
                }
            }

            const multiPokeButtons = document.querySelectorAll(`#${MULTIPOKE_BUTTON_ID}`);
            if (multiPokeButtons.length > 1) {
                for (let i = 1; i < multiPokeButtons.length; i++) {
                    multiPokeButtons[i].remove();
                }
            }

            CHAT_ROOMS.forEach((room, index) => {
                const roomBtns = document.querySelectorAll(`#${ROOM_BUTTON_PREFIX}${index}`);
                if (roomBtns.length > 1) {
                    for (let i = 1; i < roomBtns.length; i++) {
                        roomBtns[i].remove();
                    }
                }
            });
        }, 500);

    }, 100);

    // Add CSS for multi-poke buttons and added poke buttons
    const style = document.createElement('style');
    style.textContent = `
        .multi-poke-btn {
            background-color: #ff6b35 !important;
            color: white !important;
            padding: 1px 4px !important;
            border-radius: 3px !important;
            text-decoration: none !important;
            font-weight: bold !important;
            font-size: 10px !important;
            margin-left: 2px !important;
        }
        .multi-poke-btn:hover {
            background-color: #ff8c42 !important;
            color: white !important;
        }
        .ula {
            color: #666 !important;
            text-decoration: underline !important;
            cursor: pointer !important;
        }
        .ula:hover {
            color: #007acc !important;
        }
    `;
    document.head.appendChild(style);

})();
