<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SHMCamStudio</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
    <style>
        /* Reset and base styles */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Inter', Arial, sans-serif;
        }
        body {
            background: #0a1122;
            color: #ffffff;
            display: flex;
            flex-direction: column;
            min-height: 100vh;
            overflow: hidden;
        }

        /* Top bar */
        .top-bar {
            height: 60px;
            background: linear-gradient(to right, #3b4d66, #6a1b9a);
            display: flex;
            align-items: center;
            padding: 0 20px;
            gap: 10px;
            
        }
        .top-bar img {
            height: 40px;
            width: auto;
            margin-right: 10px;
        }
        .top-bar span {
            font-size: 20px;
            font-weight: 600;
        }
        .top-bar a {
            color: #3b82f6;
            text-decoration: none;
        }
        .top-bar a:hover {
            text-decoration: underline;
        }
        
        /* Auto-open toggle in top bar */
        .auto-open-toggle {
            display: flex;
            align-items: center;
            margin-right: 15px;
            background: rgba(0, 0, 0, 0.2);
            padding: 5px 10px;
            border-radius: 20px;
        }
        
        .auto-open-toggle label {
            display: flex;
            align-items: center;
            cursor: pointer;
            font-size: 14px;
            color: #fff;
        }
        
        .auto-open-toggle input[type="checkbox"] {
            margin-right: 8px;
            cursor: pointer;
        }

        /* Desktop layout: 3 columns */
        .container {
            display: flex;
            height: calc(100vh - 60px);
            width: 100%;
        }

        .left-column {
            width: 25%;
            min-width: 20%;
            max-width: 45%;
            background: linear-gradient(to bottom, #2a2a2a, #1f1f1f);
            padding: 10px;
            border-right: 2px solid #111111;
            height: 100%;
            display: flex;
            flex-direction: column;
            overflow-x: hidden;
            overflow-y: auto;
            position: relative;
        }

        .resize-handle {
            position: absolute;
            right: -2px;
            top: 0;
            width: 4px;
            height: 100%;
            background: #111111;
            cursor: col-resize;
            z-index: 10;
        }

        .center-column {
            flex: 1;
            padding: 10px;
            background: linear-gradient(to bottom, #1c1c1c, #121212);
            display: flex;
            flex-direction: column;
        }

        .right-column {
            flex: 0 0 20%;
            background: linear-gradient(to bottom, #2a2a2a, #1f1f1f);
            padding: 10px;
            border-left: 2px solid #111111;
            overflow-y: auto;
        }

        /* Video window */
        .video-container {
            position: relative;
.tab[data-tab="session"] {
    background: #2a2a2a;
    border-radius: 8px 8px 0 0;
    margin-right: 5px;
    font-size: 14px;
    white-space: nowrap;
}

.tab[data-tab="session"].active {
    background: #3b82f6;
}
            background: #000;
            border-radius: 8px;
            overflow: hidden;
            flex-shrink: 0;
            width: 100%;
        }
        video {
            width: 100%;
            height: auto;
            aspect-ratio: 16 / 9;
            display: block;
        }
        .video-controls {
            position: absolute;
            top: 10px;
            left: 10px;
            display: flex;
            gap: 10px;
            opacity: 0;
            transition: opacity 0.3s;
        }
        .video-container:hover .video-controls {
            opacity: 1;
        }
        .video-controls select, .video-controls button {
            padding: 5px;
            border: none;
            border-radius: 20px;
            background: #3b82f6;
            color: #fff;
            cursor: pointer;
        }
        .video-controls select {
            flex: 1;
            min-width: 100px;
            max-width: 150px;
        }
        .video-controls button {
            min-width: 60px;
        }
        .video-stats {
            position: absolute;
            bottom: 0;
            width: 100%;
            background: rgba(0, 0, 0, 0.7);
            padding: 5px;
            font-size: 12px;
            border-radius: 0 0 8px 8px;
        }

        /* Online/offline button */
        .status-button-container {
            position: relative;
            display: flex;
            align-items: center;
            margin: 10px 0;
            flex-shrink: 0;
        }
        .status-button {
            flex: 1;
            padding: 12px;
            font-size: 18px;
            font-weight: 600;
            border: none;
            border-radius: 20px 0 0 20px;
            cursor: pointer;
            text-align: center;
        }
        .status-button.online {
            background: #dc3545;
        }
        .status-button.offline {
            background: #28a745;
        }
        .status-toggle {
            width: 40px;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.2);
            border: none;
            border-radius: 0 20px 20px 0;
            cursor: pointer;
            font-size: 16px;
            color: #fff;
        }
        .status-toggle:hover {
            background: rgba(0, 0, 0, 0.3);
        }
        .status-menu {
            display: none;
            position: absolute;
            top: 100%;
            right: 0;
            width: 300px;
            background: #2a2a2a;
            border: 1px solid #3b82f6;
            padding: 10px;
            z-index: 100;
            border-radius: 8px;
            margin-top: 5px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
        .status-menu button {
            display: flex;
            justify-content: space-between;
            width: 100%;
            padding: 8px;
            background: #135f2a8a;
            border: none;
            color: #fff;
            text-align: left;
            cursor: pointer;
            border-radius: 20px;
            margin-bottom: 5px;
        }
        .status-menu button[data-status="online"] {
           background: #794c4c;
        }
        .status-menu button:last-child {
            margin-bottom: 0;
        }
        .status-menu button .platform-status {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-left: 8px;
        }
        .status-menu button .platform-status.online {
            background: #28a745;
        }
        .status-menu button .platform-status.offline {
            background: #dc3545;
        }

        /* Tabs */
        .tabs {
            display: flex;
            border-bottom: 2px solid #111111;
            margin-top: 10px;
            flex-shrink: 0;
            overflow-x: hidden;
        }
        .tab {
            padding: 8px 12px;
            cursor: pointer;
            background: #2a2a2a;
            border-radius: 8px 8px 0 0;
            margin-right: 5px;
            font-size: 14px;
            white-space: nowrap;
        }
        .tab.active {
            background: #3b82f6;
        }
        .tab-content {
            display: none;
            padding: 15px;
            background: #2a2a2a;
            border-radius: 0 0 8px 8px;
            overflow-y: auto;
            flex-grow: 1;
            max-height: 100%;
            overflow-x: hidden;
        }
        .tab-content.active {
            display: block;
        }

        /* Chat window */
        .chat-window {
            flex: 1;
            background: #121212;
            border-radius: 8px;
            padding: 15px;
            overflow-y: auto;
            margin-bottom: 10px;
        }
        .message {
            margin: 8px 0;
            padding: 10px;
            font-size: 16px;
        }
        .message.me {
            background: linear-gradient(to right, #2563eb, #4b0082);
            margin-left: 20%;
            text-align: right;
            border-radius: 10px 10px 0px 10px;
        }
        .message.me .sender {
            color: #93c5fd;
            font-weight: 600;
        }
        .message.me .content {
            color: #f0f9ff;
        }
        .message.other {
            background: linear-gradient(to right, #1e293b, #2a1b3d);
            margin-right: 20%;
            border-radius: 10px 10px 10px 0px;
        }
        .message.notify-system {
            background: linear-gradient(to right, #964a5f, #71143f);
            margin: 8px 10%;
            text-align: center;
            border-radius: 8px;
        }
        .message.notify-platform {
            background: linear-gradient(to right, #b54d23, #813316);
            margin: 8px 10%;
            text-align: center;
            border-radius: 8px;
        }
        .message.tip {
            background: linear-gradient(to right, #064e3b, #1b3d2a);
            margin: 8px 10%;
            text-align: center;
            border-radius: 8px 8px 0 8px;
        }
        .message.tip .content {
            color: #d1fae5;
        }
        .message .sender {
            color: #60a5fa;
            font-weight: 600;
            cursor: pointer;
        }
        .message .content {
            color: #dfe2ea;
        }
        .message img {
            max-width: 100px;
            border-radius: 8px;
        }
        .message a {
            color: #00b7ff;
            text-decoration: underline;
        }
        .chat-input-container {
            display: flex;
            gap: 10px;
            align-items: stretch;
        }
        .chat-input {
            display: flex;
            gap: 10px;
            position: relative;
            flex: 1;
        }
        .platform-selector {
            height: 40px;
            padding: 8px;
            border: none;
            border-radius: 20px;
            background: #3b82f6;
            color: #fff;
            cursor: pointer;
            font-size: 14px;
            width: 120px;
        }
        .chat-input .emoji-button {
            position: absolute;
            left: 10px;
            top: 50%;
            transform: translateY(-50%);
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            z-index: 10;
        }
        .chat-input textarea {
            flex: 1;
            height: 40px;
            padding: 10px 40px 10px 60px;
            border: none;
            border-radius: 20px;
            background: #1e293b;
            color: #fff;
            resize: none;
            font-size: 14px;
        }
        .chat-input button {
            height: 40px;
            padding: 10px 20px;
            background: #3b82f6;
            border: none;
            border-radius: 20px;
            color: #fff;
            cursor: pointer;
            font-weight: 500;
        }
        .emoji-picker {
            display: none;
            position: absolute;
            background: #2a2a2a;
            border: 1px solid #3b82f6;
            padding: 10px;
            z-index: 100;
            border-radius: 8px;
            max-width: 300px;
            flex-wrap: wrap;
        }
        .emoji-picker span {
            cursor: pointer;
            font-size: 20px;
            margin: 5px;
        }

        /* User list */
        .user-list-header {
            display: flex;
            justify-content: space-between;
            padding: 8px;
            background: #2a2a2a;
            border-bottom: 2px solid #111111;
            font-size: 16px;
            font-weight: 600;
        }
        .user-list .platform {
            margin: 10px 0;
        }
        .platform-header {
            cursor: pointer;
            padding: 8px;
            background: #1e293b;
            border-radius: 8px;
            display: flex;
            justify-content: space-between;
            font-weight: 500;
        }
        .user {
            padding: 8px 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 14px;
        }
        .status-dot {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            display: inline-block;
            margin-right: 5px;
        }
        .status-dot.online {
            background: #28a745;
        }
        .status-dot.offline {
            background: #dc3545;
        }
        .users {
            display: none;
        }
        .users.active {
            display: block;
        }

        /* Context menu */
        .context-menu {
            position: absolute;
            background: #2a2a2a;
            border: 1px solid #3b82f6;
            padding: 10px;
            z-index: 1000;
            display: none;
            border-radius: 8px;
        }
        .context-menu a, .context-menu button {
            display: block;
            padding: 8px;
            color: #fff;
            text-decoration: none;
            background: none;
            border: none;
            cursor: pointer;
            width: 100%;
            text-align: left;
            border-radius: 20px;
            font-size: 14px;
        }
        .context-menu a:hover, .context-menu button:hover:not([disabled]) {
            background: #3b82f6;
        }
        .context-menu button[disabled] {
            color: #aaa;
            cursor: default;
        }

        /* Earnings table */
        .earnings-table {
            width: 100%;
            max-width: 100%;
            margin: 0;
            border-collapse: collapse;
            font-size: 12px;
        }
        .earnings-table th, .earnings-table td {
            padding: 6px;
            border: 1px solid #111111;
            text-align: left;
            white-space: nowrap;
        }
        .earnings-table tr:nth-child(even) {
            background: #1e293b;
        }
        .earnings-table th {
            background: #3b82f6;
            font-weight: 600;
        }
        .earnings-table .totals-row {
            background: #4b5563;
            font-weight: 600;
        }
        #earnings {
            overflow-x: auto;
            margin-bottom: 10px;
        }
        .reset-session-button {
            width: 100%;
            padding: 8px;
            background: #dc3545;
            border: none;
            border-radius: 20px;
            color: #fff;
            cursor: pointer;
            font-size: 12px;
            text-align: center;
        }
        .reset-session-button:hover {
            background: #b91c1c;
        }

        /* Notification indicator */
        .notification-indicator {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background-color: #ff3860;
            display: inline-block;
            margin-right: 8px;
            animation: blink 1s infinite;
        }
        
        @keyframes blink {
            0% { opacity: 1; }
            50% { opacity: 0.3; }
            100% { opacity: 1; }
        }
        
        /* Private chats list styles */
        .private-chats-list {
            margin-top: 10px;
        }
        
        .private-chat-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8px 10px;
            background: #1e293b;
            border-radius: 8px;
            margin-bottom: 8px;
            cursor: pointer;
        }
        
        .private-chat-item:hover {
            background: #2a3b53;
        }
        
        .private-chat-item-name {
            font-size: 14px;
            font-weight: 500;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .private-chat-item-close {
            color: #aaa;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            width: 20px;
            height: 20px;
            text-align: center;
            line-height: 20px;
        }
        
        .private-chat-item-close:hover {
            color: #fff;
        }
        
        .no-private-chats {
            text-align: center;
            padding: 20px;
            color: #aaa;
            font-style: italic;
        }
        
        /* Private chat window styles */
        .private-chat-window-container {
            display: none;
            position: fixed;
            top: 100px;
            right: 100px;
            width: 350px;
            z-index: 990;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
            border-radius: 8px;
            resize: both;
            overflow: hidden;
            min-width: 300px;
            min-height: 310px;
        }
        
        .private-chat-window-container.active {
            z-index: 991;
        }
        
        .private-chat-content {
            background: linear-gradient(to bottom, #2a2a2a, #1f1f1f);
            padding: 7px;
            padding-top: 0px;
            /* border: 1px solid #3b82f6; */
            border-radius: 8px;
            height: 100%;
            display: flex;
            flex-direction: column;
        }
        
        .private-chat-header {
            display: flex;
            background: linear-gradient(to right, #3b4d66, #6a1b9a);
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            margin-bottom: 10px;
            cursor: move; /* Indicate draggable */
        }
        
        .private-chat-title-container {
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .private-chat-header .notification-indicator {
            display: none; /* Hidden by default */
            margin-right: 8px;
        }
        
        .private-chat-title {
            font-size: 16px;
            font-weight: 600;
            color: #fff;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .private-chat-controls {
            display: flex;
            gap: 5px;
        }
        
        .minimize-chat,
        .close-chat {
            color: #aaa;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            width: 20px;
            height: 20px;
            text-align: center;
            line-height: 20px;
        }
        
        .minimize-chat:hover,
        .close-chat:hover {
            color: #fff;
        }
        
        .private-chat-messages {
            flex: 1;
            background: #121212;
            border-radius: 8px;
            padding: 10px;
            overflow-y: auto;
            margin-bottom: 10px;
            min-height: 200px;
        }
        
        .private-chat-input {
            display: flex;
            gap: 5px;
        }
        
        .private-chat-input textarea {
            flex: 1;
            height: 40px;
            padding: 8px 10px;
            border: none;
            border-radius: 20px;
            background: #1e293b;
            color: #fff;
            resize: none;
            font-size: 14px;
        }
        
        .private-chat-input button {
            height: 40px;
            padding: 8px 15px;
            background: #3b82f6;
            border: none;
            border-radius: 20px;
            color: #fff;
            cursor: pointer;
            font-weight: 500;
            font-size: 14px;
        }
        
        /* Mobile layout */
        @media (max-width: 768px) {
            .container {
                flex-direction: column;
                height: auto;
            }
            .left-column, .center-column, .right-column {
                width: 100%;
                border: none;
                min-width: 0;
                height: auto;
                display: block;
            }
            .left-column {
                order: -1;
            }
            .resize-handle {
                display: none;
            }
            .chat-window {
                height: 50vh;
            }
            .earnings-table {
                width: 100%;
            }
            .tab-content {
                max-height: none;
                display: block;
            }
            video {
                height: 200px;
            }
            .top-bar {
                padding: 0 10px;
            }
            .top-bar img {
                height: 30px;
            }
            .top-bar span {
                font-size: 16px;
            }
            .chat-input-container {
                flex-direction: column;
                align-items: stretch;
            }
            .platform-selector {
                width: 100%;
                margin-bottom: 5px;
            }
            .chat-input {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="top-bar">
        <img src="https://www.sexhack.me/content/uploads/2022/06/cropped-sexhack-300x99.png" alt="SexHack Logo">
        <span>SHM CamStudio by <a href="https://www.sexhack.me">sexhack.me</a></span>
        <div style="flex: 1;"></div>
        <div class="auto-open-toggle">
            <label for="auto-open-chats" title="Auto-open private chat windows">
                <input type="checkbox" id="auto-open-chats" checked>
                <span>Auto-open chats</span>
            </label>
        </div>
    </div>
    <div class="container">
        <div class="left-column">
            <div class="resize-handle"></div>
            <div class="video-container">
                <video id="video" autoplay></video>
                <div class="video-controls">
                    <select id="video-source"></select>
                    <button id="mirror-video">Mirror</button>
                </div>
                <div class="video-stats">
                    Bitrate: 2 Mbps | Quality: HD | Audio: <span id="audio-bar">████</span>
                </div>
            </div>
            <div class="status-button-container">
                <button class="status-button offline" id="status-button">GO ONLINE</button>
                <button class="status-toggle" id="status-toggle">⋮</button>
                <div class="status-menu" id="status-menu">
                    <button data-platform="C4.sexhackme">
                        C4.sexhackme
                        <span class="platform-status offline"></span>
                    </button>
                    <button data-platform="SC.spora">
                        SC.spora
                        <span class="platform-status offline"></span>
                    </button>
                </div>
            </div>
            <div class="tabs">
                <div class="tab active" data-tab="panel">Panel</div>
                <div class="tab" data-tab="earnings">Earnings</div>
<div class="tab" data-tab="session">Sessions</div>
            </div>
            <div class="tab-content active" id="panel">
                <div class="panel-container" style="position: relative;">
                    <div class="panel-header" style="display: flex; justify-content: space-between; align-items: center; background: #1e293b; padding: 5px 10px; border-radius: 8px 8px 0 0; margin-bottom: 2px;">
                        <span style="font-size: 14px; font-weight: 500;">Control Panel</span>
                        <button id="panel-expand-toggle" style="background: #3b82f6; color: white; border: none; border-radius: 4px; width: 30px; height: 24px; cursor: pointer; font-size: 14px;">⤢</button>
                    </div>
                    <iframe id="panel-iframe" style="width:100%;height:300px;border:none;border-radius:0 0 8px 8px;" src="/panel"></iframe>
                </div>
            </div>
            <div class="tab-content" id="earnings">
                <table class="earnings-table">
                    <thead>
                        <tr><th>Plat.<br>Acc.</th><th>Last<br>Sess</th><th>Today</th><th>Hour</th><th>Sess</th></tr>
                    </thead>
                    <tbody></tbody>
                </table>
                <button class="reset-session-button" id="reset-session">Reset Session</button>
            </div>
        </div>
        <div class="center-column">
            <div class="chat-window" id="chat-window"></div>
            <div class="chat-input-container">
                <select class="platform-selector" id="platform-selector">
                    <option value="all">All</option>
                    <option value="C4.sexhackme">C4.sexhackme</option>
                    <option value="SC.spora">SC.spora</option>
                </select>
                <div class="chat-input">
                    <button class="emoji-button">😊</button>
                    <textarea id="chat-input" rows="3" placeholder="Type a message..."></textarea>
                    <button id="send-message">Send</button>
                    <div class="emoji-picker" id="emoji-picker">
                        <span data-emoji="😊">😊</span><span data-emoji="👍">👍</span><span data-emoji="❤️">❤️</span><span data-emoji="😂">😂</span>
                        <span data-emoji="😍">😍</span><span data-emoji="😢">😢</span><span data-emoji="😎">😎</span><span data-emoji="😴">😴</span>
                        <span data-emoji="😛">😛</span><span data-emoji="😣">😣</span><span data-emoji="😇">😇</span><span data-emoji="😱">😱</span>
                        <span data-emoji="😳">😳</span><span data-emoji="😬">😬</span><span data-emoji="🙂">🙂</span><span data-emoji="🙃">🙃</span>
                        <span data-emoji="🙈">🙈</span><span data-emoji="🙉">🙉</span><span data-emoji="🙊">🙊</span><span data-emoji="💪">💪</span>
                        <span data-emoji="👏">👏</span><span data-emoji="👋">👋</span><span data-emoji="👌">👌</span><span data-emoji="👀">👀</span>
                        <span data-emoji="💋">💋</span><span data-emoji="💕">💕</span><span data-emoji="💖">💖</span><span data-emoji="💗">💗</span>
                        <span data-emoji="💥">💥</span><span data-emoji="💦">💦</span><span data-emoji="🔥">🔥</span><span data-emoji="⭐">⭐</span>
                        <span data-emoji="🌈">🌈</span><span data-emoji="🎉">🎉</span><span data-emoji="🎈">🎈</span><span data-emoji="🎁">🎁</span>
                        <span data-emoji="🍑">🍑</span><span data-emoji="🍆">🍆</span><span data-emoji="🍒">🍒</span><span data-emoji="🍓">🍓</span>
                    </div>
                </div>
            </div>
        </div>
        <div class="right-column">
            <div class="tabs">
                <div class="tab active" data-tab="userlist">Userlist (<span id="total-users">0</span>)</div>
                <div class="tab" data-tab="private-chats"><span class="notification-indicator" id="private-chats-tab-indicator" style="display: none;"></span>Private Chats (<span id="private-chats-count">0</span>)</div>
            </div>
            <div class="tab-content active" id="userlist">
                <div class="user-list" id="user-list"></div>
            </div>
            <div class="tab-content" id="private-chats">
                <div class="private-chats-list" id="private-chats-list">
                    <div class="no-private-chats">No private chats open</div>
                </div>
            </div>
        </div>
    </div>
    <div class="context-menu" id="context-menu">
        <a href="#" id="context-profile">View Profile</a>
        <button id="context-tokens">Tokens: 0</button>
        <button id="context-ban">Ban User</button>
        <button id="context-kick">Kick User</button>
        <button id="context-private">Private Chat</button>
    </div>
    
    <!-- Container for multiple private chat windows -->
    <div id="private-chat-windows-container"></div>

    <!-- Include Socket.IO client library -->
    <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
    
    <script>
        // Data variables that will be populated from the server
        let messages = [];
        let users = {};
        let earnings = [];
        let statusData = {};
        let rtspUrls = [];
        let privateChats = {};
        
        // Configuration variables
        let autoOpenPrivateChats = true; // Default to true (enabled)

        // Initialize video
        const video = document.getElementById('video');
        const videoSource = document.getElementById('video-source');
        const mirrorVideo = document.getElementById('mirror-video');
        let isMirrored = false;

        async function populateVideoSources() {
            videoSource.innerHTML = '<option value="none">Select Source</option>';
            try {
                const devices = await navigator.mediaDevices.enumerateDevices();
                devices.filter(d => d.kind === 'videoinput').forEach((device, index) => {
                    const option = document.createElement('option');
                    option.value = device.deviceId;
                    option.text = device.label || `Webcam ${index + 1}`;
                    videoSource.appendChild(option);
                });
            } catch (err) {
                console.error('Error enumerating devices:', err);
            }
            rtspUrls.forEach(url => {
                const option = document.createElement('option');
                option.value = url.id;
                option.text = url.url;
                videoSource.appendChild(option);
            });
            navigator.mediaDevices.getUserMedia({ video: true })
                .then(stream => {
                    video.srcObject = stream;
                    videoSource.value = stream.getVideoTracks()[0].getSettings().deviceId;
                })
                .catch(err => console.error('Webcam access error:', err));
        }

        videoSource.addEventListener('change', () => {
            if (videoSource.value === 'none') {
                video.srcObject = null;
                video.src = '';
            } else if (rtspUrls.find(url => url.id === videoSource.value)) {
                video.srcObject = null;
                video.src = rtspUrls.find(url => url.id === videoSource.value).url;
            } else {
                navigator.mediaDevices.getUserMedia({ video: { deviceId: videoSource.value } })
                    .then(stream => video.srcObject = stream)
                    .catch(err => console.error('Webcam error:', err));
            }
        });

        mirrorVideo.addEventListener('click', () => {
            isMirrored = !isMirrored;
            video.style.transform = isMirrored ? 'scaleX(-1)' : 'scaleX(1)';
        });

        // Resize handle
        const leftColumn = document.querySelector('.left-column');
        const resizeHandle = document.querySelector('.resize-handle');
        let isResizing = false;

        resizeHandle.addEventListener('mousedown', (e) => {
            isResizing = true;
            e.preventDefault();
        });

        document.addEventListener('mousemove', (e) => {
            if (isResizing) {
                const newWidth = e.clientX;
                if (newWidth >= window.innerWidth * 0.2 && newWidth <= window.innerWidth * 0.45) {
                    leftColumn.style.width = `${newWidth}px`;
                }
            }
        });

        document.addEventListener('mouseup', () => {
            isResizing = false;
        });

        // Status button and menu
        const statusButton = document.getElementById('status-button');
        const statusToggle = document.getElementById('status-toggle');
        const statusMenu = document.getElementById('status-menu');
        
        // Main status button toggles all platforms at once
        statusButton.addEventListener('click', () => {
            const isCurrentlyOffline = statusButton.textContent === 'GO ONLINE';
            const newStatus = isCurrentlyOffline ? 'online' : 'offline';
            
            // Send status update to server
            fetch('/api/update_status', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    all: newStatus
                }),
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    statusData = data.status;
                    updateStatus();
                }
            })
            .catch(error => {
                console.error('Error updating status:', error);
            });
        });
        
        // Toggle button shows/hides the platform menu
        statusToggle.addEventListener('click', (e) => {
            e.stopPropagation(); // Prevent triggering the main button
            statusMenu.style.display = statusMenu.style.display === 'block' ? 'none' : 'block';
        });
        
        // Close menu when clicking outside
        document.addEventListener('click', (e) => {
            if (!statusToggle.contains(e.target) && !statusMenu.contains(e.target)) {
                statusMenu.style.display = 'none';
            }
        });
        
        // Individual platform buttons
        statusMenu.querySelectorAll('button').forEach(btn => {
            btn.addEventListener('click', (e) => {
                e.stopPropagation();
                const platform = btn.dataset.platform;
                const newStatus = statusData[platform] === 'online' ? 'offline' : 'online';
                
                // Send status update to server
                fetch('/api/update_status', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        platform: platform,
                        status: newStatus
                    }),
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        statusData = data.status;
                        updateStatus();
                    }
                })
                .catch(error => {
                    console.error('Error updating status:', error);
                });
            });
        });

        function updateStatus() {
            // Update main button based on any platform being online
            const isOnline = Object.values(statusData).some(status => status === 'online');
            statusButton.className = `status-button ${isOnline ? 'online' : 'offline'}`;
            statusButton.textContent = isOnline ? 'GO OFFLINE' : 'GO ONLINE';
            
            // Update individual platform buttons
            statusMenu.querySelectorAll('button').forEach(btn => {
                const platform = btn.dataset.platform;
                const statusDot = btn.querySelector('.platform-status');
                const isOnline = statusData[platform] === 'online';
                
                // Update status dot
                statusDot.className = `platform-status ${statusData[platform]}`;
                
                // Update button status attribute for styling
                if (isOnline) {
                    btn.setAttribute('data-status', 'online');
                } else {
                    btn.removeAttribute('data-status');
                }
            });
        }

        // Load panel content
        //const panelIframe = document.getElementById('panel-iframe');
        //panelIframe.srcdoc = '<p>Control panel content loaded here.</p>';

        // Chat functionality
        const chatWindow = document.getElementById('chat-window');
        const chatInput = document.getElementById('chat-input');
        const sendButton = document.getElementById('send-message');
        const emojiButton = document.querySelector('.emoji-button');
        const emojiPicker = document.getElementById('emoji-picker');
        const platformSelector = document.getElementById('platform-selector');

        function renderMessages(messages) {
            chatWindow.innerHTML = '';
            messages.forEach(msg => {
                const div = document.createElement('div');
                div.className = `message ${msg.sender === 'me' ? 'me' : msg.type === 'notify-system' ? 'notify-system' : msg.type === 'notify-platform' ? 'notify-platform' : msg.type === 'tip' ? 'tip' : 'other'}`;
                div.dataset.sender = msg.sender;
                let content = msg.content;
                if (!msg.type?.startsWith('notify') && msg.type !== 'tip' && !msg.content.includes('<img')) {
                    content = msg.content
                        .replace(/\n/g, '<br>')
                        .replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" target="_blank">$1</a>');
                }
                if (msg.sender === 'me') {
                    const senderSpan = document.createElement('span');
                    senderSpan.className = 'sender';
                    senderSpan.textContent = 'me:';
                    senderSpan.style.color = '#93c5fd';
                    div.appendChild(senderSpan);
                    div.appendChild(document.createTextNode(' '));
                } else if (msg.sender !== 'me' && !msg.type?.startsWith('notify') && msg.type !== 'tip') {
                    const senderSpan = document.createElement('span');
                    senderSpan.className = 'sender';
                    senderSpan.textContent = msg.sender;
                    senderSpan.dataset.sender = msg.sender;
                    senderSpan.addEventListener('contextmenu', (e) => {
                        e.preventDefault();
                        showContextMenu(e, msg.sender);
                    });
                    senderSpan.addEventListener('dblclick', () => {
                        openPrivateChat(msg.sender);
                    });
                    div.appendChild(senderSpan);
                    div.appendChild(document.createTextNode(': '));
                }
                const contentSpan = document.createElement('span');
                contentSpan.className = 'content';
                contentSpan.innerHTML = content;
                div.appendChild(contentSpan);
                const senderSpan = div.querySelector('.sender');
                if (senderSpan && msg.sender !== 'me' && !msg.type?.startsWith('notify')) {
                    senderSpan.addEventListener('contextmenu', (e) => {
                        e.preventDefault();
                        showContextMenu(e, senderSpan.dataset.sender, false);
                    });
                    senderSpan.addEventListener('dblclick', () => {
                        openPrivateChat(senderSpan.dataset.sender);
                    });
                }
                chatWindow.appendChild(div);
            });
            chatWindow.scrollTop = chatWindow.scrollHeight;
        }

        // Username autocompletion
        let completionState = { index: -1, prefix: '', original: '', matches: [] };

        function getUsernames() {
            const usernames = new Set();
            for (const platform in users) {
                users[platform].forEach(user => {
                    usernames.add(`${user.username}@${platform}`);
                });
            }
            messages.forEach(msg => {
                if (msg.sender !== 'me' && !msg.sender.startsWith('system') && !msg.sender.startsWith('platform@')) {
                    usernames.add(msg.sender);
                }
            });
            return Array.from(usernames);
        }

        chatInput.addEventListener('keydown', (e) => {
            if (e.key === 'Tab') {
                e.preventDefault();
                const text = chatInput.value;
                const cursorPos = chatInput.selectionStart;
                const textBeforeCursor = text.slice(0, cursorPos);
                const lastWordMatch = textBeforeCursor.match(/(\S+)$/);
                if (lastWordMatch) {
                    const prefix = lastWordMatch[1];
                    const usernames = getUsernames();
                    let matches = usernames.filter(u => u.toLowerCase().startsWith(prefix.toLowerCase()));
                    if (matches.length === 0) return;

                    if (completionState.prefix !== prefix) {
                        completionState = { index: -1, prefix, original: prefix, matches };
                    }

                    completionState.index = (completionState.index + 1) % matches.length;
                    const selectedUsername = matches[completionState.index];

                    const isFirstWord = textBeforeCursor.trim().length === prefix.length && textBeforeCursor.match(/^\s*/)[0].length + prefix.length === textBeforeCursor.length;
                    const replacement = isFirstWord ? `${selectedUsername}: ` : selectedUsername;

                    const newText = text.slice(0, cursorPos - prefix.length) + replacement + text.slice(cursorPos);
                    chatInput.value = newText;
                    chatInput.selectionStart = chatInput.selectionEnd = cursorPos - prefix.length + replacement.length;
                }
            } else if (e.key === 'Enter') {
                if (e.shiftKey || e.ctrlKey) {
                    e.preventDefault();
                    chatInput.value += '\n';
                } else {
                    e.preventDefault();
                    sendMessage();
                }
            } else {
                completionState = { index: -1, prefix: '', original: '', matches: [] };
            }
        });

        sendButton.addEventListener('click', sendMessage);

        function sendMessage() {
            const content = chatInput.value.trim();
            const platform = platformSelector.value;
            if (content) {
                console.log(`Sending message to ${platform}: ${content}`);
                
                // Send message to server
                fetch(`/api/send_message?client_id=${clientId}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        content: content,
                        platform: platform
                    }),
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        // Add new message to the list
                        messages.push(data.message);
                        renderMessages(messages);
                    }
                })
                .catch(error => {
                    console.error('Error sending message:', error);
                });
                
                chatInput.value = '';
                completionState = { index: -1, prefix: '', original: '', matches: [] };
            }
        }

        // Emoji picker
        emojiButton.addEventListener('mouseover', () => {
            emojiPicker.style.display = 'flex';
            emojiPicker.style.left = `${emojiButton.offsetLeft}px`;
            emojiPicker.style.top = `${emojiButton.offsetTop - emojiPicker.offsetHeight}px`;
        });
        emojiPicker.addEventListener('mouseleave', () => {
            emojiPicker.style.display = 'none';
        });
        emojiPicker.querySelectorAll('span').forEach(span => {
            span.addEventListener('click', () => {
                chatInput.value += span.dataset.emoji;
                emojiPicker.style.display = 'none';
                chatInput.focus();
            });
        });

        // Context menu
        const contextMenu = document.getElementById('context-menu');
        function showContextMenu(e, sender, isFromPrivateChat = false) {
            e.preventDefault();
            const parts = sender.split('@');
            if (parts.length !== 2) {
                console.error(`Invalid sender format: ${sender}`);
                return;
            }
            const [username, platformAccount] = parts;
            const [platform, account] = platformAccount.split('.');
            if (!platform || !account) {
                console.error(`Invalid platform.account format: ${platformAccount}`);
                return;
            }
            const userList = users[`${platform}.${account}`];
            if (!userList) {
                console.error(`Platform not found in users: ${platform}.${account}`);
                return;
            }
            const user = userList.find(u => u.username === username);
            if (!user) {
                console.error(`User not found: ${username} in ${platform}.${account}`);
                return;
            }
            
            // Set profile link
            contextMenu.querySelector('#context-profile').href = `https://${platform}.com/profile/${username}`;
            
            // Change tokens to non-clickable text
            const tokensElement = contextMenu.querySelector('#context-tokens');
            tokensElement.textContent = `Tokens: ${user.tokens}`;
            tokensElement.style.cursor = 'default';
            tokensElement.setAttribute('disabled', 'disabled');
            
            // Set other button actions
            contextMenu.querySelector('#context-ban').onclick = () => alert(`Ban ${sender}`);
            contextMenu.querySelector('#context-kick').onclick = () => alert(`Kick ${sender}`);
            
            // Hide or show private chat button based on context
            const privateButton = contextMenu.querySelector('#context-private');
            if (isFromPrivateChat) {
                privateButton.style.display = 'none';
            } else {
                privateButton.style.display = 'block';
                privateButton.onclick = () => openPrivateChat(sender);
            }
            
            contextMenu.style.display = 'block';
            contextMenu.style.left = `${e.pageX}px`;
            contextMenu.style.top = `${e.pageY}px`;
        }

        document.addEventListener('click', () => {
            contextMenu.style.display = 'none';
            statusMenu.style.display = 'none';
        });

        // User list
        function renderUserList() {
            const userList = document.getElementById('user-list');
            const totalUsers = document.getElementById('total-users');
            let total = 0;
            userList.innerHTML = '';
            for (const platform in users) {
                total += users[platform].length;
                const platformDiv = document.createElement('div');
                platformDiv.className = 'platform';
                platformDiv.innerHTML = `<div class="platform-header">${platform} <span>(${users[platform].length})</span></div>`;
                const usersDiv = document.createElement('div');
                usersDiv.className = 'users';
                users[platform].forEach(user => {
                    const userDiv = document.createElement('div');
                    userDiv.className = 'user';
                    userDiv.dataset.sender = `${user.username}@${platform}`;
                    userDiv.innerHTML = `
                        <span><span class="status-dot ${user.status}"></span>${user.username}</span>
                        <span>${user.tokens} tokens</span>
                    `;
                    userDiv.addEventListener('contextmenu', (e) => {
                        e.preventDefault();
                        showContextMenu(e, userDiv.dataset.sender, false);
                    });
                    userDiv.addEventListener('dblclick', () => {
                        openPrivateChat(userDiv.dataset.sender);
                    });
                    usersDiv.appendChild(userDiv);
                });
                platformDiv.appendChild(usersDiv);
                userList.appendChild(platformDiv);
            }
            totalUsers.textContent = total;
            document.querySelectorAll('.platform-header').forEach(header => {
                header.addEventListener('click', () => {
                    const users = header.nextElementSibling;
                    users.classList.toggle('active');
                });
            });
        }

        // Tabs
        document.querySelectorAll('.tabs').forEach(tabGroup => {
                    tabGroup.querySelectorAll('.tab').forEach(tab => {
                        tab.addEventListener('click', () => {
                            // Only affect tabs within the same tab group
                            tabGroup.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                            tab.classList.add('active');
                            
                            // Only affect tab content elements related to this tab group
                            const tabContentId = tab.dataset.tab;
                            document.getElementById(tabContentId).classList.add('active');
                            
                            // Find all sibling tab contents and hide them
                            const tabContents = document.querySelectorAll('.tab-content');
                            tabContents.forEach(content => {
                                if (content.id !== tabContentId &&
                                    ((tabGroup.closest('.left-column') && content.closest('.left-column')) ||
                                     (tabGroup.closest('.right-column') && content.closest('.right-column')))) {
                                    content.classList.remove('active');
                                }
                            });
                        });
                    });
                });

        // Earnings
        function renderEarnings() {
            const tbody = document.querySelector('.earnings-table tbody');
            tbody.innerHTML = '';
            const totals = earnings.reduce((acc, e) => ({
                lastSession: acc.lastSession + e.lastSession,
                today: acc.today + e.today,
                lastHour: acc.lastHour + e.lastHour,
                sess: acc.sess + e.sess
            }), { lastSession: 0, today: 0, lastHour: 0, sess: 0 });
            const totalsRow = document.createElement('tr');
            totalsRow.className = 'totals-row';
            totalsRow.innerHTML = `
                <td>Totals</td>
                <td>$${totals.lastSession}</td>
                <td>$${totals.today}</td>
                <td>$${totals.lastHour}</td>
                <td>$${totals.sess}</td>
            `;
            tbody.appendChild(totalsRow);
            earnings.forEach(e => {
                const [platform, account] = e.platform.split('.');
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${platform}<br>${account}</td>
                    <td>$${e.lastSession}</td>
                    <td>$${e.today}</td>
                    <td>$${e.lastHour}</td>
                    <td>$${e.sess}</td>
                `;
                tbody.appendChild(row);
            });
        }

        // Reset session button
        document.getElementById('reset-session').addEventListener('click', () => {
            fetch('/api/reset_session', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({}),
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // The long polling will automatically update the earnings data
                    console.log("Session reset successfully");
                }
            })
            .catch(error => {
                console.error('Error resetting session:', error);
            });
        });

        // Private Chat functionality
        const privateChatWindowsContainer = document.getElementById('private-chat-windows-container');
        
        // Store private chat states
        const openPrivateChats = new Set(); // Track open private chats
        const activeChatWindows = {}; // Store references to active chat windows
        
        // Track dragging state for each window
        const dragStates = {};
        
        // Private chats list
        const privateChatsListElement = document.getElementById('private-chats-list');
        
        function renderPrivateChatslist() {
            privateChatsListElement.innerHTML = '';
            
            // Update the private chats count in the tab title
            const privateChatsCount = document.getElementById('private-chats-count');
            privateChatsCount.textContent = openPrivateChats.size;
            
            if (openPrivateChats.size === 0) {
                const noChatsDiv = document.createElement('div');
                noChatsDiv.className = 'no-private-chats';
                noChatsDiv.textContent = 'No private chats open';
                privateChatsListElement.appendChild(noChatsDiv);
                return;
            }
            
            openPrivateChats.forEach(sender => {
                const chatItem = document.createElement('div');
                chatItem.className = 'private-chat-item';
                chatItem.dataset.sender = sender;
                
                // Create notification indicator
                const notificationIndicator = document.createElement('span');
                notificationIndicator.className = 'notification-indicator';
                
                // Initially hide the notification indicator
                notificationIndicator.style.display = 'none';
                
                const nameSpan = document.createElement('div');
                nameSpan.className = 'private-chat-item-name';
                nameSpan.textContent = sender;
                
                // Create a container for the indicator and name
                const leftContainer = document.createElement('div');
                leftContainer.style.display = 'flex';
                leftContainer.style.alignItems = 'center';
                leftContainer.appendChild(notificationIndicator);
                leftContainer.appendChild(nameSpan);
                
                const closeButton = document.createElement('div');
                closeButton.className = 'private-chat-item-close';
                closeButton.innerHTML = '&times;';
                closeButton.title = 'Close chat';
                
                chatItem.appendChild(leftContainer);
                chatItem.appendChild(closeButton);
                
                // Click on chat item to open/restore the chat
                chatItem.addEventListener('click', (e) => {
                    if (e.target !== closeButton) {
                        openPrivateChat(sender);
                    }
                });
                
                // Right-click on chat item to show context menu
                chatItem.addEventListener('contextmenu', (e) => {
                    if (e.target !== closeButton) {
                        e.preventDefault();
                        showContextMenu(e, sender, false);
                    }
                });
                
                // Click on close button to close the chat
                closeButton.addEventListener('click', (e) => {
                    e.stopPropagation();
                    closePrivateChat(sender);
                });
                
                privateChatsListElement.appendChild(chatItem);
            });
        }
        
                // Create a new private chat window
                function createPrivateChatWindow(sender) {
                    // Create window container
                    const chatWindow = document.createElement('div');
                    chatWindow.className = 'private-chat-window-container';
                    chatWindow.id = `private-chat-window-${sender.replace(/[@.]/g, '-')}`;
                    chatWindow.dataset.sender = sender;
                    
                    // Position windows in a cascading manner
                    const openWindowsCount = document.querySelectorAll('.private-chat-window-container').length;
                    const offsetX = 50 + (openWindowsCount * 20);
                    const offsetY = 100 + (openWindowsCount * 20);
                    chatWindow.style.top = `${offsetY}px`;
                    chatWindow.style.right = `${offsetX}px`;
                    
                    // Create window content
                    chatWindow.innerHTML = `
                        <div class="private-chat-content">
                            <div class="private-chat-header" data-sender="${sender}">
                                <div class="private-chat-title-container">
                                    <span class="notification-indicator"></span>
                                    <div class="private-chat-title">Private Chat with <span class="private-chat-username">${sender}</span></div>
                                </div>
                                <div class="private-chat-controls">
                                    <span class="minimize-chat" title="Minimize">_</span>
                                    <span class="close-chat" title="Close">&times;</span>
                                </div>
                            </div>
                            <div class="private-chat-messages"></div>
                            <div class="private-chat-input">
                                <textarea placeholder="Type a private message..."></textarea>
                                <button class="send-private-message">Send</button>
                            </div>
                        </div>
                    `;
                    
                    // Add to DOM
                    privateChatWindowsContainer.appendChild(chatWindow);
                    
                    // Setup dragging for this window
                    setupDraggableWindow(chatWindow);
                    
                    // Setup event listeners for this window
                    setupChatWindowEvents(chatWindow, sender);
                    
                    // Store reference to the window
                    activeChatWindows[sender] = chatWindow;
                    
                    return chatWindow;
                }
                
                // Setup dragging functionality for a chat window
                function setupDraggableWindow(chatWindow) {
                    const header = chatWindow.querySelector('.private-chat-header');
                    const sender = header.dataset.sender;
                    
                    // Initialize drag state for this window
                    dragStates[sender] = {
                        isDragging: false,
                        offsetX: 0,
                        offsetY: 0
                    };
                    
                    header.addEventListener('mousedown', (e) => {
                        const state = dragStates[sender];
                        state.isDragging = true;
                        state.offsetX = e.clientX - chatWindow.getBoundingClientRect().left;
                        state.offsetY = e.clientY - chatWindow.getBoundingClientRect().top;
                        header.style.cursor = 'grabbing';
                    });
                    
                    document.addEventListener('mousemove', (e) => {
                        const state = dragStates[sender];
                        if (state && state.isDragging) {
                            const x = e.clientX - state.offsetX;
                            const y = e.clientY - state.offsetY;
                            
                            // Keep window within viewport bounds
                            const maxX = window.innerWidth - chatWindow.offsetWidth;
                            const maxY = window.innerHeight - chatWindow.offsetHeight;
                            
                            chatWindow.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
                            chatWindow.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
                        }
                    });
                    
                    // Add mouseup event to stop dragging
                    document.addEventListener('mouseup', () => {
                        const state = dragStates[sender];
                        if (state) {
                            state.isDragging = false;
                            header.style.cursor = 'move';
                        }
                    });
                }
                
                // Setup event listeners for a chat window
                function setupChatWindowEvents(chatWindow, sender) {
                    const closeBtn = chatWindow.querySelector('.close-chat');
                    const minimizeBtn = chatWindow.querySelector('.minimize-chat');
                    const sendBtn = chatWindow.querySelector('.send-private-message');
                    const textarea = chatWindow.querySelector('textarea');
                    const header = chatWindow.querySelector('.private-chat-header');
                    
                    // Close button
                    closeBtn.addEventListener('click', () => {
                        closePrivateChat(sender);
                    });
                    
                    // Minimize button
                    minimizeBtn.addEventListener('click', () => {
                        minimizePrivateChat(sender);
                    });
                    
                    // Right-click on header to show context menu
                    header.addEventListener('contextmenu', (e) => {
                        e.preventDefault();
                        showContextMenu(e, sender, true);
                    });
                    
                    // Set active window on click (for z-index management)
                    chatWindow.addEventListener('mousedown', () => {
                        setActivePrivateChat(sender);
                    });
                    
                    // Send button
                    sendBtn.addEventListener('click', () => {
                        sendPrivateMessage(sender);
                    });
                    
                    // Enter key to send
                    textarea.addEventListener('keydown', (e) => {
                        if (e.key === 'Enter' && !e.shiftKey) {
                            e.preventDefault();
                            sendPrivateMessage(sender);
                        }
                    });
                }
                
                // Open a private chat window
                function openPrivateChat(sender) {
                    // Initialize private chat if it doesn't exist
                    if (!privateChats[sender]) {
                        privateChats[sender] = [];
                    }
                    
                    // Add to open chats if not already there
                    if (!openPrivateChats.has(sender)) {
                        openPrivateChats.add(sender);
                        renderPrivateChatslist();
                    }
                    
                    // Get or create the chat window
                    let chatWindow = activeChatWindows[sender];
                    if (!chatWindow) {
                        chatWindow = createPrivateChatWindow(sender);
                    }
                    
                    // Show and restore the window
                    chatWindow.style.display = 'block';
                    
                    // Render messages
                    renderPrivateMessages(sender);
                    
                    // Focus the input
                    chatWindow.querySelector('textarea').focus();
                    
                    // Mark messages as read
                    markMessagesAsRead(sender);
                    
                    // Set as active window
                    setActivePrivateChat(sender);
                }
                
                // Set active private chat window (manage z-index)
                function setActivePrivateChat(sender) {
                    // Set all windows to z-index 990
                    Object.keys(activeChatWindows).forEach(key => {
                        if (activeChatWindows[key]) {
                            activeChatWindows[key].classList.remove('active');
                        }
                    });
                    
                    // Set the clicked window to z-index 991
                    if (activeChatWindows[sender]) {
                        activeChatWindows[sender].classList.add('active');
                    }
                }
                
                // Mark messages as read for a specific sender
                function markMessagesAsRead(sender) {
                    fetch(`/api/mark_messages_read?client_id=${clientId}`, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            sender: sender
                        }),
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            // Update the notification indicator in the chat list
                            const chatItem = document.querySelector(`.private-chat-item[data-sender="${sender}"]`);
                            if (chatItem) {
                                const indicator = chatItem.querySelector('.notification-indicator');
                                if (indicator) {
                                    indicator.style.display = 'none';
                                }
                            }
                            
                            // Also hide the indicator in the chat window header
                            const chatWindow = activeChatWindows[sender];
                            if (chatWindow) {
                                const headerIndicator = chatWindow.querySelector('.private-chat-header .notification-indicator');
                                if (headerIndicator) {
                                    headerIndicator.style.display = 'none';
                                }
                            }
                            
                            // Check if any other chats have unread messages
                            let anyUnread = false;
                            document.querySelectorAll('.private-chat-item .notification-indicator').forEach(ind => {
                                if (ind.style.display === 'inline-block') {
                                    anyUnread = true;
                                }
                            });
                            
                            // Update tab indicator
                            if (!anyUnread) {
                                const tabIndicator = document.getElementById('private-chats-tab-indicator');
                                if (tabIndicator) {
                                    tabIndicator.style.display = 'none';
                                }
                            }
                        }
                    })
                    .catch(error => {
                        console.error('Error marking messages as read:', error);
                    });
                }
                
                // Close a private chat window
                function closePrivateChat(sender) {
                    const chatWindow = activeChatWindows[sender];
                    if (chatWindow) {
                        chatWindow.remove();
                        delete activeChatWindows[sender];
                        delete dragStates[sender];
                    }
                    
                    openPrivateChats.delete(sender);
                    renderPrivateChatslist();
                }
                
                // Minimize a private chat window
                function minimizePrivateChat(sender) {
                    const chatWindow = activeChatWindows[sender];
                    if (chatWindow) {
                        chatWindow.style.display = 'none';
                    }
                }
                
                // Render messages in a private chat window
                function renderPrivateMessages(sender) {
                    const chatWindow = activeChatWindows[sender];
                    if (!chatWindow) return;
                    
                    const messagesContainer = chatWindow.querySelector('.private-chat-messages');
                    messagesContainer.innerHTML = '';
                    
                    if (privateChats[sender] && privateChats[sender].length > 0) {
                        privateChats[sender].forEach(msg => {
                            const div = document.createElement('div');
                            div.className = `message ${msg.sender === 'me' ? 'me' : 'other'}`;
                            
                            if (msg.sender === 'me') {
                                const senderSpan = document.createElement('span');
                                senderSpan.className = 'sender';
                                senderSpan.textContent = 'me:';
                                senderSpan.style.color = '#93c5fd';
                                div.appendChild(senderSpan);
                                div.appendChild(document.createTextNode(' '));
                            } else {
                                const senderSpan = document.createElement('span');
                                senderSpan.className = 'sender';
                                senderSpan.textContent = msg.sender;
                                div.appendChild(senderSpan);
                                div.appendChild(document.createTextNode(': '));
                            }
                            
                            const contentSpan = document.createElement('span');
                            contentSpan.className = 'content';
                            contentSpan.textContent = msg.content;
                            div.appendChild(contentSpan);
                            
                            messagesContainer.appendChild(div);
                        });
                    } else {
                        const div = document.createElement('div');
                        div.className = 'message notify-system';
                        div.textContent = 'Start a private conversation...';
                        messagesContainer.appendChild(div);
                    }
                    
                    messagesContainer.scrollTop = messagesContainer.scrollHeight;
                }
                
                // Send a private message
                function sendPrivateMessage(sender) {
                    const chatWindow = activeChatWindows[sender];
                    if (!chatWindow) return;
                    
                    const textarea = chatWindow.querySelector('textarea');
                    const content = textarea.value.trim();
                    
                    if (content) {
                        // Send private message to server
                        fetch(`/api/send_private_message?client_id=${clientId}`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                            },
                            body: JSON.stringify({
                                recipient: sender,
                                content: content
                            }),
                        })
                        .then(response => response.json())
                        .then(data => {
                            if (data.success) {
                                // Update private chat messages
                                privateChats[sender] = data.messages;
                                renderPrivateMessages(sender);
                            }
                        })
                        .catch(error => {
                            console.error('Error sending private message:', error);
                        });
                        
                        textarea.value = '';
                    }
                }
        
        // Panel expand/collapse functionality
        const panelExpandToggle = document.getElementById('panel-expand-toggle');
        const panelIframe = document.getElementById('panel-iframe');
        const panelContainer = document.querySelector('.panel-container');
        let isPanelExpanded = false;

        panelExpandToggle.addEventListener('click', () => {
            isPanelExpanded = !isPanelExpanded;
            
            if (isPanelExpanded) {
                // Expand panel
                panelContainer.style.position = 'fixed';
                panelContainer.style.top = '10%';
                panelContainer.style.left = '10%';
                panelContainer.style.width = '80%';
                panelContainer.style.height = '80%';
                panelContainer.style.zIndex = '1010';
                panelIframe.style.height = '100%';
                panelExpandToggle.innerHTML = '⤓';
                panelContainer.style.background = '#1c1c1c';
                panelContainer.style.boxShadow = '0 0 20px rgba(0, 0, 0, 0.5)';
                panelContainer.style.borderRadius = '8px';
            } else {
                // Collapse panel
                panelContainer.style.position = 'relative';
                panelContainer.style.top = 'auto';
                panelContainer.style.left = 'auto';
                panelContainer.style.width = '100%';
                panelContainer.style.height = 'auto';
                panelContainer.style.zIndex = 'auto';
                panelIframe.style.height = '300px';
                panelExpandToggle.innerHTML = '⤢';
                panelContainer.style.background = 'none';
                panelContainer.style.boxShadow = 'none';
            }
        });

        // Client ID for tracking requests
        const clientId = `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
        let lastRequestTime = 0;

        /**
         * Hybrid real-time data synchronization system
         *
         * This implements a dual approach for real-time updates:
         * 1. Primary: SocketIO for immediate push notifications when data changes
         * 2. Fallback: Long polling with adaptive backoff for reliability
         *
         * The combination ensures:
         * - Immediate updates when possible (via SocketIO)
         * - Reliability in all network conditions (via long polling)
         * - Efficient server resource usage (non-blocking on server, adaptive polling on client)
         * - Multiple browser windows can open the chat page simultaneously
         */
        async function fetchData() {
            try {
                // Initial data load
                await fetchChatData();
                
                // Ensure UI is updated with initial data
                renderMessages(messages);
                renderUserList();
                renderEarnings();
                updateStatus();
                renderPrivateChatslist();
                
                // Start long polling as a fallback mechanism
                // SocketIO will be the primary update mechanism
                startLongPolling();
            } catch (error) {
                console.error("Error fetching data:", error);
                // Retry after a short delay
                setTimeout(fetchData, 5000);
            }
        }
        
        // Fetch chat data from the consolidated API endpoint
        async function fetchChatData() {
            try {
                const response = await fetch(`/api/chat?client_id=${clientId}&last_request=${lastRequestTime}`);
                const data = await response.json();
                
                // Update last request time for next poll
                lastRequestTime = data.timestamp;
                
                // If there are no updates, just return the data for retry handling
                if (data.no_update) {
                    return data;
                }
                
                // Update all data
                messages = data.messages || [];
                users = data.users || {};
                earnings = data.earnings || [];
                statusData = data.status || {};
                rtspUrls = data.rtsp_urls || [];
                privateChats = data.private_chats || {};
                
                // Initialize private chats if they exist in the data
                if (privateChats) {
                    for (const sender in privateChats) {
                        if (privateChats[sender] && privateChats[sender].length > 0) {
                            // Add to open chats if not already there
                            if (!openPrivateChats.has(sender)) {
                                openPrivateChats.add(sender);
                            }
                        }
                    }
                }
                
                // Handle unread private messages
                if (data.unread_private_messages) {
                    updateUnreadIndicators(data.unread_private_messages);
                    
                    // Handle unread messages
                    for (const sender in data.unread_private_messages) {
                        if (data.unread_private_messages[sender] > 0 && privateChats[sender] && privateChats[sender].length > 0) {
                            // Add to open chats if not already there
                            if (!openPrivateChats.has(sender)) {
                                openPrivateChats.add(sender);
                                
                                // Open a new chat window if auto-open is enabled
                                if (autoOpenPrivateChats && !activeChatWindows[sender]) {
                                    openPrivateChat(sender);
                                } else if (!activeChatWindows[sender] || activeChatWindows[sender].style.display === 'none') {
                                    // Show notification indicator in the chat list
                                    const chatItem = document.querySelector(`.private-chat-item[data-sender="${sender}"]`);
                                    if (chatItem) {
                                        const indicator = chatItem.querySelector('.notification-indicator');
                                        if (indicator) {
                                            indicator.style.display = 'inline-block';
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                // Always render the private chats list
                renderPrivateChatslist();
                
                // Update UI
                renderMessages(messages);
                renderUserList();
                renderEarnings();
                updateStatus();
                
                // Update private chats list
                renderPrivateChatslist();
                
                return data;
            } catch (error) {
                console.error("Error fetching chat data:", error);
                throw error;
            }
        }
        
        // Adaptive polling with exponential backoff
        let pollBackoffDelay = 1000; // Start with 1 second
        const maxPollBackoffDelay = 10000; // Max 10 seconds
        
        // Start long polling for updates
        function startLongPolling() {
            fetchChatData()
                .then(data => {
                    if (data && data.no_update) {
                        // No updates available, use adaptive backoff
                        pollBackoffDelay = Math.min(pollBackoffDelay * 1.5, maxPollBackoffDelay);
                        const retryAfter = data.retry_after || pollBackoffDelay;
                        console.log(`No updates, next poll in ${retryAfter}ms`);
                        setTimeout(startLongPolling, retryAfter);
                    } else {
                        // Got updates, reset backoff and immediately start the next poll
                        pollBackoffDelay = 1000;
                        startLongPolling();
                    }
                })
                .catch(error => {
                    console.error("Long polling error:", error);
                    // Retry after a short delay
                    setTimeout(startLongPolling, 5000);
                });
        }

        // Initialize SocketIO connection with reconnection options
        const socket = io({
            reconnection: true,
            reconnectionAttempts: Infinity,
            reconnectionDelay: 1000,
            reconnectionDelayMax: 5000,
            timeout: 20000
        });
        
        // Listen for chat updates
        socket.on('chat_update', (data) => {
            console.log('Received update notification:', data);
            
            // If it's a private chat update with specific sender info
            if (data.type === 'private_chats' && data.sender) {
                // Fetch the latest data with priority
                fetchChatData().then(responseData => {
                    // If this update indicates unread messages
                    if (data.has_unread) {
                        const sender = data.sender;
                        
                        // Add to open chats if not already there
                        if (!openPrivateChats.has(sender)) {
                            openPrivateChats.add(sender);
                            renderPrivateChatslist();
                        }
                        
                        // Show indicator in the tab title
                        const tabIndicator = document.getElementById('private-chats-tab-indicator');
                        if (tabIndicator) {
                            tabIndicator.style.display = 'inline-block';
                        }
                        
                        // Check if we should auto-open or just show notification
                        const chatWindow = activeChatWindows[sender];
                        
                        if (!chatWindow) {
                            if (autoOpenPrivateChats) {
                                // Create and open a new chat window if auto-open is enabled
                                openPrivateChat(sender);
                            } else {
                                // Just show notification in the chat list
                                const chatItem = document.querySelector(`.private-chat-item[data-sender="${sender}"]`);
                                if (chatItem) {
                                    const indicator = chatItem.querySelector('.notification-indicator');
                                    if (indicator) {
                                        indicator.style.display = 'inline-block';
                                    }
                                }
                            }
                        } else if (chatWindow.style.display === 'none') {
                            // Window exists but is minimized, show notification in chat list
                            const chatItem = document.querySelector(`.private-chat-item[data-sender="${sender}"]`);
                            if (chatItem) {
                                const indicator = chatItem.querySelector('.notification-indicator');
                                if (indicator) {
                                    indicator.style.display = 'inline-block';
                                }
                            }
                        } else if (!chatWindow.classList.contains('active')) {
                            // Window is open but not focused, show indicator in header
                            const headerIndicator = chatWindow.querySelector('.private-chat-header .notification-indicator');
                            if (headerIndicator) {
                                headerIndicator.style.display = 'inline-block';
                            }
                        }
                        
                        // Update the chat window content if it exists
                        if (chatWindow && privateChats[sender]) {
                            renderPrivateMessages(sender);
                        }
                    } else if (data.has_unread === false) {
                        // This is a "mark as read" update
                        const sender = data.sender;
                        
                        // Hide notification indicators
                        const chatItem = document.querySelector(`.private-chat-item[data-sender="${sender}"]`);
                        if (chatItem) {
                            const indicator = chatItem.querySelector('.notification-indicator');
                            if (indicator) {
                                indicator.style.display = 'none';
                            }
                        }
                        
                        // Check if any other chats have unread messages
                        let anyUnread = false;
                        document.querySelectorAll('.private-chat-item .notification-indicator').forEach(ind => {
                            if (ind.style.display === 'inline-block') {
                                anyUnread = true;
                            }
                        });
                        
                        // Update tab indicator
                        if (!anyUnread) {
                            const tabIndicator = document.getElementById('private-chats-tab-indicator');
                            if (tabIndicator) {
                                tabIndicator.style.display = 'none';
                            }
                        }
                        
                        const chatWindow = activeChatWindows[sender];
                        if (chatWindow) {
                            const headerIndicator = chatWindow.querySelector('.private-chat-header .notification-indicator');
                            if (headerIndicator) {
                                headerIndicator.style.display = 'none';
                            }
                        }
                    }
                });
            } else if (data.type === 'initial_connect') {
                // New connection - fetch all data immediately
                fetchChatData();
            } else {
                // For other updates, just fetch the data
                fetchChatData();
            }
        });
        
        // Handle connection events
        socket.on('connect', () => {
            console.log('SocketIO connected');
        });
        
        socket.on('disconnect', () => {
            console.log('SocketIO disconnected');
        });
        
        socket.on('connect_error', (error) => {
            console.error('SocketIO connection error:', error);
        });
        // Function to update unread message indicators
        function updateUnreadIndicators(unreadCounts) {
            // If unreadCounts is undefined or null, return early
            if (!unreadCounts) return;
            
            // First ensure all private chats are in the list
            let hasAnyUnread = false;
            for (const sender in unreadCounts) {
                if (unreadCounts[sender] > 0 && privateChats[sender] && privateChats[sender].length > 0) {
                    // Add to open chats if not already there
                    if (!openPrivateChats.has(sender)) {
                        openPrivateChats.add(sender);
                        renderPrivateChatslist();
                    }
                    hasAnyUnread = true;
                }
            }
            
            // Update the tab indicator based on whether any chats have unread messages
            const tabIndicator = document.getElementById('private-chats-tab-indicator');
            if (tabIndicator) {
                tabIndicator.style.display = hasAnyUnread ? 'inline-block' : 'none';
            }
            
            // Update indicators in the private chats list
            document.querySelectorAll('.private-chat-item').forEach(item => {
                const sender = item.dataset.sender;
                const indicator = item.querySelector('.notification-indicator');
                
                if (indicator) {
                    if (unreadCounts[sender] && unreadCounts[sender] > 0) {
                        // Show indicator in chat list
                        indicator.style.display = 'inline-block';
                        hasAnyUnread = true;
                        
                        // Also show indicator in chat window header if window exists and is not active
                        const chatWindow = activeChatWindows[sender];
                        if (chatWindow) {
                            if (chatWindow.style.display === 'none' || !chatWindow.classList.contains('active')) {
                                const headerIndicator = chatWindow.querySelector('.private-chat-header .notification-indicator');
                                if (headerIndicator) {
                                    headerIndicator.style.display = 'inline-block';
                                }
                            }
                        }
                    } else {
                        // Hide indicator
                        indicator.style.display = 'none';
                        
                        // Also hide in header
                        const chatWindow = activeChatWindows[sender];
                        if (chatWindow) {
                            const headerIndicator = chatWindow.querySelector('.private-chat-header .notification-indicator');
                            if (headerIndicator) {
                                headerIndicator.style.display = 'none';
                            }
                        }
                    }
                }
            });
        }
        
        // Initialize
        populateVideoSources();
        fetchData();
        
        // Auto-open toggle event listener
        document.getElementById('auto-open-chats').addEventListener('change', function() {
            autoOpenPrivateChats = this.checked;
            console.log(`Auto-open private chats: ${autoOpenPrivateChats ? 'enabled' : 'disabled'}`);
            
            // Save preference to localStorage
            localStorage.setItem('autoOpenPrivateChats', autoOpenPrivateChats);
        });
        
        // Load auto-open preference from localStorage
        if (localStorage.getItem('autoOpenPrivateChats') !== null) {
            autoOpenPrivateChats = localStorage.getItem('autoOpenPrivateChats') === 'true';
            document.getElementById('auto-open-chats').checked = autoOpenPrivateChats;
        }
        
        // Handle window resize to keep chat windows within viewport
        window.addEventListener('resize', () => {
            for (const sender in activeChatWindows) {
                const chatWindow = activeChatWindows[sender];
                if (chatWindow) {
                    // Keep window within viewport bounds
                    const maxX = window.innerWidth - chatWindow.offsetWidth;
                    const maxY = window.innerHeight - chatWindow.offsetHeight;
                    
                    const currentX = parseInt(chatWindow.style.left) || 0;
                    const currentY = parseInt(chatWindow.style.top) || 0;
                    
                    chatWindow.style.left = `${Math.max(0, Math.min(currentX, maxX))}px`;
                    chatWindow.style.top = `${Math.max(0, Math.min(currentY, maxY))}px`;
                }
            }
        });
    </script>
</body>
</html>
