#include channels.js
#include common.js
#include parsing.js
#include settings.js
#include url.js
#include users.js
#include utility.js
#include weeb.js
#include ui/emotes.js

Umi.UI.Messages = (function() {
    let lastMsgUser = null,
        lastMsgChannel = null,
        lastWasTiny = null;

    return {
        Add: function(msg) {
            if(msg.getChannel() !== null
                && Umi.Channels.Current() !== null
                && msg.getChannel() !== Umi.Channels.Current().getName())
                return;

            let isTiny = false,
                skipTextParsing = false,
                msgText = msg.getText();

            let eBase = null,
                eAvatar = null,
                eText = null,
                eMeta = null,
                eUser = null;

            const sender = msg.getUser();
            let avatarUser = sender,
                avatarSize = '80';

            const userClass = 'message--user-' + sender.getId();

            const classes = ['message', userClass];
            const styles = {};

            const avatarClasses = ['message__avatar'];

            const msgIsFirst = lastMsgUser !== sender.getId() || lastMsgChannel !== msg.getChannel();
            if(msgIsFirst)
                classes.push('message--first');

            if(msg.shouldHighlight())
                classes.push('message--highlight');

            if(msg.isAction()) {
                isTiny = true;
                classes.push('message-action');
            }

            if(sender.getId() === "136")
                styles.transform = 'scaleY(' + (0.76 + (0.01 * Math.max(0, Math.ceil(Date.now() / (7 * 24 * 60 * 60000)) - 2813))).toString() + ')';

            const msgDateTimeObj = msg.getTime();
            const msgDateTime = msgDateTimeObj.getHours().toString().padStart(2, '0')
                + ':' + msgDateTimeObj.getMinutes().toString().padStart(2, '0')
                + ':' + msgDateTimeObj.getSeconds().toString().padStart(2, '0');

            if(sender.isBot() && Umi.Settings.get('fancyInfo')) {
                const botInfo = msg.getBotInfo();

                if(botInfo) {
                    if(botInfo.type === 'join' || botInfo.type === 'jchan'
                        || botInfo.type === 'leave' || botInfo.type === 'lchan'
                        || botInfo.type === 'kick' || botInfo.type === 'flood'
                        || botInfo.type === 'timeout') {
                        const target = botInfo.target || Umi.Users.FindExact(botInfo.args[0]);

                        if(target) {
                            isTiny = true;
                            skipTextParsing = true;
                            avatarUser = target;
                            msgText = 'did something';

                            $ari(classes, userClass);

                            switch(botInfo.type) {
                                case 'join':
                                    msgText = 'has joined';
                                    break;
                                case 'leave':
                                    msgText = 'has disconnected';
                                    avatarClasses.push('avatar-filter-greyscale');
                                    break;
                                case 'jchan':
                                    msgText = 'has joined the channel';
                                    break;
                                case 'lchan':
                                    msgText = 'has left the channel';
                                    avatarClasses.push('avatar-filter-greyscale');
                                    break;
                                case 'kick':
                                    msgText = 'got bludgeoned to death';
                                    avatarClasses.push('avatar-filter-invert');
                                    break;
                                case 'flood':
                                    msgText = 'got kicked for flood protection';
                                    avatarClasses.push('avatar-filter-invert');
                                    break;
                                case 'timeout':
                                    msgText = 'exploded';
                                    avatarClasses.push('avatar-filter-greyscale');
                                    break;
                            }
                        }
                    }
                }
            }

            if(isTiny) {
                if(!msgIsFirst) // small messages must always be "first"
                    classes.push('message--first');
                classes.push('message-tiny');

                avatarSize = '40';

                if(msgText.indexOf("'") !== 0 || (msgText.match(/\'/g).length % 2) === 0)
                    msgText = "\xA0" + msgText;

                eBase = <div id={`message-${msg.getId()}`} class={classes} style={styles}>
                    {eAvatar = <div class={avatarClasses}/>}
                    <div class="message__container">
                        {eMeta = <div class="message__meta">
                            {eUser = <div class="message__user" style={{ color: avatarUser.getColour() }}>{avatarUser.getName()}</div>}
                            {eText = <div class="message-tiny-text"/>}
                            <div class="message__time">{msgDateTime}</div>
                        </div>}
                    </div>
                </div>;
            } else {
                eBase = <div id={`message-${msg.getId()}`} class={classes} style={styles}>
                    {eAvatar = <div class={avatarClasses}/>}
                    <div class="message__container">
                        {eMeta = <div class="message__meta">
                            {eUser = <div class="message__user" style={{ color: avatarUser.getColour() }}>{avatarUser.getName()}</div>}
                            <div class="message__time">{msgDateTime}</div>
                        </div>}
                        {eText = <div class="message__text"/>}
                    </div>
                </div>;
            }

            eText.innerText = msgText;

            if(!skipTextParsing) {
                eText = Umi.UI.Emoticons.Parse(eText, msg);
                eText = Umi.Parsing.Parse(eText, msg);

                const urls = [];

                if(Umi.Settings.get('autoParseUrls')) {
                    const textSplit = eText.innerText.split(' ');
                    for(const textPart of textSplit) {
                        const uri = Umi.URI.Parse(textPart);

                        if(uri !== null && uri.Slashes !== null) {
                            urls.push(textPart);

                            const linkElement = $e({
                                tag: 'a',
                                attrs: {
                                    className: 'markup__link',
                                    href: textPart,
                                    target: '_blank',
                                    rel: 'nofollow noreferrer noopener',
                                },
                                child: textPart,
                            });

                            eText.innerHTML = eText.innerHTML.replace(textPart.replace(/&/g, '&amp;'), linkElement.outerHTML);
                        }
                    }
                }

                if(Umi.Settings.get('resolveUrls')) {
                    // todo: resolve urls
                }

                if(Umi.Settings.get('weeaboo')) {
                    eText.appendChild($t(Weeaboo.getTextSuffix(sender)));

                    const kaomoji = Weeaboo.getRandomKaomoji(true, msg);
                    if(kaomoji) {
                        eText.appendChild($t(' '));
                        eText.appendChild($t(kaomoji));
                    }
                }

                if(Umi.Settings.get('weeaboo'))
                    eUser.appendChild($t(Weeaboo.getNameSuffix(sender)));
            }

            if(isTiny !== lastWasTiny) {
                if(!msgIsFirst)
                    eBase.classList.add('message--first');
                eBase.classList.add(isTiny ? 'message-tiny-fix' : 'message-big-fix');
            }
            lastWasTiny = isTiny;

            const avatarUrl = futami.get('avatar');
            if (avatarUrl !== null && avatarUrl.length > 1) {
                eAvatar.style.backgroundImage = 'url({0})'.replace('{0}', avatarUrl.replace('{user:id}', avatarUser.getId())
                    .replace('{resolution}', avatarSize).replace('{user:avatar_change}', avatarUser.getAvatarTime().toString()));
            } else eAvatar.classList.add('message__avatar--disabled');

            Umi.UI.Elements.Messages.appendChild(eBase);
            lastMsgUser = sender.getId();
            lastMsgChannel = msg.getChannel();

            if(Umi.Settings.get('autoEmbedV1')) {
                const callEmbedOn = eBase.querySelectorAll('a[onclick^="Umi.Parser.SockChatBBcode.Embed"]');
                for(const embedElem of callEmbedOn)
                    if(embedElem.dataset.embed !== '1')
                        embedElem.click();
            }

            if(Umi.Settings.get('autoScroll'))
                Umi.UI.Elements.Messages.scrollTop = Umi.UI.Elements.Messages.scrollHeight;

            if(window.CustomEvent)
                window.dispatchEvent(new CustomEvent('umi:ui:message_add', {
                    detail: {
                        element: eBase,
                        message: msg,
                    },
                }));
        },
        Remove: function(msg) {
            lastMsgUser = null;
            lastMsgChannel = null;
            lastWasTiny = null;
            $ri('message-' + msg.getId());
        },
        RemoveAll: function() {
            lastMsgUser = null;
            lastMsgChannel = null;
            lastWasTiny = null;
            Umi.UI.Elements.Messages.innerHTML = '';
        },
    };
})();
