import { PlatformServiceName, } from "@limetech/lime-web-components";
import { h, } from "@stencil/core";
/**
 * This component is used to provide a more visual way of selecting
 * a custom web component or a command.
 * Instead of manually typing the name of the component,
 * users can visually pick the desired component from a list.
 *
 * @beta
 *
 * @exampleComponent limebb-example-web-component-picker
 * @exampleComponent limebb-example-command-picker
 */
export class ComponentPicker {
    constructor() {
        /**
         * The type of items to display in the picker
         */
        this.type = 'component';
        /**
         * The label for the copy button
         */
        this.copyLabel = 'Copy value';
        /**
         * Whether to hide the copy button
         */
        this.hideCopyButton = false;
        this.allItems = [];
        this.getConfigs = () => {
            const fields = {
                component: () => this.webComponentRegistry.getAll(),
                command: () => this.commandbus.getAll(),
            };
            return fields[this.type]();
        };
        this.getConfigValue = (config) => {
            if ('name' in config && typeof config.name === 'string') {
                return config.name;
            }
            if ('id' in config && typeof config.id === 'string') {
                return config.id;
            }
            return '';
        };
        this.hasTag = (config) => {
            if (!this.tags) {
                return true;
            }
            return this.tags.some((tag) => { var _a; return (_a = config.tags) === null || _a === void 0 ? void 0 : _a.includes(tag); });
        };
        this.handleBlur = () => {
            this.emitIfValidValue(this.currentInput);
        };
        this.handleChange = (event) => {
            var _a;
            event.stopPropagation();
            this.change.emit((_a = event.detail) === null || _a === void 0 ? void 0 : _a.value);
        };
        this.handleCopyButton = () => {
            navigator.clipboard.writeText(this.value);
            this.copy.emit(this.value);
        };
        this.handleKeyUp = (event) => {
            if (event.key !== 'Enter') {
                return;
            }
            this.emitIfValidValue(this.currentInput);
        };
        this.emitIfValidValue = (value) => {
            if (this.isValidIdentifier(value)) {
                this.change.emit(value);
            }
        };
        this.isValidIdentifier = (identifier) => {
            if (!identifier) {
                return false;
            }
            if (this.type === 'component') {
                return Boolean(customElements.get(identifier));
            }
            return this.allItems.some((item) => item.value === identifier);
        };
        this.renderPicker = () => {
            let value = this.allItems.find((item) => this.value === item.value);
            if (!value && this.value) {
                value = {
                    text: this.value,
                    value: this.value,
                    icon: {
                        name: 'question',
                        color: 'rgb(var(--color-glaucous-light))',
                    },
                };
            }
            return (h("limel-picker", { disabled: this.disabled, helperText: this.helperText, label: this.label, readonly: this.readonly, required: this.required, searcher: this.search, value: value, title: value === null || value === void 0 ? void 0 : value.text, onBlur: this.handleBlur, onChange: this.handleChange, onKeyUp: this.handleKeyUp }));
        };
        this.renderCopyButton = () => {
            if (this.hideCopyButton) {
                return;
            }
            return (h("limel-icon-button", { icon: "copy", disabled: !this.value, label: this.copyLabel, onClick: this.handleCopyButton }));
        };
        this.search = async (query) => {
            if (!query) {
                return this.allItems;
            }
            return this.allItems.filter(this.isItemMatching(query.toLocaleLowerCase()));
        };
        this.isItemMatching = (query) => (item) => {
            const queryParts = query.split(/\s+/);
            return queryParts.every((part) => {
                var _a, _b;
                return item.text.toLocaleLowerCase().includes(part) ||
                    ((_a = item.secondaryText) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase().includes(part)) ||
                    ((_b = item.value) === null || _b === void 0 ? void 0 : _b.toLocaleLowerCase().includes(part));
            });
        };
    }
    componentWillLoad() {
        this.allItems = this.getConfigs()
            .filter(this.hasTag)
            .map((config) => {
            var _a, _b;
            return ({
                value: this.getConfigValue(config),
                text: this.translator.get((_a = config.title) !== null && _a !== void 0 ? _a : this.getConfigValue(config)),
                secondaryText: this.translator.get((_b = config.description) !== null && _b !== void 0 ? _b : ''),
                icon: config.icon,
            });
        })
            .sort((a, b) => a.text.localeCompare(b.text));
    }
    render() {
        return [this.renderPicker(), this.renderCopyButton()];
    }
    get currentInput() {
        var _a, _b, _c, _d, _e, _f, _g;
        return ((_g = (_f = (_e = (_d = (_c = (_b = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('limel-picker')) === null || _b === void 0 ? void 0 : _b.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('limel-chip-set')) === null || _d === void 0 ? void 0 : _d.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('input')) === null || _f === void 0 ? void 0 : _f.value) !== null && _g !== void 0 ? _g : '');
    }
    get webComponentRegistry() {
        return this.platform.get(PlatformServiceName.WebComponentRegistry);
    }
    get commandbus() {
        return this.platform.get(PlatformServiceName.CommandBus);
    }
    get translator() {
        return this.platform.get(PlatformServiceName.Translate);
    }
    static get is() { return "limebb-component-picker"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["component-picker.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["component-picker.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
            },
            "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": "The type of items to display in the picker"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "type",
                "defaultValue": "'component'"
            },
            "tags": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[] | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The tags to filter the items by"
                },
                "getter": false,
                "setter": false
            },
            "value": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The name of the selected component"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value"
            },
            "copyLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The label for the copy button"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "copy-label",
                "defaultValue": "'Copy value'"
            },
            "hideCopyButton": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether to hide the copy button"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "hide-copy-button",
                "defaultValue": "false"
            },
            "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"
            }
        };
    }
    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": "string",
                    "resolved": "string",
                    "references": {}
                }
            }, {
                "method": "copy",
                "name": "copy",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Event that is emitted when the value is copied to the clipboard\n\nThe event detail is the value that was copied"
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "host"; }
}
