import { h } from "@stencil/core";
import { NativeEvent } from '../../utils/native-event';
export class BceOptionCreator {
    constructor() {
        this.value = [];
        this.allowOther = false;
        this.other = false;
        this.labelOCAddButton = 'Add';
        this.labelOCRemoveButton = 'Delete';
        this.labelOCOther = 'Other';
        this.labelOCImage = 'Image';
        this.handleInput = (event, index) => {
            event.cancelBubble = true;
            const input = event.target;
            if (!input)
                return;
            // Update value
            const copy = [...this.value];
            const update = Object.assign({}, this.value[index], { text: input.value });
            copy.splice(index, 1, update);
            this.value = copy;
            this.el.dispatchEvent(new NativeEvent('input'));
        };
        this.handleKeyDown = async (event) => {
            if (event.code === 'Enter')
                this.handleAdd();
        };
        this.handleAdd = (focus = true) => {
            const insert = { text: '' };
            this.value = this.other
                ? [...this.value.slice(0, -1), insert, ...this.value.slice(-1)]
                : [...this.value, insert];
            if (focus)
                this.focusLast(true);
        };
        this.handleOther = () => {
            this.other = !this.other;
            this.value = this.other
                ? [...this.value, { text: this.labelOCOther }]
                : this.value.slice(0, -1);
            this.onOther.emit(this.other);
        };
        this.handleRemove = (index) => {
            const copy = [...this.value];
            copy.splice(index, 1);
            this.value = copy;
            this.el.dispatchEvent(new NativeEvent('input'));
        };
        this.handleImage = (index) => {
            const current = this.value[index];
            if (current.image)
                this.deleteImage(current, index);
            else
                this.uploadImage(index);
        };
    }
    watchValue(value) {
        if (!value.length)
            this.handleAdd(false);
    }
    async focusLast(nextTick = false) {
        if (nextTick)
            await new Promise(res => setTimeout(res, 100));
        // Find last input element
        const options = this.el.querySelectorAll('[data-option]');
        const option = options[options.length - (this.other ? 2 : 1)];
        const input = option && option.querySelector('bce-input input');
        // Set focus to new element
        if (input)
            input.focus();
    }
    async uploadImage(index) {
        const root = this.el.closest('bce-root');
        const input = document.createElement('bce-upload-input');
        // Trigger upload button
        const file = await root.execute(input, res => {
            input.addEventListener('file', e => {
                e.cancelBubble = true;
                res(e.detail);
            });
            input.upload();
        });
        // Emit file
        this.onFile.emit(file);
        // Update value
        const copy = [...this.value];
        copy.splice(index, 1, Object.assign({}, this.value[index], { image: file.path }));
        // Emit value
        this.value = copy;
        this.el.dispatchEvent(new NativeEvent('input'));
    }
    deleteImage(option, index) {
        if (!option.image)
            return;
        // Emit file delete
        const match = option.image.match(/BCE:\/\/([^/]+)\//);
        if (match)
            this.onFileDelete.emit({ id: match[1], path: option.image });
        // Update value
        const copy = [...this.value];
        const value = Object.assign({}, this.value[index]);
        delete value.image;
        copy.splice(index, 1, value);
        // Emit value
        this.value = copy;
        this.el.dispatchEvent(new NativeEvent('input'));
    }
    componentDidLoad() {
        this.watchValue(this.value);
    }
    renderTooltip(icon, content) {
        if (!content)
            return null;
        return (h("bce-tooltip", { placement: "left", icon: icon }, content));
    }
    renderMetadata(option) {
        if (!option.image)
            return;
        return h("div", { "data-meta": true }, this.renderTooltip('fas:image', option.image));
    }
    renderOption(option, index, other = false) {
        if (!option.hasOwnProperty('text'))
            return null;
        const placeholder = this.placeholder && `${this.placeholder} ${index + 1}`;
        return (h("div", { key: index, "data-option": true },
            h("bce-input", { value: option.text, onInput: e => this.handleInput(e, index), onKeyDown: this.handleKeyDown, placeholder: placeholder }),
            h("bce-icon", { raw: other ? 'fas:font' : this.icon, "fixed-width": true }),
            this.renderMetadata(option),
            h("bce-dropdown-menu", null,
                !other && (h("bce-button", { icon: "fas:image", onClick: () => this.handleImage(index) },
                    option.image ? this.labelOCRemoveButton : this.labelOCAddButton,
                    "\u00A0",
                    this.labelOCImage)),
                this.value.length > 1 && (h("bce-button", { icon: "fas:trash", onClick: () => this.handleRemove(index) }, this.labelOCRemoveButton)),
                h("slot", { name: "option" }))));
    }
    render() {
        const options = this.other ? this.value.slice(0, -1) : this.value;
        const other = this.other && this.value[this.value.length - 1];
        return [
            this.label && h("label", null, this.label),
            options.map((option, i) => this.renderOption(option, i)),
            other && this.renderOption(other, this.value.length - 1, true),
            h("slot", null),
            h("div", null,
                h("bce-button", { type: "text", icon: "fas:plus", onClick: () => this.handleAdd() },
                    this.labelOCAddButton,
                    " ",
                    this.placeholder),
                this.allowOther && (h("bce-button", { type: "text", icon: "fas:font", onClick: this.handleOther },
                    this.other ? this.labelOCRemoveButton : this.labelOCAddButton,
                    "\u00A0\"",
                    this.labelOCOther,
                    "\"")),
                h("slot", { name: "action" }))
        ];
    }
    static get is() { return "bce-option-creator"; }
    static get originalStyleUrls() { return {
        "$": ["bce-option-creator.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["bce-option-creator.css"]
    }; }
    static get properties() { return {
        "value": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "Block.ElementOption[]",
                "resolved": "ElementOption[]",
                "references": {
                    "Block": {
                        "location": "import",
                        "path": "../../models/block"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "defaultValue": "[]"
        },
        "icon": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "icon",
            "reflect": true
        },
        "allowOther": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "allow-other",
            "reflect": true,
            "defaultValue": "false"
        },
        "other": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "other",
            "reflect": false,
            "defaultValue": "false"
        },
        "labelOCAddButton": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-o-c-add-button",
            "reflect": false,
            "defaultValue": "'Add'"
        },
        "labelOCRemoveButton": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-o-c-remove-button",
            "reflect": false,
            "defaultValue": "'Delete'"
        },
        "labelOCOther": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-o-c-other",
            "reflect": false,
            "defaultValue": "'Other'"
        },
        "labelOCImage": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-o-c-image",
            "reflect": false,
            "defaultValue": "'Image'"
        },
        "label": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label",
            "reflect": false
        },
        "placeholder": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "placeholder",
            "reflect": false
        }
    }; }
    static get events() { return [{
            "method": "onOther",
            "name": "other",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            }
        }, {
            "method": "onFile",
            "name": "file",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "File",
                "resolved": "File",
                "references": {
                    "File": {
                        "location": "import",
                        "path": "../../utils/file"
                    }
                }
            }
        }, {
            "method": "onFileDelete",
            "name": "file-delete",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "{ id: string; path: string }",
                "resolved": "{ id: string; path: string; }",
                "references": {}
            }
        }]; }
    static get methods() { return {
        "focusLast": {
            "complexType": {
                "signature": "(nextTick?: boolean) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "HTMLInputElement": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "el"; }
    static get watchers() { return [{
            "propName": "value",
            "methodName": "watchValue"
        }]; }
}
