import { h } from "@stencil/core";
import { PlatformServiceName, } from "@limetech/lime-web-components";
import { DEFAULT_ALLOWED_PROPERTY_TYPES, RELATION_PROPERTY_TYPES, } from "../property-types";
import { getIcon } from "../../../util/limetype";
import { isEqual, isString } from "lodash-es";
import { isNonNull } from "../../../util/non-null";
const allNonSystemPropertyTypes = DEFAULT_ALLOWED_PROPERTY_TYPES.filter((propertyType) => propertyType !== 'system');
allNonSystemPropertyTypes.push(...RELATION_PROPERTY_TYPES);
/**
 * Limetype Field Component
 *
 * A dropdown selector for choosing a limetype (object type) from the available
 * limetypes in the system.
 *
 * This component:
 * - Displays all limetypes with their icons and localized names
 * - Supports restricting to a specific list of limetypes
 * - Can update dependent property-path fields when selection changes
 * - Implements the FormComponent interface for use in forms
 *
 * Common use cases:
 * - Selecting which object type to query in a lime query builder
 * - Choosing target limetype for relations
 * - Configuring limetype-dependent settings
 *
 * @private
 */
export class LimetypeField {
    constructor() {
        /**
         * A list of property fields that should be updated when the selected limetype changes.
         */
        this.propertyFields = [];
        /**
         * The name of this field. May be used as reference when a property mapping
         * depends on the selected limetype.
         */
        this.fieldName = 'limetype';
        this.handleChange = (event) => {
            event.stopPropagation();
            let selectedLimetype = '';
            if (event.detail && 'value' in event.detail) {
                selectedLimetype = event.detail.value;
            }
            this.change.emit(selectedLimetype || undefined);
        };
    }
    componentWillLoad() {
        const language = this.platform
            .get(PlatformServiceName.Application)
            .getLanguage();
        this.collator = new Intl.Collator(language, {
            numeric: true,
            sensitivity: 'base',
        });
    }
    componentShouldUpdate(newValue, oldValue, property) {
        var _a, _b;
        return (property !== 'formInfo' ||
            !isEqual((_a = newValue === null || newValue === void 0 ? void 0 : newValue.schema) === null || _a === void 0 ? void 0 : _a.oneOf, (_b = oldValue === null || oldValue === void 0 ? void 0 : oldValue.schema) === null || _b === void 0 ? void 0 : _b.oneOf));
    }
    render() {
        var _a;
        const options = this.getLimeTypes().map(limeTypeToOption);
        options.sort((a, b) => this.collator.compare(a.text, b.text));
        let selectedOption = options.find((option) => option.value === this.value);
        let invalid = this.invalid;
        if (this.value && !selectedOption) {
            invalid = true;
            options.unshift({
                text: ((_a = this.limeTypeRepository.getLimeType(this.value)) === null || _a === void 0 ? void 0 : _a.localname.singular) || this.value,
                value: this.value,
            });
            selectedOption = options[0];
        }
        const emptyOption = {
            text: '',
            value: '',
        };
        options.unshift(emptyOption);
        return (h("limel-select", { key: '20a7d5eb86c746d11ad805083be5ef9f5fd2397d', label: this.label, options: options, value: selectedOption, required: this.required, helperText: this.helperText, invalid: invalid, disabled: this.disabled || this.readonly, onChange: this.handleChange }));
    }
    componentWillRender() {
        this.updatePropertyFields(this.value || '');
    }
    getLimeTypes() {
        var _a, _b;
        let limetypes = this.limetypes;
        if ((_b = (_a = this.formInfo) === null || _a === void 0 ? void 0 : _a.schema) === null || _b === void 0 ? void 0 : _b.oneOf) {
            limetypes = this.formInfo.schema.oneOf
                .map((choice) => choice.const)
                .filter(isString);
        }
        if (!limetypes) {
            return this.limeTypeRepository.getLimeTypes();
        }
        return limetypes
            .map((limetype) => this.limeTypeRepository.getLimeType(limetype))
            .filter(isNonNull);
    }
    updatePropertyFields(selectedLimetype) {
        for (const field of this.propertyFields) {
            field.limetype = selectedLimetype;
            if (field.allowedPropertyTypes === DEFAULT_ALLOWED_PROPERTY_TYPES) {
                field.allowedPropertyTypes = allNonSystemPropertyTypes;
            }
        }
    }
    get limeTypeRepository() {
        return this.platform.get(PlatformServiceName.LimeTypeRepository);
    }
    static get is() { return "limebb-limetype-field"; }
    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": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "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": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "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
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "The label of the current property"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "label"
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "Whether or not the current property is required"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "required"
            },
            "readonly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "Whether or not the current property is readonly"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "readonly"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "Whether or not the current property is disabled"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled"
            },
            "value": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "The value of the current property"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "value"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "The helper text for the current property"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "helper-text"
            },
            "invalid": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "invalid"
            },
            "limetypes": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[] | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The limetypes to choose from"
                },
                "getter": false,
                "setter": false
            },
            "propertyFields": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "DependentPropertyField[]",
                    "resolved": "DependentPropertyField[]",
                    "references": {
                        "DependentPropertyField": {
                            "location": "global",
                            "id": "global::DependentPropertyField"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A list of property fields that should be updated when the selected limetype changes."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "fieldName": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The name of this field. May be used as reference when a property mapping\ndepends on the selected limetype."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "field-name",
                "defaultValue": "'limetype'"
            },
            "formInfo": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "FormInfo",
                    "resolved": "FormInfo | undefined",
                    "references": {
                        "FormInfo": {
                            "location": "import",
                            "path": "@limetech/lime-elements",
                            "id": "node_modules::FormInfo",
                            "referenceLocation": "FormInfo"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "Additional contextual information about the form"
                },
                "getter": false,
                "setter": false
            }
        };
    }
    static get events() {
        return [{
                "method": "change",
                "name": "change",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "The event to emit when the value of the current property has changed"
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }];
    }
}
const limeTypeToOption = (limetype) => ({
    text: limetype.localname.singular,
    value: limetype.name,
    icon: getIcon(limetype),
});
