/* ===================== AUTOGENERATED SOURCE IMPORT ===================== */

import Template from "/emcJS/util/html/template/HTMLTemplate.js";

const TPL = new Template(`
    <div id="container"></div>
    
`);

import GlobalStyle from "/emcJS/util/html/template/CSSTemplate.js";

const STYLE = new GlobalStyle(`
    :host {
        position: relative;
        margin: 1px;
        color: #ffffff;
        background: #222222;
    }
    
    #container {
        position: relative;
        box-sizing: border-box;
        padding: 6px;
        white-space: pre-wrap;
        user-select: text;
    }
    
    #container .player-current {
        color: var(--ap-color-player-current, #ee00ee);
    }
    
    #container .player-other {
        color: var(--ap-color-player-other, #fafad2);
    }
    
    #container .item-progressive {
        color: var(--ap-color-item-progressive, #af99ef);
    }
    
    #container .item-useful {
        color: var(--ap-color-item-useful, #6d8be8);
    }
    
    #container .item-normal {
        color: var(--ap-color-item-normal, #00eeee);
    }
    
    #container .item-trap {
        color: var(--ap-color-item-trap, #fa8072);
    }
    
    #container .location {
        color: var(--ap-color-location, #00ff7f);
    }
    
    #container .entrance {
        color: var(--ap-color-entrance, #6495ed);
    }
    
    #container .hint-unspecified {
        color: var(--ap-color-hint-unspecified, #ffffff);
    }
    
    #container .hint-no-priority {
        color: var(--ap-color-hint-no-priority, #00eeee);
    }
    
    #container .hint-priority {
        color: var(--ap-color-hint-priority, #af99ef);
    }
    
    #container .hint-avoid {
        color: var(--ap-color-hint-avoid, #fa8072);
    }
    
    #container .hint-found {
        color: var(--ap-color-hint-found, #00ff7f);
    }
    
`);

/* ======================================================================= */

import CustomElement from "/emcJS/ui/element/CustomElement.js";
import {
    VALID_JSON_MESSAGE_TYPE
} from "/ArchipelagoJS/types/JSONMessagePart.js";
import {
    PRINT_JSON_TYPE
} from "/ArchipelagoJS/consts/PrintJSONType.js";
import {
    HINT_STATUS
} from "/ArchipelagoJS/consts/HintStatus.js";

const hintTypes = Object.entries(HINT_STATUS).reduce((prev, [key, value]) => {
    prev[value] = key.toLowerCase().replace(/_/g, "-");
    return prev;
}, {});

export default class ChatListEntry extends CustomElement {

    #containerEl;

    constructor() {
        super();
        TPL.apply(this.shadowRoot);
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.#containerEl = this.shadowRoot.getElementById("container");
    }

    setData(data) {
        const convertedMessage = this.#consolidateMessage(data);
        this.#containerEl.innerHTML = convertedMessage;
    }

    set key(value) {
        this.setAttribute("key", value);
    }

    get key() {
        return this.getAttribute("key");
    }

    #consolidateMessage(packet) {
        if (packet.type === PRINT_JSON_TYPE.SERVER_CHAT) {
            return packet.message.replace(/</g, "&lt;").replace(/>/g, "&gt;");
        }

        if (packet.type === PRINT_JSON_TYPE.CHAT) {
            const escapedText = packet.message.replace(/</g, "&lt;").replace(/>/g, "&gt;");
            return `${packet.playerAlias}: ${escapedText.replace(/</g, "&lt;").replace(/>/g, "&gt;")}`;
        }

        /**
         * TODO
         * add dictionary to combine message resolving and rendering into one entry.
         * the idea is to make it easily extendible.
         */
        return packet.message.reduce((string, piece) => {
            switch (piece.type) {
                case VALID_JSON_MESSAGE_TYPE.PLAYER_ID: {
                    if (piece.current) {
                        const escapedPlayerAlias = piece.playerAlias.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                        return `${string}<span class="player-current">${escapedPlayerAlias}</span>`;
                    } else {
                        const escapedPlayerAlias = piece.playerAlias.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                        const escapedPlayerGame = piece.playerGame.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                        return `${string}<span class="player-other">${escapedPlayerAlias}<span class="showGameName"> [${escapedPlayerGame}]</span></span>`;
                    }
                }

                case VALID_JSON_MESSAGE_TYPE.LOCATION_ID: {
                    const escapedLocationName = piece.locationName.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    return `${string}<span class="location">${escapedLocationName}</span>`;
                }

                case VALID_JSON_MESSAGE_TYPE.ITEM_ID: {
                    const escapedItemName = piece.itemName.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    return `${string}<span class="item-${piece.itemClass}">${escapedItemName}</span>`;
                }

                case VALID_JSON_MESSAGE_TYPE.ENTRANCE_NAME: {
                    const escapedEntranceName = piece.entranceName.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    return `${string}<span class="entrance">${escapedEntranceName}</span>`;
                }

                case VALID_JSON_MESSAGE_TYPE.HINT_STATUS: {
                    const escapedHintText = piece.text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    return `${string}<span class="${hintTypes[piece.hintStatus]}">${escapedHintText}</span>`;
                }

                case VALID_JSON_MESSAGE_TYPE.COLOR: {
                    const escapedText = piece.text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    return `${string}<span style="color: ${piece.color}">${escapedText}</span>`;
                }

                default: {
                    const escapedText = piece.text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    return `${string}<span class="default">${escapedText}</span>`;
                }
            }
        }, "");
    }

}

customElements.define("ootrt-ap-chatlist-entry", ChatListEntry);
