import { faAngleRight, faPlus, faSearch, faTrash } from '@fortawesome/free-solid-svg-icons';
import { library } from '@fortawesome/fontawesome-svg-core';
import { h } from "@stencil/core";
import { ModuleFlow } from '../../models/module';
import { FlowTree } from '../../utils/flow-tree';
import { NativeEvent } from '../../utils/native-event';
library.add(faAngleRight, faPlus, faSearch, faTrash);
export class BceFlowEditor {
    constructor() {
        this.value = Object.assign({}, ModuleFlow.empty(), { start: { id: '<start>', version: 'v1' } });
        this.current = '';
        this.currentVersion = '';
        this.labelTitle = 'Define what happens next';
        this.labelSubtitle = 'Use the module-graph, or the buttons below to define what happens after this screen.';
        this.labelOptionEnd = 'Nothing, the module will end';
        this.labelOptionNext = 'Another screen is shown';
        this.labelOptionConditional = "One of the following screen's is shown";
        this.labelActionEnd = 'Complete module';
        this.labelActionOpen = 'Show screen';
        this.labelActionDelete = 'Delete screen';
        this.labelActionAdd = 'Add screen';
        this.labelConditionScreen = 'Screen';
        this.labelConditionOther = 'In all other cases';
        this.handleInput = (event) => {
            this.value = event.target.value;
            this.el.dispatchEvent(new NativeEvent('input'));
        };
        this.handleEndInput = async (event) => {
            event.cancelBubble = true;
            const editor = document.querySelector('bce-flow-graph');
            if (!editor)
                return;
            const end = event.target.value === 'true';
            if (!end) {
                const target = { id: this.current, version: this.currentVersion };
                return editor.addBlock(target);
            }
            const tasks = this.next.map(t => editor.unlink(this.current, t.id));
            await Promise.all(tasks);
            return;
        };
        this.handleConditionInput = (event, index) => {
            const target = event.target;
            if (!target)
                return;
            const current = this.next[index];
            const copy = [...this.next];
            copy.splice(index, 1, Object.assign({}, current, { condition: target.value }));
            this.value = Object.assign({}, this.value, { blocks: Object.assign({}, this.value.blocks, { [this.current]: copy }) });
            this.el.dispatchEvent(new NativeEvent('input'));
        };
        this.handleCompleteModule = () => {
            this.onComplete.emit();
        };
        this.handleShowBlock = () => {
            const { id, version } = this.next[0];
            this.onNode.emit({ id, version });
        };
        this.handleDeleteBlock = () => {
            const editor = document.querySelector('bce-flow-graph');
            if (!editor)
                return;
            const target = this.next[0];
            return editor.deleteBlock(target);
        };
        this.handleAddBlock = () => {
            const editor = document.querySelector('bce-flow-graph');
            if (!editor)
                return;
            const target = { id: this.current, version: this.currentVersion };
            return editor.addBlock(target);
        };
    }
    get tree() {
        return new FlowTree(this.value);
    }
    get next() {
        return (this.value.blocks && this.value.blocks[this.current]) || [];
    }
    get end() {
        return !this.next.length || !this.next[0].id;
    }
    getLabel(ref) {
        return [
            this.labelConditionScreen,
            this.tree.getLabel(ref.id, ref.version)
        ].join(' ');
    }
    renderEnd() {
        return (h("bce-button", { type: "text", onClick: this.handleCompleteModule },
            this.labelActionEnd,
            " ",
            h("bce-icon", { raw: "fas:angle-right" })));
    }
    renderSingleCtrl() {
        return [
            h("bce-button", { type: "text", icon: "fas:search", onClick: this.handleShowBlock }, this.labelActionOpen),
            h("bce-button", { type: "text", icon: "fas:trash", onClick: this.handleDeleteBlock }, this.labelActionDelete)
        ];
    }
    renderConditionalCtrl() {
        return this.next.map((n, i) => (h("bce-input", { type: "container", key: n.id, label: this.getLabel(n) }, this.next.length !== i + 1 ? (h("bce-code-editor", { value: n.condition || ModuleFlow.DEFAULT_CONDITION, onInput: e => this.handleConditionInput(e, i) })) : (h("p", null, this.labelConditionOther)))));
    }
    renderCtrl() {
        return [
            this.next.length > 1
                ? this.renderConditionalCtrl()
                : this.renderSingleCtrl(),
            h("bce-button", { type: "text", icon: "fas:plus", onClick: this.handleAddBlock }, this.labelActionAdd)
        ];
    }
    renderFooter() {
        return [
            h("bce-input", { type: "radio", key: '' + this.end, value: '' + this.end, onInput: this.handleEndInput },
                h("bce-option", { value: "true" }, this.labelOptionEnd),
                h("bce-option", { value: "false" }, this.next.length > 1
                    ? this.labelOptionConditional
                    : this.labelOptionNext)),
            this.end ? this.renderEnd() : this.renderCtrl()
        ];
    }
    render() {
        return [
            this.labelTitle && h("h5", null, this.labelTitle),
            this.labelSubtitle && h("p", null, this.labelSubtitle),
            h("bce-flow-graph", { value: this.value, current: this.current, createId: this.createId, existing: this.existing, editable: true, onInput: this.handleInput }),
            this.current && this.renderFooter()
        ];
    }
    static get is() { return "bce-flow-editor"; }
    static get originalStyleUrls() { return {
        "$": ["bce-flow-editor.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["bce-flow-editor.css"]
    }; }
    static get properties() { return {
        "value": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "ModuleFlow",
                "resolved": "ModuleFlow",
                "references": {
                    "ModuleFlow": {
                        "location": "import",
                        "path": "../../models/module"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "defaultValue": "{\n    ...ModuleFlow.empty(),\n    start: { id: '<start>', version: 'v1' }\n  }"
        },
        "current": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "current",
            "reflect": false,
            "defaultValue": "''"
        },
        "currentVersion": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "current-version",
            "reflect": false,
            "defaultValue": "''"
        },
        "existing": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "string[]",
                "resolved": "string[] | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            }
        },
        "createId": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "() => string",
                "resolved": "(() => string) | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            }
        },
        "labelTitle": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-title",
            "reflect": false,
            "defaultValue": "'Define what happens next'"
        },
        "labelSubtitle": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-subtitle",
            "reflect": false,
            "defaultValue": "'Use the module-graph, or the buttons below to define what happens after this screen.'"
        },
        "labelOptionEnd": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-option-end",
            "reflect": false,
            "defaultValue": "'Nothing, the module will end'"
        },
        "labelOptionNext": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-option-next",
            "reflect": false,
            "defaultValue": "'Another screen is shown'"
        },
        "labelOptionConditional": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-option-conditional",
            "reflect": false,
            "defaultValue": "\"One of the following screen's is shown\""
        },
        "labelActionEnd": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-action-end",
            "reflect": false,
            "defaultValue": "'Complete module'"
        },
        "labelActionOpen": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-action-open",
            "reflect": false,
            "defaultValue": "'Show screen'"
        },
        "labelActionDelete": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-action-delete",
            "reflect": false,
            "defaultValue": "'Delete screen'"
        },
        "labelActionAdd": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-action-add",
            "reflect": false,
            "defaultValue": "'Add screen'"
        },
        "labelConditionScreen": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-condition-screen",
            "reflect": false,
            "defaultValue": "'Screen'"
        },
        "labelConditionOther": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "label-condition-other",
            "reflect": false,
            "defaultValue": "'In all other cases'"
        }
    }; }
    static get events() { return [{
            "method": "onNode",
            "name": "node",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "Reference",
                "resolved": "{ id: string; version: string; }",
                "references": {
                    "Reference": {
                        "location": "import",
                        "path": "../../models/reference"
                    }
                }
            }
        }, {
            "method": "onComplete",
            "name": "complete-module",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }]; }
    static get elementRef() { return "el"; }
}
