var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
        r = Reflect.decorate(decorators, target, key, desc);
    else
        for (var i = decorators.length - 1; i >= 0; i--)
            if (d = decorators[i])
                r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { h } from "@stencil/core";
import { PlatformServiceName, SelectLimeTypes as Limetypes, } from "@limetech/lime-web-components";
import { getPropertyFromPath, getNormalizedProperties, } from "../property-resolution";
import { getIcon } from "../../../util/limetype";
/**
 * Property Selector Component
 *
 * A menu-based property selector that allows users to navigate through properties
 * and relations, only emitting complete property paths (not intermediate relations).
 *
 * Similar to limec-context-expression but specifically for selecting properties
 * with dot-notation paths.
 *
 * Features:
 * - Menu-based navigation through properties
 * - Submenu support for drilling into relations
 * - Internal state management during navigation
 * - Only emits complete paths (leaf properties)
 * - Chip-set display showing current path
 * @private
 */
export class PropertySelector {
    constructor() {
        /**
         * Label for the input
         */
        this.label = 'Property';
        /**
         * Whether the field is required
         */
        this.required = false;
        this.isOpen = false;
        this.navigationPath = '';
        this.menuItems = [];
        this.handleChipSetWrapperClick = (event) => {
            // Stop all clicks on the chip-set from bubbling
            // This prevents the menu from opening when clicking chip remove buttons
            event.stopPropagation();
        };
        this.handleChipSetFocus = () => {
            // Open menu when the chip-set input receives focus
            // This happens when user clicks to type/edit
            if (!this.isOpen) {
                this.navigationPath = this.value || '';
                this.loadMenuItems();
                this.isOpen = true;
            }
        };
        this.handleSelect = (event) => {
            event.stopPropagation();
            const selectedPath = event.detail.value;
            if (!selectedPath) {
                return;
            }
            // Check if this is a complete path (leaf property, not a relation)
            const property = getPropertyFromPath(this.limetypes, this.limetype, selectedPath);
            if (property === null || property === void 0 ? void 0 : property.relation) {
                // This is a relation - update navigation but don't emit
                this.navigationPath = selectedPath;
            }
            else {
                // This is a leaf property - emit and close
                this.change.emit(selectedPath);
                this.isOpen = false;
                this.navigationPath = '';
            }
        };
        this.handleNavigateMenu = (event) => {
            var _a;
            event.stopPropagation();
            if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a.value) {
                // Update navigation path when drilling down
                this.navigationPath = event.detail.value;
            }
        };
        this.handleCancel = () => {
            this.isOpen = false;
            this.navigationPath = '';
        };
        this.handleChipSetChange = (event) => {
            event.stopPropagation();
            const detail = event.detail;
            // Handle both single chip and array of chips
            if (!detail) {
                // Clear all was clicked
                this.change.emit('');
                this.navigationPath = '';
                return;
            }
            // Convert to array if it's a single chip
            const chips = Array.isArray(detail) ? detail : [detail];
            if (chips.length === 0) {
                // All chips removed
                this.change.emit('');
                this.navigationPath = '';
            }
            else {
                // A chip was removed - emit the last remaining chip's value
                const lastChip = chips.at(-1);
                if (lastChip) {
                    this.change.emit(lastChip.value);
                }
                this.navigationPath = '';
            }
        };
    }
    componentWillLoad() {
        const language = this.platform
            .get(PlatformServiceName.Application)
            .getLanguage();
        this.collator = new Intl.Collator(language, {
            numeric: true,
            sensitivity: 'base',
        });
    }
    render() {
        if (!this.limetype || !this.limetypes) {
            return null;
        }
        const chips = this.getChipsForPath(this.navigationPath || this.value || '');
        return (h("limel-menu", { items: this.menuItems, open: this.isOpen, emptyResultMessage: "No available properties", surfaceWidth: "inherit-from-trigger", openDirection: "bottom-end", onSelect: this.handleSelect, onNavigateMenu: this.handleNavigateMenu, onCancel: this.handleCancel }, h("div", { slot: "trigger" }, h("div", { onClick: this.handleChipSetWrapperClick }, h("limel-chip-set", { type: "input", label: this.label, value: chips, required: this.required, helperText: this.helperText, delimiter: "\u203A", maxItems: 1, onChange: this.handleChipSetChange, onFocus: this.handleChipSetFocus })))));
    }
    loadMenuItems() {
        // Get the limetype we're currently navigating in
        const currentLimetype = this.getCurrentLimetype();
        if (!currentLimetype) {
            this.menuItems = [];
            return;
        }
        this.menuItems = this.createMenuItems(currentLimetype, '');
    }
    getCurrentLimetype() {
        if (!this.navigationPath) {
            return this.limetypes[this.limetype];
        }
        // Get the limetype at the current navigation path
        const property = getPropertyFromPath(this.limetypes, this.limetype, this.navigationPath);
        if (property === null || property === void 0 ? void 0 : property.relation) {
            return property.relation.getLimetype();
        }
        return this.limetypes[this.limetype];
    }
    createMenuItems(limetype, pathPrefix) {
        const results = [];
        if (!limetype) {
            return results;
        }
        const normalizedProperties = getNormalizedProperties(limetype);
        for (const [propName, property] of Object.entries(normalizedProperties)) {
            // Skip hasMany and hasAndBelongsToMany relations
            if (property.type === 'hasmany' ||
                property.type === 'hasandbelongstomany') {
                continue;
            }
            const fullPath = pathPrefix
                ? `${pathPrefix}.${propName}`
                : propName;
            const isRelation = !!property.relation;
            let items;
            if (isRelation && property.relation) {
                // Create submenu for relation (only belongsto at this point)
                const relatedLimetype = property.relation.getLimetype();
                if (relatedLimetype) {
                    items = async () => this.createMenuItems(relatedLimetype, fullPath);
                }
            }
            results.push({
                text: property.localname || propName,
                secondaryText: this.getSecondaryText(property),
                icon: this.getIconForProperty(property),
                value: fullPath,
                items: items,
            });
        }
        // Sort properties alphabetically by display text
        results.sort((a, b) => { var _a, _b; return this.collator.compare((_a = a.text) !== null && _a !== void 0 ? _a : '', (_b = b.text) !== null && _b !== void 0 ? _b : ''); });
        if (results.length === 0) {
            return [
                {
                    text: 'No available properties',
                    value: '',
                    disabled: true,
                },
            ];
        }
        return results;
    }
    getSecondaryText(property) {
        var _a;
        if (property.relation) {
            const relatedLimetype = property.relation.getLimetype();
            return ((_a = relatedLimetype === null || relatedLimetype === void 0 ? void 0 : relatedLimetype.localname) === null || _a === void 0 ? void 0 : _a.singular) || 'Object';
        }
        // Return the property type as the secondary text
        return property.type.charAt(0).toUpperCase() + property.type.slice(1);
    }
    getIconForProperty(property) {
        if (property.relation) {
            return getIcon(property.relation.getLimetype());
        }
        // Use generic property icon
        return {
            name: 'dot_circle',
            color: 'rgb(var(--color-gray-default))',
        };
    }
    getChipsForPath(path) {
        if (!path) {
            return [];
        }
        const parts = path.split('.');
        const chips = [];
        let currentLimetype = this.limetypes[this.limetype];
        let currentPath = '';
        for (const part of parts) {
            currentPath = currentPath ? `${currentPath}.${part}` : part;
            // Use getNormalizedProperties to include _id and _timestamp
            const normalizedProperties = getNormalizedProperties(currentLimetype);
            const property = normalizedProperties[part];
            if (property) {
                chips.push({
                    id: currentPath,
                    text: property.localname || part,
                    icon: this.getIconForProperty(property),
                    value: currentPath,
                });
                if (property.relation) {
                    currentLimetype = property.relation.getLimetype();
                }
            }
        }
        return chips;
    }
    static get is() { return "limebb-property-selector"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["property-selector.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["property-selector.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": "Platform service provider"
                },
                "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": "Component context"
                },
                "getter": false,
                "setter": false
            },
            "limetype": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The limetype to select properties from"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "limetype"
            },
            "value": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Current complete property path value"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Label for the input"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "label",
                "defaultValue": "'Property'"
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether the field is required"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "required",
                "defaultValue": "false"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Helper text to display"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "helper-text"
            }
        };
    }
    static get states() {
        return {
            "limetypes": {},
            "isOpen": {},
            "navigationPath": {}
        };
    }
    static get events() {
        return [{
                "method": "change",
                "name": "change",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when a complete property path is selected"
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }];
    }
}
__decorate([
    Limetypes()
], PropertySelector.prototype, "limetypes", void 0);
