#include channels.js
#include users.js
#include ui/messages.jsx

// messages should probably also be an "event" like how it is on the server

Umi.Message = (() => {
    const chatBot = new MamiUserInfo('-1', 'Server');

    return function(msgId, time, user, text, channel, highlight, botInfo, isAction, isLog) {
        msgId = (msgId || '').toString();
        time = time === null ? new Date() : (typeof time === 'object' ? time : new Date(parseInt(time || 0) * 1000));
        user = user !== null && typeof user === 'object' ? user : chatBot;
        text = (text || '').toString();
        channel = (channel || '').toString();
        highlight = !!highlight;
        isAction = !!isAction;
        isLog = !!isLog;
        hasSeen = isLog;

        const msgIdInt = parseInt(msgId);

        return {
            getId: () => msgId,
            getIdInt: () => {
                const num = parseInt(msgId);
                return isNaN(num) ? (Math.round(Number.MIN_SAFE_INTEGER * Math.random())) : num;
            },
            getTime: () => time,
            getUser: () => MamiConvertUserInfoToUmi(user),
            getUserV2: () => user,
            getText: () => text,
            getChannel: () => channel,
            shouldHighlight: () => highlight,
            getBotInfo: () => botInfo,
            isAction: () => isAction,
            isLog: () => isLog,
            hasSeen: () => hasSeen,
            markSeen: () => hasSeen = true,
        };
    };
})();

Umi.Messages = (function() {
    const msgs = new Map;

    return {
        Add: function(msg) {
            const msgId = msg.getId();
            if(!msgs.has(msgId)) {
                msgs.set(msgId, msg);
                Umi.UI.Messages.Add(msg);
                mami.globalEvents.dispatch('umi:message_add', msg);
            }
        },
        Remove: function(msg) {
            const msgId = msg.getId();
            if(msgs.has(msgId)) {
                msgs.delete(msgId);
                Umi.UI.Messages.Remove(msg);
            }
        },
        Clear: function() {
            msgs.clear();
            Umi.UI.Messages.RemoveAll();
        },
        All: function(channel, excludeNull) {
            if(!channel)
                return Array.from(msgs.values());

            if(!Umi.Channels.Get(channel))
                return null;

            const filtered = [];
            msgs.forEach(function(msg) {
                if(msg.getChannel() === channel || (!excludeNull && msg.getChannel() === null))
                    filtered.push(msg);
            });

            return filtered.slice(Math.max(filtered.length - 30, 0));
        },
        Get: function(msgId) {
            msgId = msgId.toString();
            if(msgs.has(msgId))
                return msgs.get(msgId);
            return null;
        },
    };
})();
