class LabelComposite extends HTMLElement {
    get scannable() {
        return this.getAttribute("scannable") || this._scannable;
    }

    set scannable(value) {
        this._scannable = value;
    }

    get id() {
        return this.getAttribute("id") || this._id;
    }

    set id(value) {
        this._id = value;
    }

    get label() {
        return this.getAttribute("label") || this._label;
    }

    set label(value) {
        this._label = value;
    }

    get descriptor() {
        return this.getAttribute("descriptor") || this._descriptor;
    }

    set descriptor(value) {
        this._descriptor = value;
    }

    get lookup() {
        return this.getAttribute("lookup") || this._lookup;
    }

    set lookup(value) {
        this._lookup = value;
    }

    get peek() {
        return this.getAttribute("peek") || this._peek;
    }

    set peek(value) {
        this._peek = value;
    }

    get model() {
        return this._model;
    }

    set model(value) {
        this._model = value;
    }


    constructor() {
        super();
    }

    connectedCallback() {
        this.initTemplate();

        this.focusInHandler = this.focusIn.bind(this);
        this.focusOutHandler = this.focusOut.bind(this);
        this.checkValidityHandler = this.checkValidity.bind(this);
        this.buttonsKeyboardActionHandler = this.handleKeyboardActionOnButtons.bind(this);

        this.addEventListener("focusin", this.focusInHandler);
        this.addEventListener("focusout", this.focusOutHandler);
        this.addEventListener("keyup", this.buttonsKeyboardActionHandler);
        this.input.addEventListener("keyup", this.checkValidityHandler);

    }

    disconnectedCallback() {
        delete this.model;

        if (this.btnLookupClickHandler != undefined) {
            this.querySelector("#btnLookup").removeEventListener("click", this.btnLookupClickHandler);
            this.btnLookupClickHandler = null;
        }

        if (this.btnScanClickHandler != undefined) {
            this.querySelector("#btnScan").removeEventListener("click", this.btnScanClickHandler);
            this.btnScanClickHandler = null;
        }

        if (this.btnPeekClickHandler != undefined) {
            this.querySelector("#btnPeek").removeEventListener("click", this.btnPeekClickHandler);
        }

        this.removeEventListener("focusin", this.focusInHandler);
        this.removeEventListener("focusout", this.focusOutHandler);
        this.removeEventListener("keyup", this.buttonsKeyboardActionHandler);
        this.input.removeEventListener("keyup", this.checkValidityHandler);

        this.focusInHandler = null;
        this.focusOutHandler = null;
        this.buttonsKeyboardActionHandler = null;
        this.checkValidityHandler = null;
        this.input = null;
    }

    initTemplate() {
        const instance = document.importNode(window.templates.get("label-composite"), true);
        this.input = this.children[0];

        const inputGroup = instance.querySelector(".input-group");
        const label = instance.querySelector("label");

        this.removeChild(this.input);
        label.innerText = this.label;

        this.initDescriptor(instance);
        if (this.initInputGroup(instance, inputGroup, this.input)) {
            this.initButtons(inputGroup);
            this.listenForDblClick();
        }

        this.appendChild(instance);
    }

    initDescriptor(instance) {
        const descriptor = instance.querySelector(".descriptor");

        if (this.descriptor == undefined) {
            instance.removeChild(descriptor);
        }
        else {
            descriptor.innerText = this.descriptor;
        }
    }

    initInputGroup(instance, group, input) {
        if (this.lookup == undefined && this.peek == undefined && this.scannable == undefined) {
            instance.replaceChild(input, group);
            return false;
        }

        group.insertBefore(input, group.children[0]);
        return true;
    }

    initButtons(parent) {
        const btnLookup = parent.querySelector("#btnLookup");
        const btnScan = parent.querySelector("#btnScan");
        const btnPeek = parent.querySelector("#btnPeek");

        btnLookup.setAttribute("aria-label", `Lookup ${this.label}`);
        btnScan.setAttribute("aria-label", `Scan ${this.label}`);
        btnPeek.setAttribute("aria-label", `View ${this.label}`);


        if (this.lookup == undefined) {
            parent.removeChild(btnLookup);
        }
        else {
            this.btnLookupClickHandler = this.btnLookupClick.bind(this);
            btnLookup.addEventListener("click", this.btnLookupClickHandler);
        }

        if (this.scannable == undefined) {
            parent.removeChild(btnScan);
        }
        else {
            this.btnScanClickHandler = this.btnScanClick.bind(this);
            btnScan.addEventListener("click", this.btnScanClickHandler);
        }

        if (this.peek == undefined) {
            parent.removeChild(btnPeek);
        }
        else {
            this.btnPeekClickHandler = this.btnPeekClick.bind(this);
            btnPeek.addEventListener("click", this.btnPeekClickHandler);
        }
    }

    btnLookupClick() {
        this.model.doLookup(this.lookup);
    }

    btnScanClick() {
        alert("do scan");
    }

    btnPeekClick() {
        this.model.doPeek(this.peek);
    }

    focusIn() {
        this.setAttribute("data-status", this.isValid == false ? "invalid" : "focused");
    }

    focusOut() {
        this.setAttribute("data-status", this.isValid == false ? "invalid" : "normal");
    }

    shallowValidate() {
        this.ignoreFullValidityCheck = true;
        this.checkValidity();
        this.ignoreFullValidityCheck = false;
    }

    checkValidity() {
        if (this.input == undefined || this.input == null) {
            return;
        }

        const isValid = this.input.validity == undefined ? true : this.input.validity.valid;

        if (isValid != this.isValid) {
            this.setValidity(isValid);
        }
    }

    setValidity(isValid) {
        this.isValid = isValid;
        this.setAttribute("data-status", isValid == true ? "focused" : "invalid");
    }

    listenForDblClick() {
        this.handelMouseUpHandler = this.handelMouseUp.bind(this);
        this.input.addEventListener("mouseup", this.handelMouseUpHandler);
    }

    handelMouseUp(event) {
        if (!this.tapedTwice) {
            this.tapedTwice = true;
            setTimeout(() => {
                this.tapedTwice = false;
            }, 300);

            return false;
        }

        event.preventDefault();
        this.model.doDrillDown(this.peek);
    }

    handleKeyboardActionOnButtons(event) {
        if (event.keyCode == 32 || event.keyCode == 13) {
            switch (event.target.id) {
                case("btnPeek"):
                    this.btnPeekClick();
                    return;
                case("btnLookup"):
                    this.btnLookupClick();
                    return;
                case("btnScan"):
                    this.btnScanClick();
                    return;

            }
        }
    }
}

customElements.define("label-composite", LabelComposite);