<script>
    import { onDestroy, onMount } from "svelte";
    import { ArrowUpIcon } from "svelte-feather-icons";
    import request from "../request";
    import { apiRoute, getItem } from "../storage";
    import { messagesStoreProvider, overlayStore, selectedChannel, setMessageInputEvent, smallViewport, typingStore, userInfoStore } from "../stores";

    export let channel;
    let messageInput = "";
    let messageTextarea;
    let typingList = "?no one?";
    let typingMessage = "is typing...";

    $: messages = messagesStoreProvider.getStore(channel.id);
    $: {
        const typing = $typingStore.filter(a => a.channelId === channel.id);
        const ownIndex = typing.findIndex(a => a.user.id === $userInfoStore.id);
        if (ownIndex !== -1) {
            typing.splice(ownIndex, 1);
        }

        if (typing.length === 0) {
            typingList = "?no one?";
            typingMessage = "is typing...";
        } else if (typing.length === 1) {
            typingList = `${typing[0].user.username}`;
            typingMessage = "is typing...";
        } else if (typing.length > 1) {
            typingList = "";
            for (let i = 0; i < typing.length; i++) {
                const item = typing[i];
                if (i == (typing.length - 1)) {
                    // we are at the end
                    typingList += `and ${item.user.username} `;
                } else {
                    typingList += `${item.user.username}, `;
                }
            }
            typingMessage = "are typing...";
        }
    }

    const sendMessage = async () => {
        messageTextarea.focus();

        if (messageInput.trim() === "" || !$userInfoStore)
            return;

        // optimistically add message to store
        const optimisticMessageId = Math.floor(Math.random() * 999999);
        const optimisticMessage = {
            id: optimisticMessageId,
            content: messageInput,
            channel_id: channel.id,
            author_id: $userInfoStore.id,
            author_username: $userInfoStore.username,
            created_at: Date.now().toString(),
            _isPending: true
        };
        messages.addMessage(optimisticMessage);
        messageInput = "";

        const res = await request("POST", apiRoute(`channels/${channel.id}/messages`), true, {
            content: optimisticMessage.content,
            optimistic_id: optimisticMessageId
        });
        
        if (res.success && res.ok) {
            messages.setMessage(optimisticMessageId, res.json);
        } else {
            messages.deleteMessage({
                id: optimisticMessageId
            });
            overlayStore.open("toast", {
                message: "Couldn't send message"
            });
        }
    };

    const onKeydown = async (e) => {
        if (e.code === "Enter") {
            if (e.shiftKey) {
                return;
            } else {
                e.preventDefault();
                await sendMessage();
            }
        }
    };

    const onInput = () => {
        typingStore.didInputKey();
    };


    const unsubscribers = [];


    // Focus the text area when the component first loads, or when the user selects another channel
    const focusTextarea = () => messageTextarea && messageTextarea.focus();
    onMount(focusTextarea);
    unsubscribers.push(selectedChannel.subscribe(focusTextarea));

    // Handle the setMessageInput event
    unsubscribers.push(setMessageInputEvent.subscribe((value) => {
        messageInput = value;
        focusTextarea();
    }));


    onDestroy(() => {
        unsubscribers.forEach(e => e());
    });
</script>

<style>
    .message-input-container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        width: 100%;
        padding: var(--space-norm);
        padding-bottom: 0;
    }
    
    .message-input-container.small {
        padding-top: var(--space-sm);
    }
    
    .message-input.small {
        padding: var(--space-xsplus);
        padding-left: var(--space-sm);
        border-radius: 1.4em;
    }

    .message-input {
        width: 100%;
        background-color : var(--background-color-2);
        border: none;
        color: currentColor;
        border-radius: var(--radius-md);
        padding: var(--space-sm);
        font-size: inherit;
        line-height: inherit;
        resize: none;
    }

    .message-input::placeholder {
        color: var(--foreground-color-4);
    }

    .send-button {
        margin-left: var(--space-sm);
        border-radius: 50%;
        background-color: var(--purple-1);
        padding: 12px;
        aspect-ratio: 1;
        flex-shrink: 0;
    }

    .invisible {
        visibility: hidden;
    }

    .inner-input-container {
        display: flex;
        flex-direction: row;
        width: 100%;
        height: 100%;
        padding: 0;
        margin: 0;
    }

    .typing-info-container {
        padding-left: var(--space-xxs);
    }

    .typing-list {
        font-weight: bolder;
    }

    .typing-message {
        color: var(--foreground-color-2);
    }
</style>

<div class="message-input-container" class:small={ $smallViewport }>
    <div class="inner-input-container">
        <textarea
            placeholder={$smallViewport ? `Message #${channel.name}` : `Send something interesting to #${channel.name}`}
            type="text"
            class="message-input"
            rows="1"
            on:keydown={ onKeydown }
            on:input={ onInput }
            bind:value={ messageInput }
            bind:this={ messageTextarea }
            class:small={ $smallViewport || getItem("ui:alwaysUseMobileChatBar") }
        />
        {#if $smallViewport || getItem("ui:alwaysUseMobileChatBar")}
            <button class="icon-button send-button" on:click="{ sendMessage }">
                <ArrowUpIcon />
            </button>
        {/if}
    </div>
    <div class="typing-info-container">
        <span class="typing-list" class:invisible={ typingList === "?no one?" }>{ typingList }</span>
        <span class="typing-message" class:invisible={ typingList === "?no one?" }>{ typingMessage }</span>
    </div>
</div>
