{% extends "app.html" %}

{% block header_text %}<h2>{{ name }}</h2>{% endblock %} 

{% block main %}
<section class="chat-area" id="chat">
    <div class="chat-messages">
        {% for message in messages %}
            {% autoescape false %}
            {{ message.html }}
            {% endautoescape %}
        {% endfor %}
    </div>
    <chat-window style="display:none" class="chat-area"></chat-window>
    <div class="chat-input">
        <textarea placeholder="Type a message..." rows="2"></textarea>
        <upload-button channel="{{ channel.uid.value }}"></upload-button>
    </div>
</section>

<script type="module">
    import { app } from "/app.js";

    const channelUid = "{{ channel.uid.value }}";

    function getInputField(){
        return document.querySelector("textarea")
    }
        
    function initInputField(textBox) {
        textBox.addEventListener('change', (e) => {
            e.preventDefault();
            this.dispatchEvent(new CustomEvent('change', { detail: e.target.value, bubbles: true }));
        });

        textBox.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                const message = e.target.value.trim();
                if (message) {
                    app.rpc.sendMessage(channelUid, message);
                    e.target.value = '';
                }
            }
        });
        textBox.focus();
    }

    function replyMessage(message) {
        const field = getInputField() 
        field.value = "```markdown\n> " + (message || '') + "\n```\n";
        field.focus();
    }

    function updateTimes() {
        document.querySelectorAll(".time").forEach((container) => {
            const messageDiv = container.closest('.message');
            const userNick = messageDiv.dataset.user_nick;
            const text = messageDiv.querySelector(".text").innerText;
            const time = document.createElement("span");
            time.innerText = app.timeDescription(container.dataset.created_at);
            
            container.replaceChildren(time);
            const reply = document.createElement("a");
            reply.innerText = " reply";
            reply.href = "#reply";
            container.appendChild(reply);
            reply.addEventListener('click', (e) => {
                e.preventDefault();
                replyMessage(text);
            })
        });
    }

    function isElementVisible(element) {
        const rect = element.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }
    
    const messagesContainer = document.querySelector(".chat-messages");

    function isScrolledPastHalf() {
        let scrollTop = messagesContainer.scrollTop;
        let scrollableHeight = messagesContainer.scrollHeight - messagesContainer.clientHeight;

        if (scrollTop < scrollableHeight / 2) {
            return true;
        }
        return false;
    }

    let isLoadingExtra = false;

    async function loadExtra() {
        const firstMessage = messagesContainer.querySelector(".message:first-child");
        if (isLoadingExtra) {
            return;
        }
        if (!isScrolledPastHalf()) {
           return;
        }
        
        isLoadingExtra = true;
        
        const messages = await app.rpc.getMessages(channelUid, 0, firstMessage.dataset.created_at);

        messages.forEach((message) => {
            firstMessage.insertAdjacentHTML("beforebegin", message.html);
        })
        updateLayout(false);

        isLoadingExtra = false;
    }

    messagesContainer.addEventListener("scroll", () => {
        loadExtra();
    });

    let lastMessage

    function updateLayout(doScrollDown) {
        const messagesContainer = document.querySelector(".chat-messages");
        updateTimes();
        let previousUser = null;
        document.querySelectorAll(".message").forEach((message) => {
            if (previousUser !== message.dataset.user_uid) {
                message.classList.add("switch-user");
                previousUser = message.dataset.user_uid;
            } else {
                message.classList.remove("switch-user");
            }
        });
        lastMessage = messagesContainer.querySelector(".message:last-child");
        if (doScrollDown) { 
            lastMessage?.scrollIntoView({ block: "end", inline: "nearest" });
        }
    }

    setInterval(updateTimes, 30000);

    function isMentionToMe(message){
        const mentionText = '@{{ user.username.value }}';
        return message.toLowerCase().includes(mentionText);
    }
    function extractMentions(message) {
        return [...new Set(message.match(/@\w+/g) || [])];
    }
    function isMentionForSomeoneElse(message){
        const mentions = extractMentions(message);
        const mentionText = '@{{ user.username.value }}';
        return mentions.length > 0 && mentions.indexOf(mentionText) == -1;
    }
    
    app.addEventListener("channel-message", (data) => {
        if (data.channel_uid !== channelUid) {
            if(!isMentionForSomeoneElse(data.message)){
                channelSidebar.notify(data);
                app.playSound("messageOtherChannel");
            }
            
            return;
        }
        if (data.username !== "{{ user.username.value }}") {
            if(isMentionToMe(data.message)){
                app.playSound("mention");
            }else if (!isMentionForSomeoneElse(data.message)){
                app.playSound("message");
            }
        }
        
        const messagesContainer = document.querySelector(".chat-messages");
        lastMessage = messagesContainer.querySelector(".message:last-child");
        const doScrollDownBecauseLastMessageIsVisible = !lastMessage || isElementVisible(lastMessage);

        const message = document.createElement("div");
        message.innerHTML = data.html;
        document.querySelector(".chat-messages").appendChild(message.firstChild);
        updateLayout(doScrollDownBecauseLastMessageIsVisible);
        setTimeout(() => {
            updateLayout(doScrollDownBecauseLastMessageIsVisible)
        }, 1000);
        app.rpc.markAsRead(channelUid);
    });

    initInputField(getInputField());
    updateLayout(true);
</script>
{% endblock %}
