
function get_room(name, token, on_history, on_message){

    const ws = new WebSocket(`ws://localhost:3000?room=${name}&token=${token}`);
    var status = 'pending';
    const connection = new Promise((resolve)=>{
        ws.onopen = function(){
            status = 'connected';
            resolve(true)
        }
        ws.onerror = function(){
            status = 'error';
            resolve(false)
        }   
    });

    ws.onclose = function(){
        status = 'closed';
    }
    ws.onmessage = (event) => {
       const message = JSON.parse(event.data);  
        if(message instanceof Array){
            on_history(message)
        }else{
            on_message(message)
        }
    }

    return {
        send(message){
            ws.send(JSON.stringify(message));
        },
        wait_connection(){
            return connection;
        },
        is_connected(){
            return status === 'connected';
        },
        close(){
            ws.close()
        }
    }
}

function get_utc_date(){
    return new Date().toLocaleTimeString('en-US', { hour12:false, hour: '2-digit', minute: '2-digit', timeZone: 'UTC', timeZoneName: 'short' })
}

function get_session() {
    let name = "session=";
    let decodedCookie = decodeURIComponent(document.cookie);
    let ca = decodedCookie.split(';');
    for (let i = 0; i < ca.length; i++) {
        let c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

async function get_user() {
    const session = get_session()
    if (!session) return null;
    try {
        const response = await fetch('https://api.github.com/user', {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${session}`,
                'Accept': 'application/json'
            }
        })
        return await response?.json()
    } catch (err) {
        console.error(err);
        return null;
    }
}

function request_login(){
    return document.location.href = 'https://github.com/login/oauth/authorize?scope=user:email&client_id=9481803176fb73d616b7';
}
let current_room = null;
let last_room_name = 'general';
async function send_message(event){
    if(event && event.key?.toLowerCase() !== 'enter') return;
    
    const message = document.querySelector("#chat-message");
    await current_room?.wait_connection();
    if(current_room?.is_connected()){
        current_room.send({
            text: message.value,
            datetime: get_utc_date()
        })
        //clean
        message.value = ''
    }else {
        await open_room(last_room_name)
        send_message();
    }
}

async function open_room(name){
    last_room_name = name;
    current_room?.close()
    
    const user = await get_user();
    if(!user){
        return request_login();
    }
    const chat = document.querySelector('.chat-messages');
    
    const room = get_room(name, get_session(), (history)=> {
        //clear
        chat.innerHTML = '';
        //add messages
        for(let message of history){
            chat.appendChild(format_message(message, user));
        }
        chat.scroll(0, chat.scrollHeight)
    }, (message)=>{
        //add message
        chat.appendChild(format_message(message, user));

        //trim size
        while(chat.childNodes.length > 100){
            chat.firstChild.remove();
        }
        chat.scroll(0, chat.scrollHeight)
    });
    await room.wait_connection()
    current_room = room;
}
const markdown = new showdown.Converter({simpleLineBreaks: true,openLinksInNewWindow: true, emoji: true, ghMentions: true, tables: true, strikethrough: true, tasklists: true});

function format_message(message, user){
    const message_element = document.createElement("div");
    if(message.login === user.login){
        message.name = 'You';
        message_element.classList.add('chat-message-right');
    }else{
        message.name = message.name || message.login;
        message_element.classList.add('chat-message-left'); 
    }
    
    message_element.classList.add('pb-4');
    
    const header = document.createElement("div");
    image = new Image(40, 40);
    image.src = message.avatar_url;
    image.classList.add('rounded-circle');
    image.classList.add('mr-1');
    image.alt = message.name;

    const date = document.createElement("div");
    date.classList.add('text-muted');
    date.classList.add('small');
    date.classList.add('text-nowrap');
    date.classList.add('mt-2');
    date.textContent = message.datetime;
    header.addEventListener("click", ()=> {
        window.open(message.html_url, '_blank').focus();
    });
    header.appendChild(image);
    header.appendChild(date);

    message_element.appendChild(header);

    const body = document.createElement("div");
    body.classList.add('flex-shrink-1');
    body.classList.add('bg-light');
    body.classList.add('rounded');
    body.classList.add('py-2');
    body.classList.add('px-3');
    body.classList.add('mr-3');
    
    const author = document.createElement("div")
    author.classList.add('font-weight-bold');
    author.classList.add('mb-1');
    author.textContent = message.name;
    
    
    body.appendChild(author);
    const content = document.createElement("div");
    content.innerHTML = markdown.makeHtml(message.text);
    body.appendChild(content);
    
    message_element.appendChild(body);

    return message_element;
}

get_user().then((is_logged_in)=>{
    if(is_logged_in){
         open_room("general");
    }
 }); 