import { LimeWebComponentTemplate } from "../../../util/web-component-template";
import { PlatformServiceName, } from "@limetech/lime-web-components";
import { h, } from "@stencil/core";
import { get } from "lodash-es";
/**
 * This component must be used in a limel-form
 * where the Command ID OR component name exists in the same section as the config.
 *
 * @beta
 *
 * @exampleComponent limebb-example-command-config
 * @exampleComponent limebb-example-component-config
 */
export class ComponentConfig {
    constructor() {
        this.value = {};
        /**
         * If the value should be fetched from the commandbus or the web component registry
         */
        this.type = 'component';
        this.configViewType = 'code';
        this.findConfigComponent = (name) => {
            var _a, _b;
            if (this.type === 'component') {
                return (_a = this.registry.getAll().find((config) => config.name === name)) === null || _a === void 0 ? void 0 : _a.configComponent;
            }
            if (this.type === 'command') {
                return (_b = this.commandbus.getAll().find((config) => config.id === name)) === null || _b === void 0 ? void 0 : _b.configComponent;
            }
        };
        this.handleChangeMode = (event) => {
            event.stopPropagation();
            this.configViewType = event.detail.id;
        };
        this.handleCodeEditorChange = (event) => {
            event.stopPropagation();
            try {
                const value = JSON.parse(event.detail);
                this.change.emit(value);
            }
            catch (_a) {
                // Ignore invalid JSON
            }
        };
    }
    componentWillLoad() {
        this.configComponent = this.getComponentName();
    }
    componentShouldUpdate(_newValue, _oldValue, property) {
        return property !== 'formInfo';
    }
    watchFormInfo() {
        this.configComponent = this.getComponentName();
    }
    watchconfigComponent(newValue, oldValue) {
        if (newValue && !oldValue) {
            this.configViewType = 'config';
        }
        if (!newValue) {
            this.configViewType = 'code';
        }
    }
    getComponentName() {
        var _a, _b, _c;
        const section = (_b = (_a = this.formInfo) === null || _a === void 0 ? void 0 : _a.schemaPath.slice(0, -1)) !== null && _b !== void 0 ? _b : [];
        const path = [...section, this.getNameField()];
        const name = get((_c = this.formInfo) === null || _c === void 0 ? void 0 : _c.rootValue, path);
        const configComponent = this.findConfigComponent(name);
        if (configComponent && customElements.get(configComponent.name)) {
            return configComponent;
        }
    }
    render() {
        return [this.renderHeader(), this.renderContent()];
    }
    renderHeader() {
        let buttons = [];
        if (this.configComponent) {
            buttons = [
                {
                    id: 'config',
                    title: 'Config',
                    selected: this.configViewType === 'config',
                },
                {
                    id: 'code',
                    title: 'Code',
                    selected: this.configViewType === 'code',
                },
            ];
        }
        return (h("limel-header", { icon: "edit_property", heading: this.label, subheading: this.helperText }, h("limel-button-group", { slot: "actions", value: buttons, onChange: this.handleChangeMode })));
    }
    renderContent() {
        if (this.configViewType === 'config') {
            return this.renderConfigComponent();
        }
        return this.renderCodeEditor();
    }
    renderCodeEditor() {
        return (h("limel-code-editor", { value: JSON.stringify(this.value, null, '\t'), language: "json", readonly: this.readonly, lineNumbers: true, fold: true, lint: true, onChange: this.handleCodeEditorChange }));
    }
    renderConfigComponent() {
        var _a, _b;
        return (h(LimeWebComponentTemplate, { class: "config-component", platform: this.platform, context: this.context,
            // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
            name: (_a = this.configComponent) === null || _a === void 0 ? void 0 : _a.name, props: Object.assign(Object.assign({}, (_b = this.configComponent) === null || _b === void 0 ? void 0 : _b.props), { value: this.value, required: this.required, readonly: this.readonly, disabled: this.disabled, label: this.label, helperText: this.helperText, formInfo: this.formInfo }) }));
    }
    getNameField() {
        if (this.nameField) {
            return this.nameField;
        }
        const fields = {
            component: 'name',
            command: 'id',
        };
        return fields[this.type];
    }
    get registry() {
        return this.platform.get(PlatformServiceName.WebComponentRegistry);
    }
    get commandbus() {
        return this.platform.get(PlatformServiceName.CommandBus);
    }
    static get is() { return "limebb-component-config"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["component-config.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["component-config.css"]
        };
    }
    static get properties() {
        return {
            "platform": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "LimeWebComponentPlatform",
                    "resolved": "LimeWebComponentPlatform",
                    "references": {
                        "LimeWebComponentPlatform": {
                            "location": "import",
                            "path": "@limetech/lime-web-components",
                            "id": "node_modules::LimeWebComponentPlatform",
                            "referenceLocation": "LimeWebComponentPlatform"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
                },
                "getter": false,
                "setter": false
            },
            "context": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "LimeWebComponentContext",
                    "resolved": "LimeWebComponentContext",
                    "references": {
                        "LimeWebComponentContext": {
                            "location": "import",
                            "path": "@limetech/lime-web-components",
                            "id": "node_modules::LimeWebComponentContext",
                            "referenceLocation": "LimeWebComponentContext"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
                },
                "getter": false,
                "setter": false
            },
            "value": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Record<string, unknown>",
                    "resolved": "string | unknown",
                    "references": {
                        "Record": {
                            "location": "global",
                            "id": "global::Record"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The value of the current property"
                },
                "getter": false,
                "setter": false,
                "defaultValue": "{}"
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether or not the current property is required"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "required"
            },
            "readonly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether or not the current property is readonly"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "readonly"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether or not the current property is disabled"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The label of the current property"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "label"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The helper text for the current property"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "helper-text"
            },
            "formInfo": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "FormInfo | undefined",
                    "resolved": "FormInfo | undefined",
                    "references": {
                        "FormInfo": {
                            "location": "import",
                            "path": "@limetech/lime-elements",
                            "id": "node_modules::FormInfo",
                            "referenceLocation": "FormInfo"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Additional contextual information about the form"
                },
                "getter": false,
                "setter": false
            },
            "type": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "ComponentPickerType",
                    "resolved": "\"command\" | \"component\"",
                    "references": {
                        "ComponentPickerType": {
                            "location": "import",
                            "path": "../types",
                            "id": "src/components/component-command-picker/types.ts::ComponentPickerType",
                            "referenceLocation": "ComponentPickerType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If the value should be fetched from the commandbus or the web component registry"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "type",
                "defaultValue": "'component'"
            },
            "nameField": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The name of the field that contains the component name or command id\nIf not provided, it will be based on the `type` prop\n\n`component` -> `name`\n`command` -> `id`"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "name-field"
            }
        };
    }
    static get states() {
        return {
            "configComponent": {},
            "configViewType": {}
        };
    }
    static get events() {
        return [{
                "method": "change",
                "name": "change",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "The event to emit when the value of the current property has changed"
                },
                "complexType": {
                    "original": "Record<string, unknown>",
                    "resolved": "string | unknown",
                    "references": {
                        "Record": {
                            "location": "global",
                            "id": "global::Record"
                        }
                    }
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "formInfo",
                "methodName": "watchFormInfo"
            }, {
                "propName": "configComponent",
                "methodName": "watchconfigComponent"
            }];
    }
}
