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

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

const TPL = new Template(`
    <div id="ref"></div>
    <select id="input"></select>
    
`);

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

const STYLE = new GlobalStyle(`
    #ref,
    #input {
        margin: 5px;
    }
    
    #input {
        flex-grow: 1;
        height: 2em;
        padding: 0px 7px;
        color: var(--input-text-color, #000000);
        background-color: var(--input-back-color, #ffffff);
        background-image: var(--input-back-image, none);
        border-style: solid;
        border-width: var(--input-border-width, 2px);
        border-color: var(--input-border-color, #222222);
        border-radius: var(--input-border-radius, 6px);
        font-size: 1em;
        cursor: pointer;
    }
    
    #input:focus {
        box-shadow: 0 0 2px 3px var(--input-focus-color, #06b5ff);
        outline: none;
    }
    
    #input:disabled {
        opacity: 1;
    }
    
    :host(:invalid) #input {
        background-color: var(--input-invalid-back-color, #ffebeb);
        background-image: var(--input-invalid-back-image, none);
        border-color: var(--input-invalid-border-color, #ff4444);
    }
    
    :host(:invalid) #input:focus {
        box-shadow: 0 0 2px 3px var(--input-invalid-focus-color, #ff2500);
    }
    
    :host([readonly]:not([readonly="false"])) #input {
        pointer-events: none;
        cursor: default;
        appearance: none;
    }
    
    #ref:empty::after {
        font-style: italic;
        content: "empty";
    }
    
`);

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

import AbstractElement from "./AbstractElement.js";
import LogicOperatorRegistry from "../../../data/registry/LogicOperatorRegistry.js";

export default class AbstractLiteralStateElement extends AbstractElement {

    #inputEl;

    #type;

    #options;

    constructor(type, caption) {
        super(caption);
        const els = TPL.generate();
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.shadowRoot.getElementById("body").append(els);
        this.#type = type;
        /* --- */
        this.#inputEl = this.shadowRoot.getElementById("input");
        this.#inputEl.addEventListener("change", () => {
            this.value = this.#inputEl.value;
            this.dispatchEvent(new Event("valuechange", {
                bubbles: true,
                cancelable: true
            }));
        });
    }

    getElement(forceCopy = false) {
        if (forceCopy || this.template) {
            const node = super.getElement(forceCopy);
            node.setOptions(this.#options);
            return node;
        } else {
            return this;
        }
    }

    set ref(val) {
        this.setAttribute("ref", val);
    }

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

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

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

    setOptions(options) {
        this.#options = options;
        this.#inputEl.innerHTML = "";
        if (Array.isArray(options)) {
            for (const value of options) {
                this.#addOption(value);
            }
        } else {
            for (const value in options) {
                const label = options[value];
                this.#addOption(value, label);
            }
        }
    }

    #addOption(value, label) {
        if (typeof value === "string" && value !== "") {
            const optionEl = document.createElement("option", {is: "emc-i18n-option"});
            optionEl.value = value;
            if (typeof label === "string" && label !== "") {
                optionEl.i18nValue = label;
            } else {
                optionEl.i18nValue = value;
            }
            this.#inputEl.append(optionEl);
        }
    }

    calculate(state = {}) {
        if (state[this.ref] != null) {
            const val = +(state[this.ref] === this.value);
            this.shadowRoot.getElementById("header").setAttribute("value", val);
            return val;
        } else {
            this.shadowRoot.getElementById("header").setAttribute("value", "0");
            return 0;
        }
    }

    toJSON() {
        return {
            type: this.#type,
            ref: this.ref,
            value: this.value
        };
    }

    loadLogic(logic) {
        this.ref = logic.ref;
        const operatorConfig = LogicOperatorRegistry.getOperator(logic.ref);
        if (operatorConfig != null) {
            this.setOptions(operatorConfig.options);
        }
        this.value = logic.value;
    }

    static get observedAttributes() {
        const attr = AbstractElement.observedAttributes;
        attr.push("ref", "value");
        return attr;
    }

    attributeChangedCallback(name, oldValue, newValue) {
        super.attributeChangedCallback(name, oldValue, newValue);
        switch (name) {
            case "disabled":
            case "template": {
                if (oldValue != newValue) {
                    if (this.editable) {
                        this.#inputEl.removeAttribute("disabled");
                    } else {
                        this.#inputEl.setAttribute("disabled", "true");
                    }
                }
            } break;
            case "ref": {
                if (oldValue != newValue) {
                    if (typeof newValue === "string") {
                        this.shadowRoot.getElementById("ref").innerText = newValue;
                    } else {
                        this.shadowRoot.getElementById("ref").innerHTML = "";
                    }
                }
            } break;
            case "value": {
                if (oldValue != newValue) {
                    this.#inputEl.value = newValue;
                }
            } break;
        }
    }

}
