alert("Chookchat is currently in early development, expect bugs! Please don't try breaking the public server, do that with your own test server (read more in the Git repo). Thanks for trying Chookchat!")

let ws;
let username;
let password;
let typingTimeout;
let typingPeople = [];
let currentRoom = "general"; 
let availableRooms = ["general"];
let isMobile = window.innerWidth < 768;
let avatarColors = {};

// Initialize DOM elements when document is ready
document.addEventListener('DOMContentLoaded', function() {
    // Mobile menu toggle
    if (isMobile) {
        const menuToggle = document.createElement('button');
        menuToggle.className = 'btn-icon menu-toggle';
        menuToggle.innerHTML = '<i class="fa-solid fa-bars"></i>';
        menuToggle.addEventListener('click', toggleSidebar);
        
        const chatHeader = document.querySelector('.chat-header');
        if (chatHeader) {
            chatHeader.insertBefore(menuToggle, chatHeader.firstChild);
        }
    }

    document.getElementById('messageInput').addEventListener('input', function () {
        this.style.height = 'auto';
        this.style.height = (this.scrollHeight) + 'px';
    });

    
    // Add event listeners
    document.getElementById('messageInput').addEventListener('keydown', function(event) {
        if (event.key === 'Enter' && !event.shiftKey) {
            event.preventDefault();
            sendMessage();
        }
    });
    
    document.getElementById('password').addEventListener('keypress', (event) => {
        if (event.key === 'Enter') {
            connect();
        }
    });
    
    document.getElementById('messageInput').addEventListener('input', startTypingIndicator);
    
    // File upload preview
    const fileInput = document.getElementById('fileupload');
    if (fileInput) {
        fileInput.addEventListener('change', previewFile);
    }
    
    // Handle window resize
    window.addEventListener('resize', () => {
        isMobile = window.innerWidth < 768;
        if (!isMobile) {
            const sidebar = document.querySelector('.sidebar');
            if (sidebar) {
                sidebar.classList.remove('visible');
            }
        }
    });
});

// Toggle sidebar on mobile
function toggleSidebar() {
    const sidebar = document.querySelector('.sidebar');
    if (sidebar) {
        sidebar.classList.toggle('visible');
    }
}

// Show server config
function showConfig() {
    const serverconfig = document.getElementById('serverconfig');
    if (serverconfig) {
        serverconfig.style.display = serverconfig.style.display === 'block' ? 'none' : 'block';
    }
}

// Hash password using MD5
function md5(string) {
    return CryptoJS.MD5(string).toString();
}

// Get WebSocket URL
function getUrl() {
    const serverUrl = document.getElementById('serverUrl').value.trim();
    const serverPort = document.getElementById('serverPort').value;
    const useWss = document.getElementById('securityStatus').checked;
    const protocol = useWss ? 'wss' : 'ws';

    const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');

    return `${protocol}://${cleanUrl}:${serverPort}/api/websocket`;
}

// Get signup URL
function getSignupUrl() {
    const serverUrl = document.getElementById('serverUrl').value.trim();
    const serverPort = document.getElementById('serverPort').value;
    const useWss = document.getElementById('securityStatus').checked;
    const protocol = useWss ? 'https' : 'http';

    const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');

    return `${protocol}://${cleanUrl}:${serverPort}/api/createaccount/`;
}

// Get upload URL
function getUploadUrl() {
    const serverUrl = document.getElementById('serverUrl').value.trim();
    const serverPort = document.getElementById('serverPort').value;
    const useWss = document.getElementById('securityStatus').checked;
    const protocol = useWss ? 'https' : 'http';

    const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');

    return `${protocol}://${cleanUrl}:${serverPort}/api/upload`;
}

// Get available rooms
async function getRooms() {
    try {
        const serverUrl = document.getElementById('serverUrl').value.trim();
        const serverPort = document.getElementById('serverPort').value;
        const useWss = document.getElementById('securityStatus').checked;
        const protocol = useWss ? 'https' : 'http';
        const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
        const url = `${protocol}://${cleanUrl}:${serverPort}/api/rooms`;
        const response = await fetch(url, {
            mode: "no-cors"
        });
        const data = await response.json();
        return JSON.parse(data.content);
    } catch (error) {
        console.error('Error fetching rooms:', error);
        return ["general"];
    }
}

// Get room message history
async function getRoomHistory(roomName) {
    try {
        const serverUrl = document.getElementById('serverUrl').value.trim();
        const serverPort = document.getElementById('serverPort').value;
        const useWss = document.getElementById('securityStatus').checked;
        const protocol = useWss ? 'https' : 'http';
        const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
        const url = `${protocol}://${cleanUrl}:${serverPort}/api/room/${roomName}/history`;
        const response = await fetch(url, {
            mode: "no-cors"
        });
        const history = await response.text();
        return history;
    } catch (error) {
        console.error('Error fetching room history:', error);
        return '';
    }
}

// Image mime types and extensions
const imageMimeTypes = [
    'image/webp',
    'image/tiff',
    'image/svg+xml',
    'image/png',
    'image/jpeg',
    'image/vnd.microsoft.icon',
    'image/gif',
    'image/bmp',
];

const imageTypes = [
    'png',
    'jpg',
    'jpeg',
    'svg',
    'tiff',
    'gif',
    'webp',
    'bmp'
];

// Check if file is an image
function isImage(file) {
    const fileSplit = file.split(".");
    return imageTypes.includes(fileSplit[fileSplit.length - 1].toLowerCase());
}

// Connect to the server
async function connect() {
    username = document.getElementById('username').value;
    password = document.getElementById('password').value;

    if (!username || !password) {
        alert('Please enter a username and password');
        return;
    }

    const wsUrl = getUrl();
    if (ws) {
        ws.close();
    }

    // Show connecting state
    const loginButton = document.querySelector('.btn-primary');
    if (loginButton) {
        loginButton.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Connecting...';
        loginButton.disabled = true;
    }

    ws = new WebSocket(wsUrl);
    var incorrectDetail = 0;

    ws.onopen = async () => {
        if (typeof Notification !== "undefined") {
            Notification.requestPermission();
        }
        console.log('Connected!');
        
        document.getElementById('login-container').style.display = 'none';
        document.getElementById('app').classList.remove('hidden');
        
        // Set current username in UI
        document.getElementById('current-username').textContent = username;
        
        try {
            availableRooms = await getRooms();
            updateRoomList();
        } catch (error) {
            console.error('Failed to get room list:', error);
            availableRooms = ["general"];
        }
        
        const connectMessage = {
            "type": "connect",
            "username": username,
            "token": md5(password),
            "content": `${username} joined the room!`
        }
        ws.send(JSON.stringify(connectMessage));
        
        joinRoom("general");
        
        ws.onmessage = handleMessage;
    };

    ws.onerror = () => {
        alert("Error connecting to the server. Please check your server settings.");
        resetLoginButton();
    };
    
    ws.onclose = () => {
        if (!incorrectDetail) {
            alert("Chookchat has disconnected. Refresh the page to reconnect.");
        }
        resetLoginButton();
    };
}

// Reset login button state
function resetLoginButton() {
    const loginButton = document.querySelector('.btn-primary');
    if (loginButton) {
        loginButton.innerHTML = 'Log in';
        loginButton.disabled = false;
    }
}

function markdownToHtmlDiv(markdown) {
  // Emoji mapping
  const emojiMap = {
      // 😀 Faces
      smile: '😄',
      happy: '😊',
      grin: '😁',
      laugh: '😂',
      joy: 'ðŸĪĢ',
      wink: '😉',
      blush: '☚ïļ',
      cool: '😎',
      smirk: '😏',
      thinking: 'ðŸĪ”',
      neutral: '😐',
      expressionless: '😑',
      sleepy: 'ðŸ˜ī',
      dizzy: 'ðŸ˜ĩ',
      surprised: 'ðŸ˜ē',
      scream: 'ðŸ˜ą',
      cry: 'ðŸ˜Ē',
      sob: '😭',
      angry: '😠',
      rage: 'ðŸ˜Ą',
      yum: '😋',
      relieved: '😌',
      confused: '😕',
      nerd: 'ðŸĪ“',
      zany: 'ðŸĪŠ',
      shush: 'ðŸĪŦ',
      hush: 'ðŸĪ',

      // âĪïļ Emotions
      heart: 'âĪïļ',
      heartbroken: '💔',
      love: '😍',
      kiss: '😘',
      hug: 'ðŸĪ—',
      clap: '👏',
      pray: '🙏',
      ok: '👌',
      fingerscrossed: 'ðŸĪž',
      thumbsup: '👍',
      thumbsdown: '👎',
      eyes: '👀',

      // ðŸ”Ĩ Reactions
      fire: 'ðŸ”Ĩ',
      100: 'ðŸ’Ŋ',
      poop: 'ðŸ’Đ',
      poo: 'ðŸ’Đ',
      skull: '💀',
      explosion: 'ðŸ’Ĩ',
      mindblown: 'ðŸĪŊ',
      party: 'ðŸĨģ',
      tada: '🎉',
      balloon: '🎈',

      // ðŸķ Animals
      chicken: '🐔',
      dog: 'ðŸķ',
      cat: 'ðŸą',
      fox: 'ðŸĶŠ',
      panda: '🐞',
      pig: '🐷',
      cow: 'ðŸŪ',
      rabbit: '🐰',
      bear: 'ðŸŧ',
      unicorn: 'ðŸĶ„',
      monkey: '🐒',
      dragon: '🐉',
      snake: '🐍',

      // 🍔 Food & Drink
      pizza: '🍕',
      burger: '🍔',
      fries: '🍟',
      hotdog: '🌭',
      taco: 'ðŸŒŪ',
      ramen: '🍜',
      sushi: 'ðŸĢ',
      icecream: 'ðŸĻ',
      cake: '🎂',
      coffee: '☕',
      tea: 'ðŸĩ',
      beer: '🍚',

      // 🌍 Nature & Weather
      sun: '☀ïļ',
      moon: '🌙',
      star: '⭐',
      cloud: '☁ïļ',
      rain: '🌧ïļ',
      snow: '❄ïļ',
      lightning: '⚡',
      rainbow: '🌈',
      tree: 'ðŸŒģ',
      flower: 'ðŸŒļ',

      // âš― Activities
      soccer: 'âš―',
      basketball: '🏀',
      football: '🏈',
      baseball: 'âšū',
      tennis: 'ðŸŽū',
      bowling: 'ðŸŽģ',
      video_game: 'ðŸŽŪ',
      chess: '♟ïļ',
      music: 'ðŸŽĩ',
      guitar: 'ðŸŽļ',
      mic: 'ðŸŽĪ',

      // ðŸ’Ą Objects & Symbols
      lightbulb: 'ðŸ’Ą',
      phone: 'ðŸ“ą',
      laptop: 'ðŸ’ŧ',
      bomb: 'ðŸ’Ģ',
      money: '💰',
      star2: '🌟',
      warning: '⚠ïļ',
      check: '✅',
      x: '❌',
      question: '❓',
      exclamation: '❗',
      infinity: 'â™ūïļ',
      hourglass: 'âģ',
      clock: '🕒',

      pepe: 'ðŸļ',
      troll: '😈',
      sus: '🧐',
      amongus: 'ðŸŸĨ',
      monke: 'ðŸĩ',
      chad: 'ðŸĶ',
      gigachad: '💊',
      wojak: '😔',
      feelsbadman: '😞',
      feelsgoodman: '😌',
      yikes: '😎',
      clown: 'ðŸĪĄ',
      clownworld: '🌎ðŸĪĄ',
      triggered: 'ðŸ˜Ą',
      pog: 'ðŸ˜ē',
      kek: 'ðŸĪĢ',
      based: '😎',
      cringe: '😖',
      dab: '🕚',
      sigma: '🧠',
      npc: 'ðŸĪ–',
      doomer: '🌑',
      zoomer: '⚡',
      boomer: 'ðŸ‘ī',
      sheesh: 'ðŸ˜Ī',
      rickroll: '🕚ðŸŽķ',
      trolled: '🧌',
      rekt: '💀',
      skillissue: '📉',
      bro: '🙄',
      cope: 'ðŸ˜Ē',
      ratio: '➗',
      amogus: '👁ïļðŸ‘„👁ïļ',

};

  // Escape HTML first
  let html = markdown
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');

  // Code blocks (```...```)
  html = html.replace(/```([^```]*)```/gs, (match, p1) =>
    `<pre><code>${p1.trim()}</code></pre>`
  );

  // Inline code (`code`)
  html = html.replace(/`([^`\n]+)`/g, (match, p1) => `<code>${p1}</code>`);

  // Emojis :emoji_name:
  html = html.replace(/:([a-z0-9_]+):/gi, (match, p1) => emojiMap[p1] || match);

  // Process overlapping formatting in order: Bold+Underline+Italic
  html = parseFormatting(html);

  // Replace line breaks
  html = html.replace(/\n/g, '<br>');

  return html;
}

// Parse overlapping formatting using tokens
function parseFormatting(text) {
  // Define replacement tokens and their HTML
  const formattingRules = [
    { regex: /\*\*\*(.*?)\*\*\*/g, html: '<strong><em>$1</em></strong>' }, // ***bold italic***
    { regex: /___(.*?)___/g, html: '<u><em>$1</em></u>' },                 // ___underline italic___
    { regex: /\*\*(.*?)\*\*/g, html: '<strong>$1</strong>' },             // **bold**
    { regex: /__(.*?)__/g, html: '<u>$1</u>' },                           // __underline__
    { regex: /\*(.*?)\*/g, html: '<em>$1</em>' },                         // *italic*
    { regex: /_(.*?)_/g, html: '<em>$1</em>' },                           // _italic_
    { regex: /~~(.*?)~~/g, html: '<s>$1</s>' }                            // ~~strike~~
  ];

  // Apply formatting in order
  for (const rule of formattingRules) {
    text = text.replace(rule.regex, rule.html);
  }

  return text;
}


// Handle incoming messages
function handleMessage(event) {
    if (event.data === "ping") {
        ws.send("pong");
        return;
    }
    
    const message = JSON.parse(event.data);
    
    // Handle error messages
    if (message.type == "error") {
        if (message.username == "system") {
            if (message.content == "invalid-token") {
                alert("Your password is incorrect! Please try again.");
                location.reload();
                return;
            }
            if (message.content == "unknown-account") {
                alert("That username isn't on the server. Maybe try registering?");
                location.reload();
                return;
            }
            if (message.content == "banned") {
                alert("You've been banned from the server.");
                location.reload();
                return;
            }
        }
    }
    
    // Handle typing indicators
    else if (message.type == "typing") {
        handleTypingIndicator(message);
        return;
    }
    
    // Handle users list
    else if (message.type == "users" && message.username == "system") {
        updateOnlineUsers(message.content);
        return;
    }
    
    // Handle room users
    else if (message.type == "roomUsers" && message.username == "system") {
        updateRoomUsers(message);
        return;
    }
    
    // Handle rooms list
    else if (message.type == "roomsList" && message.username == "system") {
        try {
            availableRooms = JSON.parse(message.content);
            updateRoomList();
        } catch (error) {
            console.error('Error parsing rooms list:', error);
        }
        return;
    }
    
    // Handle room created or joined
    else if (message.type == "roomCreated" || message.type == "roomJoin") {
        handleRoomChange(message);
        return;
    }
    
    // Handle file messages
    else if (message.type == "file") {
        handleFileMessage(message);
        return;
    }
    
    // Handle call messages
    else if (message.type == "call") {
        handleCallMessage(message);
        return;
    }
    
    // Handle connect messages
    else if (message.type == "connect") {
        addSystemMessage(message.content);
        
        if (document.hidden) {
            new Notification("Chookchat", {body: message.content});
        }
    }
    
    // Handle regular messages
    else if (message.type == "message") {
        if (message.room && message.room !== currentRoom) {
            // Highlight room with unread message
            highlightRoom(message.room);
            return;
        }
        
        addChatMessage(message.username, message.content);
        
        if (document.hidden) {
            new Notification("Chookchat", {
                body: `${message.username}: ${message.content}`
            });
        }
    }
}

// Handle typing indicator updates
function handleTypingIndicator(message) {
    if (message.content == "1") {
        if (username !== message.username && !typingPeople.includes(message.username)) {
            typingPeople.push(message.username);
            updatePeopleTyping();
        }
    } else if (message.content == "0") {
        if (username !== message.username && typingPeople.includes(message.username)) {
            const index = typingPeople.indexOf(message.username);
            typingPeople.splice(index, 1);
            updatePeopleTyping();
        }
    }
}

// Update online users display
function updateOnlineUsers(usersList) {
    const usersPanel = document.querySelector('.users-list');
    if (usersPanel) {
        usersPanel.innerHTML = '';
        
        const users = usersList.split(', ');
        users.forEach(user => {
            addUserToPanel(user);
        });
    }
}

// Update room users display
function updateRoomUsers(message) {
    const usersInRoom = message.content;
    const roomName = message.room;
    
    // Update current room if needed
    if (roomName !== currentRoom) {
        currentRoom = roomName;
        updateCurrentRoomDisplay();
    }
    
    // Update users panel
    const usersPanel = document.querySelector('.users-list');
    if (usersPanel) {
        usersPanel.innerHTML = '';
        
        const users = usersInRoom.split(', ');
        users.forEach(user => {
            addUserToPanel(user);
        });
    }
}

// Add user to the users panel
function addUserToPanel(user) {
    const usersPanel = document.querySelector('.users-list');
    if (!usersPanel) return;
    
    const userItem = document.createElement('div');
    userItem.className = 'user-item';
    
    // Create user avatar
    const userAvatar = document.createElement('div');
    userAvatar.className = 'user-avatar';
    userAvatar.style.backgroundColor = getUserColor(user);
    userAvatar.textContent = user.charAt(0).toUpperCase();
    
    // Create user name
    const userName = document.createElement('div');
    userName.className = 'user-name';
    userName.textContent = user;
    
    userItem.appendChild(userAvatar);
    userItem.appendChild(userName);
    usersPanel.appendChild(userItem);
}

// Handle room change
function handleRoomChange(message) {
    if (message.room) {
        currentRoom = message.room;
        updateCurrentRoomDisplay();
        clearMessages();
        loadRoomHistory(currentRoom);                 
        updateRoomList();
    }
    
    // Display system message
    addSystemMessage(message.content);
}

// Handle file messages
function handleFileMessage(message, isHistory = false) {
    // Only show file if it's for current room
    if (message.room && message.room !== currentRoom) {
        highlightRoom(message.room);
        return;
    }
    
    const messagesDiv = document.getElementById('messagebox');
    if (!messagesDiv) return;
    
    const messageWrapper = document.createElement('div');
    messageWrapper.className = 'message';
    if (isHistory) messageWrapper.classList.add('history-message');
    
    // Create avatar
    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.style.backgroundColor = getUserColor(message.username);
    avatar.textContent = message.username.charAt(0).toUpperCase();
    
    // Create message content
    const contentDiv = document.createElement('div');
    contentDiv.className = 'message-content';
    
    // Add message header with username
    const headerDiv = document.createElement('div');
    headerDiv.className = 'message-header';
    
    const authorSpan = document.createElement('span');
    authorSpan.className = 'message-author';
    authorSpan.textContent = message.username;
    
    const timestampSpan = document.createElement('span');
    timestampSpan.className = 'message-timestamp';
    timestampSpan.textContent = isHistory ? 'History' : new Date().toLocaleTimeString();
    
    headerDiv.appendChild(authorSpan);
    headerDiv.appendChild(timestampSpan);
    contentDiv.appendChild(headerDiv);
    
    let filename = message.content.replace("https://maxwellj.xyz/chookchat/uploads/", "");
    
    if (isImage(filename)) {
        // Image file
        const imageMessage = document.createElement('div');
        imageMessage.className = 'image-message';
        
        const imagePreview = document.createElement('img');
        imagePreview.src = message.content;
        imagePreview.alt = filename;
        imagePreview.addEventListener("click", function() {
            window.open(message.content, "_blank");
        });
        
        imageMessage.appendChild(imagePreview);
        contentDiv.appendChild(imageMessage);
    } else {
        // Other file type
        const fileMessage = document.createElement('div');
        fileMessage.className = 'file-message';
        
        const fileIcon = document.createElement('i');
        fileIcon.className = 'file-icon fa-solid fa-file';
        
        const fileName = document.createElement('span');
        fileName.className = 'file-name';
        fileName.textContent = filename;
        
        const fileButton = document.createElement('button');
        fileButton.className = 'file-button';
        fileButton.textContent = 'Open';
        fileButton.addEventListener("click", function() {
            window.open(message.content, "_blank");
        });
        
        fileMessage.appendChild(fileIcon);
        fileMessage.appendChild(fileName);
        fileMessage.appendChild(fileButton);
        contentDiv.appendChild(fileMessage);
    }
    
    messageWrapper.appendChild(avatar);
    messageWrapper.appendChild(contentDiv);
    messagesDiv.appendChild(messageWrapper);
    messagesDiv.scrollTop = messagesDiv.scrollHeight;
}

// Handle call messages
function handleCallMessage(message) {
    if (message.room && message.room !== currentRoom) {
        highlightRoom(message.room);
        return;
    }
    
    const messagesDiv = document.getElementById('messagebox');
    if (!messagesDiv) return;
    
    const callNotification = document.createElement('div');
    callNotification.className = 'call-notification';
    callNotification.innerHTML = `<i class="fa-solid fa-phone"></i> ${message.username} started a call. Click to join!`;
    callNotification.addEventListener('click', () => {
        window.open(message.content, '_blank');
    });
    
    messagesDiv.appendChild(callNotification);
    messagesDiv.scrollTop = messagesDiv.scrollHeight;
}

// Add a system message
function addSystemMessage(content, isHistory = false) {
    const messagesDiv = document.getElementById('messagebox');
    if (!messagesDiv) return;
    
    const messageElement = document.createElement('div');
    messageElement.className = 'system-message';
    if (isHistory) messageElement.classList.add('history-message');
    messageElement.textContent = content;
    
    messagesDiv.appendChild(messageElement);
    messagesDiv.scrollTop = messagesDiv.scrollHeight;
}

// Add a chat message
function addChatMessage(author, content, isHistory = false) {
    const messagesDiv = document.getElementById('messagebox');
    if (!messagesDiv) return;
    
    const messageWrapper = document.createElement('div');
    messageWrapper.className = 'message';
    if (isHistory) messageWrapper.classList.add('history-message');
    
    // Create avatar
    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.style.backgroundColor = getUserColor(author);
    avatar.textContent = author.charAt(0).toUpperCase();
    
    // Create message content
    const contentDiv = document.createElement('div');
    contentDiv.className = 'message-content';
    
    // Add message header with username
    const headerDiv = document.createElement('div');
    headerDiv.className = 'message-header';
    
    const authorSpan = document.createElement('span');
    authorSpan.className = 'message-author';
    authorSpan.textContent = author;
    
    const timestampSpan = document.createElement('span');
    timestampSpan.className = 'message-timestamp';
    timestampSpan.textContent = isHistory ? 'History' : new Date().toLocaleTimeString();
    
    headerDiv.appendChild(authorSpan);
    headerDiv.appendChild(timestampSpan);
    contentDiv.appendChild(headerDiv);
    
    // Add message text
    const textDiv = document.createElement('div');
    textDiv.className = 'message-text';
    textDiv.innerHTML = markdownToHtmlDiv(content);
    contentDiv.appendChild(textDiv);
    
    messageWrapper.appendChild(avatar);
    messageWrapper.appendChild(contentDiv);
    messagesDiv.appendChild(messageWrapper);
    messagesDiv.scrollTop = messagesDiv.scrollHeight;
}

// Highlight a room with unread messages
function highlightRoom(roomName) {
    const roomItems = document.querySelectorAll('.room-item');
    roomItems.forEach(item => {
        if (item.dataset.room === roomName && !item.classList.contains('active')) {
            item.classList.add('unread');
        }
    });
}

// Create a new room
async function createRoom(roomName) {
    const message = {
        type: 'createRoom',
        username: username,
        token: md5(password),
        room: roomName,
        content: ""
    };
    ws.send(JSON.stringify(message));  
    setTimeout(updateRoomList, 500);
}

// Join a room
async function joinRoom(roomName) {
    if (roomName === currentRoom) {
        const usersMessage = {
            type: 'getUsersInRoom',
            username: username,
            token: md5(password),
            room: roomName,
            content: ""
        };
        ws.send(JSON.stringify(usersMessage));
        return;
    }
    
    const message = {
        type: 'joinRoom',
        username: username,
        token: md5(password),
        room: roomName,
        content: ""
    };
    ws.send(JSON.stringify(message));
}

// Send a message
function sendMessage() {
    const messageInput = document.getElementById('messageInput');
    const message = messageInput.value.trim();

    if (!message) return;

    const processedMessage = {
        "type": "message",
        "username": username,
        "token": md5(password),
        "room": currentRoom,
        "content": message
    }

    if (ws && ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify(processedMessage));
        messageInput.value = '';

        if (typingTimeout) {
            clearTimeout(typingTimeout);
        }
        const stoppedTypingMessage = {
            "type": "typing",
            "username": username,
            "token": md5(password),
            "room": currentRoom,
            "content": "0"
        };
        if (ws && ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify(stoppedTypingMessage));
        }
    }
}

// Show file upload modal
function showFileUpload() {
    const uploadModal = document.getElementById("upload-modal");
    if (uploadModal) {
        uploadModal.classList.remove("hidden");
    }
}

// Hide file upload modal
function hideFileUpload() {
    const uploadModal = document.getElementById("upload-modal");
    if (uploadModal) {
        uploadModal.classList.add("hidden");
    }
    
    // Clear file input
    const fileInput = document.getElementById("fileupload");
    if (fileInput) {
        fileInput.value = "";
    }
    
    // Clear preview
    const previewDiv = document.getElementById("upload-preview");
    if (previewDiv) {
        previewDiv.innerHTML = "";
    }
}

// Preview file before upload
function previewFile() {
    const fileInput = document.getElementById("fileupload");
    const previewDiv = document.getElementById("upload-preview");
    
    if (!fileInput || !previewDiv) return;
    
    previewDiv.innerHTML = "";
    
    if (!fileInput.files.length) return;
    
    const file = fileInput.files[0];
    const fileName = file.name;
    
    if (file.type.startsWith('image/')) {
        const img = document.createElement("img");
        img.file = file;
        previewDiv.appendChild(img);
        
        const reader = new FileReader();
        reader.onload = (e) => { img.src = e.target.result; };
        reader.readAsDataURL(file);
    } else {
        const fileInfo = document.createElement("div");
        fileInfo.innerHTML = `<i class="fa-solid fa-file"></i> ${fileName} (${formatFileSize(file.size)})`;
        previewDiv.appendChild(fileInfo);
    }
}

// Format file size
function formatFileSize(bytes) {
    if (bytes < 1024) return bytes + ' bytes';
    else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
    else return (bytes / 1048576).toFixed(1) + ' MB';
}

// Upload a file
async function uploadFile() {
    const fileInput = document.getElementById("fileupload");
    if (!fileInput.files.length) {
        alert("Please select a file to upload");
        return;
    }
    
    // Check file size
    if (fileInput.files[0].size > 10485760) {
        alert("File is too large. Maximum size is 10MB.");
        return;
    }
    
    // Update button state
    const uploadButton = document.querySelector('#upload-modal .btn-primary');
    if (uploadButton) {
        uploadButton.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Uploading...';
        uploadButton.disabled = true;
    }
    
    const formData = new FormData();
    formData.append("file", fileInput.files[0]);
    formData.append("room", currentRoom); 
    formData.append("username", username);
    formData.append("token", md5(password));
    
    try {
        const response = await fetch(getUploadUrl(), {
            method: 'POST',
            mode: "no-cors",
            body: formData
        });
        
        if (response.ok) {
            hideFileUpload();
        } else {
            alert("Failed to upload file. Please try again.");
        }
    } catch (error) {
        alert("Error uploading file: " + error.message);
    }
    
    // Reset button state
    if (uploadButton) {
        uploadButton.innerHTML = 'Upload';
        uploadButton.disabled = false;
    }
}

// Start typing indicator
function startTypingIndicator() {
    if (typingTimeout) {
        clearTimeout(typingTimeout);
    }

    const typingMessage = {
        "type": "typing",
        "username": username,
        "token": md5(password),
        "room": currentRoom,
        "content": "1"
    };

    if (ws && ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify(typingMessage));
    }

    typingTimeout = setTimeout(() => {
        const stoppedTypingMessage = {
            "type": "typing",
            "username": username,
            "token": md5(password),
            "room": currentRoom,
            "content": "0"
        };

        if (ws && ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify(stoppedTypingMessage));
        }
    }, 5000);
}

// Update typing indicator display
function updatePeopleTyping() {
    const typingDiv = document.getElementById('typing');
    if (typingDiv) {
        if (typingPeople.length === 0) {
            typingDiv.textContent = '';
        } else if (typingPeople.length === 1) {
            typingDiv.innerHTML = `<i class="fa-solid fa-keyboard"></i> ${typingPeople[0]} is typing...`;
        } else if (typingPeople.length === 2) {
            typingDiv.innerHTML = `<i class="fa-solid fa-keyboard"></i> ${typingPeople[0]} and ${typingPeople[1]} are typing...`;
        } else {
            typingDiv.innerHTML = `<i class="fa-solid fa-keyboard"></i> ${typingPeople.length} people are typing...`;
        }
    }
}

// Generate random string for Jitsi meeting
function generateRandomString(length) {
    const characters ='abcdefghijklmnopqrstuvwxyz';
    let result = '';
    const charactersLength = characters.length;
    for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
}

// Start a Jitsi meeting
function startMeeting() {
    const link = `https://meet.jit.si/chookchat-${generateRandomString(15)}`;
    
    const processedMessage = {
        "type": "call",
        "username": username,
        "token": md5(password),
        "room": currentRoom,
        "content": link
    };
    
    if (ws && ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify(processedMessage));
        window.open(link, '_blank');
    } else {
        alert("Something went wrong. Refresh the page and try again.");
    }
}

// Update the room list UI
async function updateRoomList() {
    const roomListDiv = document.getElementById('room-list');
    if (!roomListDiv) return;
    
    try {
        availableRooms = await getRooms();
    } catch (error) {
        console.error('Error updating room list:', error);
    }
    
    // Clear existing rooms except category header
    const roomCategory = roomListDiv.querySelector('.room-category');
    if (roomCategory) {
        const header = roomCategory.querySelector('.room-category-header');
        roomCategory.innerHTML = '';
        if (header) roomCategory.appendChild(header);
        
        // Add room items
        availableRooms.forEach(room => {
            const roomElement = document.createElement('div');
            roomElement.className = `room-item ${room === currentRoom ? 'active' : ''}`;
            roomElement.dataset.room = room;
            roomElement.innerHTML = `<i class="fa-solid fa-hashtag"></i> ${room}`;
            roomElement.addEventListener('click', () => joinRoom(room));
            roomCategory.appendChild(roomElement);
        });
    }
}

// Update current room display
function updateCurrentRoomDisplay() {
    const roomNameElement = document.getElementById('current-room-name');
    if (roomNameElement) {
        roomNameElement.textContent = currentRoom;
    }
    
    // Update active state in room list
    const roomItems = document.querySelectorAll('.room-item');
    roomItems.forEach(item => {
        if (item.dataset.room === currentRoom) {
            item.classList.add('active');
            item.classList.remove('unread');
        } else {
            item.classList.remove('active');
        }
    });
}

// Clear message display
function clearMessages() {
    const messagebox = document.getElementById('messagebox');
    if (messagebox) {
        messagebox.innerHTML = '';
    }
}

// Load room message history
async function loadRoomHistory(roomName) {
    try {
        const history = await getRoomHistory(roomName);
        const jHistory = JSON.parse(history);

        
        if (history) {
            const messagebox = document.getElementById('messagebox');
            jHistory.forEach(function (message, index) {          
                // Handle file messages
                if (message.type == "file") {
                    handleFileMessage(message, true);
                    return;
                }
    
                // Handle call messages
                else if (message.type == "call") {
                    handleCallMessage(message);
                    return;
                }
                // Handle regular messages
                else if (message.type == "message") {
                    if (message.room && message.room !== currentRoom) {
                        // Highlight room with unread message
                        highlightRoom(message.room);
                        return;
                    }
                    addChatMessage(message.username, message.content, true);
                }
            });
                /*
            const lines = history.split('\n');
            
            lines.forEach(line => {
                if (line.trim()) {
                    // Parse history line to extract username and message
                    const historyMatch = line.match(/^(.*?):\s(.*)$/);
                    
                    if (historyMatch && historyMatch.length >= 3) {
                        // If it's a regular message format (username: message)
                        const historyUsername = historyMatch[1].trim();
                        const historyContent = historyMatch[2].trim();
                        addChatMessage(historyUsername, historyContent, true);
                    } else if (line.includes("joined") || line.includes("left") || line.includes("created")) {
                        // System messages
                        addSystemMessage(line, true);
                    } else {
                        // Fallback for any other format
                        addSystemMessage(line, true);
                    }
                }
            });*/
            
            messagebox.scrollTop = messagebox.scrollHeight;
        }
    } catch (error) {
        console.error('Error loading room history:', error);
    }
}

// Prompt to create a new room
function promptCreateRoom() {
    const roomName = prompt('Enter a name for the new room:');
    if (roomName && roomName.trim()) {
        createRoom(roomName.trim());
    }
}

// Show eggs panel
function showEggs() {
    const eggsPanel = document.getElementById('eggs-panel');
    if (eggsPanel) {
        eggsPanel.classList.remove('hidden');
        eggsPanel.classList.add('visible');
    }
}

// Close eggs panel
function closeEggs() {
    const eggsPanel = document.getElementById('eggs-panel');
    if (eggsPanel) {
        eggsPanel.classList.remove('visible');
        setTimeout(() => {
            eggsPanel.classList.add('hidden');
        }, 200);
    }
}

// Get or generate consistent user color
function getUserColor(username) {
    if (!avatarColors[username]) {
        // Generate a color based on username
        const hue = Math.abs(hashString(username) % 360);
        avatarColors[username] = `hsl(${hue}, 70%, 60%)`;
    }
    return avatarColors[username];
}

// Simple string hash function
function hashString(str) {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
        hash = ((hash << 5) - hash) + str.charCodeAt(i);
        hash |= 0; // Convert to 32bit integer
    }
    return hash;
}

// Register a new account
async function doRegister(username, password) {
    return fetch(`${getSignupUrl()}username:{${username}}token:{${md5(password)}}`)
        .then(response => response.json())
        .then(responseJson => responseJson);
}

// Register handler
async function register() {
    username = document.getElementById('username').value;
    password = document.getElementById('password').value;

    if (!username || !password) {
        alert('Please enter a username and password');
        return;
    }
    
    // Update button state
    const registerButton = document.querySelector('.btn-success');
    if (registerButton) {
        registerButton.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Registering...';
        registerButton.disabled = true;
    }

    try {
        const response = await doRegister(username, password);
        if (response.type == "success") {
            alert("Account created! Click 'Log in' to access Chookchat!");
        } else {
            alert(`We couldn't create your account: ${response.content}`);
        }
    } catch (error) {
        alert("Error registering account: " + error.message);
    }
    
    // Reset button state
    if (registerButton) {
        registerButton.innerHTML = 'Register';
        registerButton.disabled = false;
    }
}

// Notepad egg
function eggNotepad() {
    const eggContent = document.getElementById('egg-content');
    if (eggContent) {
        eggContent.innerHTML = `
            <div class="notepad-container">
                <textarea class="notepad-textarea" placeholder="Type your notes here..."></textarea>
                <div class="notepad-actions">
                    <button class="btn btn-primary" onclick="saveNotepad()">Save</button>
                    <button class="btn btn-danger" onclick="clearNotepad()">Clear</button>
                </div>
            </div>
        `;
        
        // Load saved content if available
        const savedNote = localStorage.getItem('chookchat-notepad');
        if (savedNote) {
            eggContent.querySelector('.notepad-textarea').value = savedNote;
        }
    }
}

// Save notepad content
function saveNotepad() {
    const textarea = document.querySelector('.notepad-textarea');
    if (textarea) {
        localStorage.setItem('chookchat-notepad', textarea.value);
        alert('Notes saved!');
    }
}

// Clear notepad content
function clearNotepad() {
    const textarea = document.querySelector('.notepad-textarea');
    if (textarea && confirm('Are you sure you want to clear your notes?')) {
        textarea.value = '';
        localStorage.removeItem('chookchat-notepad');
    }
}

// File upload size validation
const uploadField = document.getElementById("fileupload");
if (uploadField) {
    uploadField.onchange = function() {
        if (this.files[0] && this.files[0].size > 10485760) {
            alert("File is too large. Maximum size is 10MB.");
            this.value = "";
        }
    };
}