import { IgniteHtml } from '../ignite-html/ignite-html.js';
import { IgniteElement } from "../ignite-html/ignite-element.js";
import { IgniteTemplate, button, ul, slot, span, div } from "../ignite-html/ignite-template.js";
import { IgniteProperty } from "../ignite-html/ignite-html.js";

class EditableLabel extends IgniteElement {
    constructor() {
        super();
    }

    get styles() {
        return /*css*/`
            mt-editable-label {
                display: flex;
                flex-direction: row;
                align-items: center;
                justify-content: space-between;
                border-radius: 0.3rem;
                border: solid 0.13rem #ced4da;
                padding: 0.4rem;
            }

            mt-editable-label.no-border {
                border-color: transparent;
            }

            mt-editable-label.editing {
                border: solid 0.13rem rgba(0,0,0,0.1);
            }

            mt-editable-label.truncate > div {
                white-space: nowrap;
                text-overflow: ellipsis;
                overflow: hidden;
            }

            mt-editable-label:hover {
                cursor: pointer;
            }

            mt-editable-label>div {
                flex: 1;
                word-break: break-word;
            }

            mt-editable-label>div:focus {
                outline: none;
            }

            mt-editable-label>div:empty:before {
                content: attr(data-placeholder);
                opacity: 0.5;
            }

            mt-editable-label>button {
                margin-left: 0.5em;
                background-color: #2196F3;
                color: #fff;
                border: none;
                border-radius: 0.3rem;
                padding: 0;
                width: 1.5em;
                height: 1.5em;
                min-width: 1.5em;
                min-height: 1.5em;
                font-size: 0.8rem;
            }
        `;
    }

    get properties() {
        return {
            stopEditingOnBlur: true,
            editing: false,
            value: null,
            multiLine: false,
            truncate: false,
            saveButton: true,
            input: null,
            placeholder: null,
            border: false
        };
    }

    render() {
        return this.template
            .attribute("tabindex", "0")
            .class(this.border, value => value ? null : "no-border")
            .class(this.editing, value => value ? "editing" : null)
            .class([this.editing, this.truncate], (editing, truncate) => !editing && truncate ? "truncate" : null)
            .onFocus(e => this.onFocus(e))
            .child(
                new div()
                    .innerHTML(this.value)
                    .class(this.editing, (value) => { return value ? "focus" : null; })
                    .attribute("contenteditable", this.editing)
                    .data("placeholder", this.placeholder)
                    .ref(this.input)
                    .onBlur(e => this.onBlur(e))
                    .on("keydown", (e) => this.onKeyDown(e)),
                new button(`<i class="fas fa-check"></i>`)
                    .onClick(e => this.onBlur(e))
                    .style("display", this.editing, true, (value) => { return value && this.saveButton ? null : "none" })
            );
    }

    onKeyDown(e) {
        if ((e.keyCode === 13 || e.keyCode === 27) && !this.multiLine) {
            this.input.blur();
            e.preventDefault();
            e.stopPropagation();
        }
    }

    onBlur(e) {
        if (this.editing) {
            if (this.stopEditingOnBlur) {
                this.editing = false;
            }

            if (this.input.innerText !== this.value) {
                this.value = this.input.innerText;

                //Dispatch a native change event 
                this.dispatchEvent(new CustomEvent("change", { bubbles: true }));
            }
        }
    }

    onFocus(e) {
        this.editing = true;
        this.input.focus();
        this.placeCaretAtEnd(this.input);
    }

    placeCaretAtEnd(el) {
        el.focus();
        if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
            var range = document.createRange();
            range.selectNodeContents(el);
            range.collapse(false);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (typeof document.body.createTextRange != "undefined") {
            var textRange = document.body.createTextRange();
            textRange.moveToElementText(el);
            textRange.collapse(false);
            textRange.select();
        }
    }
}

class EditableLabelTemplate extends IgniteTemplate {
    constructor(...children) {
        super("mt-editable-label", children);
    }
}

IgniteHtml.register("mt-editable-label", EditableLabel);

export {
    EditableLabelTemplate as EditableLabel
}