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

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

const TPL = new Template(`
    <emc-select-switch id="input" value="true" hideerrors nohover novalidate>
        <option is="emc-i18n-option" value="true" i18n-value="True"></option>
        <option is="emc-i18n-option" value="false" i18n-value="False"></option>
        <option is="emc-i18n-option" value="logic" i18n-value="Logic"></option>
    </emc-select-switch>
    <emc-input-logic id="logic" hideerrors nohover novalidate></emc-input-logic>
    
`);

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

const STYLE = new GlobalStyle(`
    #field {
        flex-direction: column;
    }
    
    /* --- */
    #input {
        padding: 0px;
    }
    
    #input:focus {
        outline: none;
    }
    
    /* --- */
    #logic {
        margin-top: 5px;
        padding: 0;
    }
    
    #logic:not(.active) {
        display: none;
    }
    
`);

const CONFIG_FIELDS = [
    {
        "type": "SwitchInput",
        "name": "nullable",
        "label": "Show null value option",
        "value": false
    }
]
;

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

import AbstractFormElement from "../../AbstractFormElement.js";
import FormElementRegistry from "../../../../../data/registry/form/FormElementRegistry.js";
import {registerFocusable} from "../../../../../util/helper/html/ElementFocusHelper.js";
import {deepClone} from "../../../../../util/helper/DeepClone.js";
import "../../../../i18n/builtin/I18nInput.js";
import "../../../../i18n/builtin/I18nOption.js";
import "../logic/LogicInput.js";
import "../../select/switch/SwitchSelect.js";

export default class BoolOrLogicInput extends AbstractFormElement {

    static get formConfigurationFields() {
        return [...super.formConfigurationFields, ...deepClone(CONFIG_FIELDS)];
    }

    #inputEl;

    #logicEl;

    #nullOptionEl;

    constructor() {
        super();
        this.shadowRoot.getElementById("field").append(TPL.generate());
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.#inputEl = this.shadowRoot.getElementById("input");
        this.#logicEl = this.shadowRoot.getElementById("logic");
        this.#inputEl.addEventListener("input", () => {
            const value = this.#inputEl.value;
            if (value === "logic") {
                this.#logicEl.classList.add("active");
                this.value = this.#logicEl.value ?? {};
            } else {
                this.#logicEl.classList.remove("active");
                this.#logicEl.value = null;
                if (this.nullable && value === "") {
                    this.value = "";
                } else {
                    this.value = value === "true";
                }
            }
        });
        this.#logicEl.addEventListener("change", () => {
            const value = this.#inputEl.value;
            if (value === "logic") {
                this.value = this.#logicEl.value ?? {};
            }
        });
        this.#logicEl.addValidator(() => {
            return this.validationMessage;
        });
        /* --- */
        this.#nullOptionEl = document.createElement("option", {is: "emc-i18n-option"});
        this.#nullOptionEl.value = "";
        this.#nullOptionEl.i18nValue = "Null";
    }

    formDisabledCallback(disabled) {
        super.formDisabledCallback(disabled);
        this.#inputEl.disabled = disabled;
        this.#logicEl.disabled = disabled;
    }

    formResetCallback() {
        super.formResetCallback();
        this.#inputEl.formResetCallback();
        this.#logicEl.formResetCallback();
    }

    validityCallback(message) {
        this.#logicEl.setCustomValidity(message);
    }

    focus(options) {
        this.#inputEl.focus(options);
    }

    addOperatorGroup(...groupList) {
        this.#logicEl.addOperatorGroup(...groupList);
    }

    removeOperatorGroup(...groupList) {
        this.#logicEl.removeOperatorGroup(...groupList);
    }

    set defaultValue(value) {
        this.setJSONAttribute("value", value);
    }

    get defaultValue() {
        return this.getJSONAttribute("value");
    }

    set value(value) {
        if (value === "true") {
            value = true;
        } else if (value === "false") {
            value = false;
        } else if (value === "") {
            value = null;
        }
        super.value = value;
    }

    get value() {
        return super.value;
    }

    set nullable(value) {
        this.setBooleanAttribute("nullable", value);
    }

    get nullable() {
        return this.getBooleanAttribute("nullable");
    }

    static get observedAttributes() {
        return [...super.observedAttributes, "name", "readonly", "nullable"];
    }

    attributeChangedCallback(name, oldValue, newValue) {
        super.attributeChangedCallback(name, oldValue, newValue);
        switch (name) {
            case "name":{
                if (oldValue != newValue) {
                    this.#logicEl.name = newValue;
                }
            } break;
            case "readonly": {
                if (oldValue != newValue) {
                    this.#inputEl.readonly = this.readonly;
                    this.#logicEl.readonly = this.readonly;
                }
            } break;
            case "nullable": {
                if (this.nullable) {
                    this.#inputEl.prepend(this.#nullOptionEl);
                    this.#inputEl.defaultValue = "";
                } else {
                    this.#nullOptionEl.remove();
                    this.#inputEl.defaultValue = "true";
                }
            } break;
        }
    }

    checkValid() {
        const el = this.#logicEl.children[0];
        if (el != null && !el.checkValidity()) {
            return "Not a valid logic";
        }
        return super.checkValid();
    }

    renderValue(value) {
        if (typeof value === "object" && value != null) {
            this.#inputEl.value = "logic";
            this.#logicEl.value = value;
        } else if (value === false) {
            this.#inputEl.value = "false";
            this.#logicEl.value = null;
        } else if (value === true) {
            this.#inputEl.value = "true";
            this.#logicEl.value = null;
        } else {
            this.#inputEl.value = "";
            this.#logicEl.value = null;
        }
    }

    onDisplayValueChange(value) {
        if (typeof value === "object" && value != null) {
            this.#logicEl.classList.add("active");
        } else {
            this.#logicEl.classList.remove("active");
        }
    }

}

FormElementRegistry.register("BoolOrLogicInput", BoolOrLogicInput);
customElements.define("emc-input-boolorlogic", BoolOrLogicInput);
registerFocusable("emc-input-boolorlogic");
