import { __esDecorate, __runInitializers } from "tslib";
import { html } from 'lit';
import { property, state } from 'lit/decorators.js';
import { LitElement } from 'lit';
import { classMap } from 'lit/directives/class-map.js';
import { DataDomain } from '@api-client/core/modeling/DataDomain.js';
import { DataDomainKind, DomainAssociationKind, DomainEntityKind, DomainModelKind, DomainNamespaceKind, DomainPropertyKind, } from '@api-client/core/models/kinds.js';
import { getDomainLabel, getFieldIcon, getDomainIconType } from '../lib/ui_mapping.js';
let DomainNavigation = (() => {
    let _classSuper = LitElement;
    let _instanceExtraInitializers = [];
    let _root_decorators;
    let _root_initializers = [];
    let _root_extraInitializers = [];
    let _set_selected_decorators;
    let _highlighted_decorators;
    let _highlighted_initializers = [];
    let _highlighted_extraInitializers = [];
    let _selectedItems_decorators;
    let _selectedItems_initializers = [];
    let _selectedItems_extraInitializers = [];
    let _selectionType_decorators;
    let _selectionType_initializers = [];
    let _selectionType_extraInitializers = [];
    let _draggedItems_decorators;
    let _draggedItems_initializers = [];
    let _draggedItems_extraInitializers = [];
    let _dragTarget_decorators;
    let _dragTarget_initializers = [];
    let _dragTarget_extraInitializers = [];
    let _openedParents_decorators;
    let _openedParents_initializers = [];
    let _openedParents_extraInitializers = [];
    let _cutItems_decorators;
    let _cutItems_initializers = [];
    let _cutItems_extraInitializers = [];
    let _cutItemsType_decorators;
    let _cutItemsType_initializers = [];
    let _cutItemsType_extraInitializers = [];
    let _focusedItem_decorators;
    let _focusedItem_initializers = [];
    let _focusedItem_extraInitializers = [];
    let _searchQuery_decorators;
    let _searchQuery_initializers = [];
    let _searchQuery_extraInitializers = [];
    let _searchResults_decorators;
    let _searchResults_initializers = [];
    let _searchResults_extraInitializers = [];
    return class DomainNavigation extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _root_decorators = [property({ type: Object })];
            _set_selected_decorators = [property({ type: String })];
            _highlighted_decorators = [property({ type: String })];
            _selectedItems_decorators = [state()];
            _selectionType_decorators = [state()];
            _draggedItems_decorators = [state()];
            _dragTarget_decorators = [state()];
            _openedParents_decorators = [state()];
            _cutItems_decorators = [state()];
            _cutItemsType_decorators = [state()];
            _focusedItem_decorators = [state()];
            _searchQuery_decorators = [state()];
            _searchResults_decorators = [state()];
            __esDecorate(this, null, _root_decorators, { kind: "accessor", name: "root", static: false, private: false, access: { has: obj => "root" in obj, get: obj => obj.root, set: (obj, value) => { obj.root = value; } }, metadata: _metadata }, _root_initializers, _root_extraInitializers);
            __esDecorate(this, null, _set_selected_decorators, { kind: "setter", name: "selected", static: false, private: false, access: { has: obj => "selected" in obj, set: (obj, value) => { obj.selected = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _highlighted_decorators, { kind: "accessor", name: "highlighted", static: false, private: false, access: { has: obj => "highlighted" in obj, get: obj => obj.highlighted, set: (obj, value) => { obj.highlighted = value; } }, metadata: _metadata }, _highlighted_initializers, _highlighted_extraInitializers);
            __esDecorate(this, null, _selectedItems_decorators, { kind: "accessor", name: "selectedItems", static: false, private: false, access: { has: obj => "selectedItems" in obj, get: obj => obj.selectedItems, set: (obj, value) => { obj.selectedItems = value; } }, metadata: _metadata }, _selectedItems_initializers, _selectedItems_extraInitializers);
            __esDecorate(this, null, _selectionType_decorators, { kind: "accessor", name: "selectionType", static: false, private: false, access: { has: obj => "selectionType" in obj, get: obj => obj.selectionType, set: (obj, value) => { obj.selectionType = value; } }, metadata: _metadata }, _selectionType_initializers, _selectionType_extraInitializers);
            __esDecorate(this, null, _draggedItems_decorators, { kind: "accessor", name: "draggedItems", static: false, private: false, access: { has: obj => "draggedItems" in obj, get: obj => obj.draggedItems, set: (obj, value) => { obj.draggedItems = value; } }, metadata: _metadata }, _draggedItems_initializers, _draggedItems_extraInitializers);
            __esDecorate(this, null, _dragTarget_decorators, { kind: "accessor", name: "dragTarget", static: false, private: false, access: { has: obj => "dragTarget" in obj, get: obj => obj.dragTarget, set: (obj, value) => { obj.dragTarget = value; } }, metadata: _metadata }, _dragTarget_initializers, _dragTarget_extraInitializers);
            __esDecorate(this, null, _openedParents_decorators, { kind: "accessor", name: "openedParents", static: false, private: false, access: { has: obj => "openedParents" in obj, get: obj => obj.openedParents, set: (obj, value) => { obj.openedParents = value; } }, metadata: _metadata }, _openedParents_initializers, _openedParents_extraInitializers);
            __esDecorate(this, null, _cutItems_decorators, { kind: "accessor", name: "cutItems", static: false, private: false, access: { has: obj => "cutItems" in obj, get: obj => obj.cutItems, set: (obj, value) => { obj.cutItems = value; } }, metadata: _metadata }, _cutItems_initializers, _cutItems_extraInitializers);
            __esDecorate(this, null, _cutItemsType_decorators, { kind: "accessor", name: "cutItemsType", static: false, private: false, access: { has: obj => "cutItemsType" in obj, get: obj => obj.cutItemsType, set: (obj, value) => { obj.cutItemsType = value; } }, metadata: _metadata }, _cutItemsType_initializers, _cutItemsType_extraInitializers);
            __esDecorate(this, null, _focusedItem_decorators, { kind: "accessor", name: "focusedItem", static: false, private: false, access: { has: obj => "focusedItem" in obj, get: obj => obj.focusedItem, set: (obj, value) => { obj.focusedItem = value; } }, metadata: _metadata }, _focusedItem_initializers, _focusedItem_extraInitializers);
            __esDecorate(this, null, _searchQuery_decorators, { kind: "accessor", name: "searchQuery", static: false, private: false, access: { has: obj => "searchQuery" in obj, get: obj => obj.searchQuery, set: (obj, value) => { obj.searchQuery = value; } }, metadata: _metadata }, _searchQuery_initializers, _searchQuery_extraInitializers);
            __esDecorate(this, null, _searchResults_decorators, { kind: "accessor", name: "searchResults", static: false, private: false, access: { has: obj => "searchResults" in obj, get: obj => obj.searchResults, set: (obj, value) => { obj.searchResults = value; } }, metadata: _metadata }, _searchResults_initializers, _searchResults_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #root_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _root_initializers, void 0));
        /**
         * The root DataDomain to render
         */
        get root() { return this.#root_accessor_storage; }
        set root(value) { this.#root_accessor_storage = value; }
        #selected = __runInitializers(this, _root_extraInitializers);
        /**
         * The currently selected item key.
         * To be used by the parent component to control selection.
         * @attribute selected
         */
        set selected(value) {
            const old = this.#selected;
            this.#selected = value;
            this.requestUpdate('selected', old);
        }
        get selected() {
            return this.#selected;
        }
        #highlighted_accessor_storage = __runInitializers(this, _highlighted_initializers, void 0);
        /**
         * Highlighted item key for visual indication.
         * Highlighted item only renders with a different style. Has no other meaning.
         */
        get highlighted() { return this.#highlighted_accessor_storage; }
        set highlighted(value) { this.#highlighted_accessor_storage = value; }
        #selectedItems_accessor_storage = (__runInitializers(this, _highlighted_extraInitializers), __runInitializers(this, _selectedItems_initializers, new Set()
        /**
         * The type of currently selected items (namespace, model, or entity)
         */
        ));
        /**
         * Currently selected items
         */
        get selectedItems() { return this.#selectedItems_accessor_storage; }
        set selectedItems(value) { this.#selectedItems_accessor_storage = value; }
        #selectionType_accessor_storage = (__runInitializers(this, _selectedItems_extraInitializers), __runInitializers(this, _selectionType_initializers, void 0));
        /**
         * The type of currently selected items (namespace, model, or entity)
         */
        get selectionType() { return this.#selectionType_accessor_storage; }
        set selectionType(value) { this.#selectionType_accessor_storage = value; }
        #draggedItems_accessor_storage = (__runInitializers(this, _selectionType_extraInitializers), __runInitializers(this, _draggedItems_initializers, new Set()
        /**
         * Current drag target
         */
        ));
        /**
         * Items currently being dragged
         */
        get draggedItems() { return this.#draggedItems_accessor_storage; }
        set draggedItems(value) { this.#draggedItems_accessor_storage = value; }
        #dragTarget_accessor_storage = (__runInitializers(this, _draggedItems_extraInitializers), __runInitializers(this, _dragTarget_initializers, void 0));
        /**
         * Current drag target
         */
        get dragTarget() { return this.#dragTarget_accessor_storage; }
        set dragTarget(value) { this.#dragTarget_accessor_storage = value; }
        #openedParents_accessor_storage = (__runInitializers(this, _dragTarget_extraInitializers), __runInitializers(this, _openedParents_initializers, new Set()
        /**
         * Items that have been cut and are waiting to be pasted
         */
        ));
        /**
         * Set of parent items (by key) that are opened/expanded in the view
         */
        get openedParents() { return this.#openedParents_accessor_storage; }
        set openedParents(value) { this.#openedParents_accessor_storage = value; }
        #cutItems_accessor_storage = (__runInitializers(this, _openedParents_extraInitializers), __runInitializers(this, _cutItems_initializers, new Set()
        /**
         * The type of items that were cut
         */
        ));
        /**
         * Items that have been cut and are waiting to be pasted
         */
        get cutItems() { return this.#cutItems_accessor_storage; }
        set cutItems(value) { this.#cutItems_accessor_storage = value; }
        #cutItemsType_accessor_storage = (__runInitializers(this, _cutItems_extraInitializers), __runInitializers(this, _cutItemsType_initializers, void 0));
        /**
         * The type of items that were cut
         */
        get cutItemsType() { return this.#cutItemsType_accessor_storage; }
        set cutItemsType(value) { this.#cutItemsType_accessor_storage = value; }
        #focusedItem_accessor_storage = (__runInitializers(this, _cutItemsType_extraInitializers), __runInitializers(this, _focusedItem_initializers, void 0));
        /**
         * Currently focused item key for keyboard navigation
         */
        get focusedItem() { return this.#focusedItem_accessor_storage; }
        set focusedItem(value) { this.#focusedItem_accessor_storage = value; }
        #searchQuery_accessor_storage = (__runInitializers(this, _focusedItem_extraInitializers), __runInitializers(this, _searchQuery_initializers, void 0));
        /**
         * Current search query
         */
        get searchQuery() { return this.#searchQuery_accessor_storage; }
        set searchQuery(value) { this.#searchQuery_accessor_storage = value; }
        #searchResults_accessor_storage = (__runInitializers(this, _searchQuery_extraInitializers), __runInitializers(this, _searchResults_initializers, []
        /**
         * List of all visible items in navigation order (for keyboard navigation)
         */
        ));
        /**
         * Search results from domain search
         */
        get searchResults() { return this.#searchResults_accessor_storage; }
        set searchResults(value) { this.#searchResults_accessor_storage = value; }
        /**
         * List of all visible items in navigation order (for keyboard navigation)
         */
        visibleItems = (__runInitializers(this, _searchResults_extraInitializers), []);
        // Utility methods for working with selection sets
        /**
         * Check if an item is selected by key
         */
        isItemSelected(key) {
            for (const item of this.selectedItems) {
                if (item.key === key)
                    return true;
            }
            return false;
        }
        /**
         * Check if an item is dragged by key
         */
        isItemDragged(key) {
            for (const item of this.draggedItems) {
                if (item.key === key)
                    return true;
            }
            return false;
        }
        /**
         * Check if an item is cut by key
         */
        isItemCut(key) {
            for (const item of this.cutItems) {
                if (item.key === key)
                    return true;
            }
            return false;
        }
        /**
         * Remove item from selection by key
         */
        removeFromSelection(key) {
            for (const item of this.selectedItems) {
                if (item.key === key) {
                    this.selectedItems.delete(item);
                    break;
                }
            }
        }
        constructor() {
            super();
            this.handleDomainChange = this.handleDomainChange.bind(this);
            this.handleKeyDown = this.handleKeyDown.bind(this);
            this.addEventListener('focus', this.handleFocus.bind(this));
        }
        connectedCallback() {
            super.connectedCallback();
            this.setAttribute('aria-label', 'Domain hierarchy navigation');
            this.setAttribute('role', 'tree');
            this.setAttribute('tabindex', '0'); // Make component focusable for keyboard events
            // Add keyboard event listener
            this.addEventListener('keydown', this.handleKeyDown);
        }
        disconnectedCallback() {
            super.disconnectedCallback();
            // Clean up keyboard event listener
            this.removeEventListener('keydown', this.handleKeyDown);
        }
        handleFocus() {
            if (!this.focusedItem) {
                this.updateVisibleItemsList();
                this.focusedItem = this.visibleItems[0]?.key;
            }
            if (!this.focusedItem) {
                return;
            }
            this.removeAttribute('tabindex');
        }
        willUpdate(cp) {
            if (cp.has('root')) {
                const old = cp.get('root');
                if (old) {
                    old.removeEventListener('change', this.handleDomainChange);
                }
                this.root?.addEventListener('change', this.handleDomainChange);
                // Initialize collapsed state for new root
                if (this.root && this.root !== old) {
                    this.initializeOpenedParents();
                }
            }
            if (cp.has('selected')) {
                this.selectedItems.clear();
                if (this.selected) {
                    const selectedItem = this.findItemDetails(this.selected);
                    if (selectedItem) {
                        this.selectedItems.add(selectedItem);
                    }
                    this.ensureVisibility(this.selected);
                }
            }
            super.willUpdate(cp);
        }
        updated(cp) {
            super.updated(cp);
            if (cp.has('focusedItem')) {
                this.focusOnCurrentItem();
            }
        }
        handleDomainChange() {
            this.requestUpdate();
        }
        /**
         * Toggle collapsed state of a parent item
         */
        toggleCollapsed(key, event) {
            if (event) {
                event.preventDefault();
                event.stopPropagation();
            }
            if (this.openedParents.has(key)) {
                this.openedParents.delete(key);
            }
            else {
                this.openedParents.add(key);
            }
            this.requestUpdate();
        }
        /**
         * Check if an item is collapsed
         */
        isCollapsed(key) {
            return !this.openedParents.has(key);
        }
        /**
         * Initialize the opened state.
         *
         * @TODO: When selection change from the outside, we should also update the openedParents
         * to ensure that the parent of the selected item is always expanded.
         */
        initializeOpenedParents() {
            this.openedParents.clear();
        }
        ensureVisibility(key) {
            if (!this.root)
                return;
            const node = this.root.graph.node(key);
            if (!node) {
                return;
            }
            let current = node.getParentInstance();
            while (current) {
                if (current.key === this.root.key) {
                    current = undefined;
                    break; // Reached the root, no need to expand further
                }
                this.openedParents.add(current.key);
                if (!(current instanceof DataDomain)) {
                    current = current.getParentInstance();
                }
                else {
                    current = undefined; // No parent for DataDomain
                }
            }
            this.requestUpdate();
        }
        /**
         * Expand all collapsed items
         */
        expandAll() {
            this.openedParents.clear();
            if (!this.root)
                return;
            const collectParentKeys = (container) => {
                // Add namespaces that have children
                for (const namespace of container.listNamespaces()) {
                    if (namespace.hasFields()) {
                        this.openedParents.add(namespace.key);
                        collectParentKeys(namespace);
                    }
                }
                // Add models that have entities
                for (const model of container.listModels()) {
                    if (model.hasFields()) {
                        this.openedParents.add(model.key);
                    }
                }
            };
            collectParentKeys(this.root);
            this.requestUpdate();
        }
        /**
         * Collapse all parent items
         */
        collapseAll() {
            this.openedParents.clear();
            this.requestUpdate();
        }
        /**
         * Clear current selection
         */
        clearSelection() {
            this.selectedItems.clear();
            this.selectionType = undefined;
            this.requestUpdate();
            this.dispatchSelectionCleared();
        }
        /**
         * Handle keyboard shortcuts
         */
        handleKeyDown(event) {
            const { key, ctrlKey, metaKey } = event;
            const isCtrlPressed = ctrlKey || metaKey;
            // Update visible items list for navigation
            this.updateVisibleItemsList();
            if (isCtrlPressed) {
                // Only handle if there are selected items for cut/paste operations
                if (this.selectedItems.size > 0) {
                    switch (key.toLowerCase()) {
                        case 'x':
                            event.preventDefault();
                            this.cutSelectedItems();
                            break;
                        case 'v':
                            event.preventDefault();
                            this.pasteItems();
                            break;
                        case 'c':
                            // Future: could implement copy functionality
                            break;
                    }
                }
                return;
            }
            // Handle navigation keys
            switch (key) {
                case 'ArrowUp':
                    event.preventDefault();
                    this.moveFocusUp();
                    break;
                case 'ArrowDown':
                    event.preventDefault();
                    this.moveFocusDown();
                    break;
                case 'ArrowLeft':
                    event.preventDefault();
                    this.handleArrowLeft();
                    break;
                case 'ArrowRight':
                    event.preventDefault();
                    this.handleArrowRight();
                    break;
                case ' ':
                case 'Space':
                    event.preventDefault();
                    this.handleSpaceKey();
                    break;
                case 'Home':
                    event.preventDefault();
                    this.moveFocusToFirst();
                    break;
                case 'End':
                    event.preventDefault();
                    this.moveFocusToLast();
                    break;
                case 'Escape':
                    this.cancelCut();
                    break;
                case 'Enter':
                    event.preventDefault();
                    this.handleEnterKey();
                    break;
            }
        }
        /**
         * Cut the currently selected items
         */
        cutSelectedItems() {
            if (this.selectedItems.size === 0)
                return;
            // Clear any previous cut items
            this.cutItems.clear();
            // Set current selection as cut items
            for (const item of this.selectedItems) {
                this.cutItems.add(item);
            }
            this.cutItemsType = this.selectionType;
            // Clear selection but keep the cut items
            this.selectedItems.clear();
            this.selectionType = undefined;
            this.requestUpdate();
            this.dispatchCutItems();
        }
        /**
         * Paste cut items to the current selection target
         */
        pasteItems() {
            if (this.cutItems.size === 0)
                return;
            // If there's a single selected item, try to paste to it
            if (this.selectedItems.size === 1) {
                const targetItem = Array.from(this.selectedItems)[0];
                if (targetItem && this.isValidPasteTarget(targetItem.key, targetItem.kind)) {
                    this.performPaste(targetItem.key, targetItem.kind);
                }
            }
            else if (this.selectedItems.size === 0) {
                // If no selection, try to paste to root
                if (this.root && this.isValidPasteTarget(this.root.key, this.root.kind)) {
                    this.performPaste(this.root.key, this.root.kind);
                }
            }
        }
        /**
         * Perform the actual paste operation
         */
        performPaste(targetKey, targetKind) {
            const items = Array.from(this.cutItems);
            if (items.length === 0)
                return;
            const dropDetail = {
                items,
                target: {
                    key: targetKey,
                    kind: targetKind,
                    parent: this.findItemDetails(targetKey)?.parent,
                    domain: this.root ? this.root.key : '',
                },
            };
            this.dispatchEvent(new CustomEvent('items-dropped', { detail: dropDetail, bubbles: true }));
            // Clear cut state after successful paste
            this.cutItems.clear();
            this.cutItemsType = undefined;
            this.requestUpdate();
        }
        /**
         * Cancel current cut operation
         */
        cancelCut() {
            this.cutItems.clear();
            this.cutItemsType = undefined;
            this.requestUpdate();
        }
        /**
         * Check if target is valid for pasting cut items
         */
        isValidPasteTarget(targetKey, targetKind) {
            if (!this.cutItemsType || this.isItemCut(targetKey)) {
                return false;
            }
            // Use the same validation logic as drag and drop
            // Entities can only be pasted on models
            if (this.cutItemsType === DomainEntityKind) {
                return targetKind === DomainModelKind;
            }
            // Models can be pasted on namespaces or root
            if (this.cutItemsType === DomainModelKind) {
                return targetKind === DomainNamespaceKind || targetKind === DataDomainKind;
            }
            // Namespaces can be pasted on other namespaces or root
            if (this.cutItemsType === DomainNamespaceKind) {
                return targetKind === DomainNamespaceKind || targetKind === DataDomainKind;
            }
            return false;
        }
        /**
         * Dispatch cut items event
         */
        dispatchCutItems() {
            const items = Array.from(this.cutItems);
            const detail = {
                items,
                cutItemsType: this.cutItemsType || '',
            };
            this.dispatchEvent(new CustomEvent('items-cut', { detail, bubbles: true }));
        }
        /**
         * Update the list of visible items for keyboard navigation
         */
        updateVisibleItemsList() {
            this.visibleItems = [];
            if (!this.root)
                return;
            const addVisibleItems = (container, level = 0) => {
                // Add namespaces
                for (const namespace of container.listNamespaces()) {
                    const item = this.findItemDetails(namespace.key);
                    if (item) {
                        this.visibleItems.push(item);
                    }
                    // Add children if not collapsed
                    if (namespace.hasFields() && !this.isCollapsed(namespace.key)) {
                        addVisibleItems(namespace, level + 1);
                    }
                }
                // Add models
                for (const model of container.listModels()) {
                    const item = this.findItemDetails(model.key);
                    if (item) {
                        this.visibleItems.push(item);
                    }
                    // Add entities if not collapsed
                    if (model.hasFields() && !this.isCollapsed(model.key)) {
                        for (const entity of model.listEntities()) {
                            const entityItem = this.findItemDetails(entity.key);
                            if (entityItem) {
                                this.visibleItems.push(entityItem);
                            }
                        }
                    }
                }
            };
            addVisibleItems(this.root);
        }
        /**
         * Move focus to the previous item
         */
        moveFocusUp() {
            if (this.visibleItems.length === 0)
                return;
            const currentIndex = this.focusedItem ? this.visibleItems.findIndex((item) => item.key === this.focusedItem) : -1;
            const newIndex = currentIndex <= 0 ? this.visibleItems.length - 1 : currentIndex - 1;
            this.focusedItem = this.visibleItems[newIndex].key;
            this.requestUpdate();
        }
        /**
         * Move focus to the next item
         */
        moveFocusDown() {
            if (this.visibleItems.length === 0)
                return;
            const currentIndex = this.focusedItem ? this.visibleItems.findIndex((item) => item.key === this.focusedItem) : -1;
            const newIndex = currentIndex >= this.visibleItems.length - 1 ? 0 : currentIndex + 1;
            this.focusedItem = this.visibleItems[newIndex].key;
            this.requestUpdate();
        }
        /**
         * Handle left arrow key - collapse item or move to parent
         */
        handleArrowLeft() {
            if (!this.focusedItem)
                return;
            const focusedDetails = this.findItemDetails(this.focusedItem);
            if (!focusedDetails)
                return;
            // If item is expanded, collapse it
            if ((focusedDetails.kind === DomainNamespaceKind || focusedDetails.kind === DomainModelKind) &&
                !this.isCollapsed(this.focusedItem)) {
                this.toggleCollapsed(this.focusedItem);
                return;
            }
            // If item is already collapsed or is a leaf, move to parent
            if (focusedDetails.parent) {
                this.focusedItem = focusedDetails.parent;
                this.requestUpdate();
            }
        }
        /**
         * Handle right arrow key - expand item or move to first child
         */
        handleArrowRight() {
            if (!this.focusedItem)
                return;
            const focusedDetails = this.findItemDetails(this.focusedItem);
            if (!focusedDetails)
                return;
            // If item can be expanded and is collapsed, expand it
            if ((focusedDetails.kind === DomainNamespaceKind || focusedDetails.kind === DomainModelKind) &&
                this.isCollapsed(this.focusedItem)) {
                this.toggleCollapsed(this.focusedItem);
                this.updateVisibleItemsList();
                this.requestUpdate();
                return;
            }
            // If item is already expanded, move to first child
            this.updateVisibleItemsList();
            const currentIndex = this.visibleItems.findIndex((item) => item.key === this.focusedItem);
            if (currentIndex >= 0 && currentIndex < this.visibleItems.length - 1) {
                const nextItem = this.visibleItems[currentIndex + 1];
                // Only move to next item if it's actually a child (has current item as parent)
                if (nextItem.parent === this.focusedItem) {
                    this.focusedItem = nextItem.key;
                    this.requestUpdate();
                }
            }
        }
        /**
         * Handle space key - select/deselect focused item
         */
        handleSpaceKey() {
            if (!this.focusedItem)
                return;
            const item = this.findItemDetails(this.focusedItem);
            if (item) {
                // Toggle selection of focused item
                if (this.isItemSelected(this.focusedItem)) {
                    // Deselect if already selected
                    this.removeFromSelection(this.focusedItem);
                    if (this.selectedItems.size === 0) {
                        this.selectionType = undefined;
                    }
                }
                else {
                    // Select the focused item
                    this.handleSingleSelection(item.key, item.kind, item.domain, item.parent);
                }
                this.requestUpdate();
            }
        }
        /**
         * Handle enter key - activate focused item (same as click)
         */
        handleEnterKey() {
            if (!this.focusedItem)
                return;
            const item = this.findItemDetails(this.focusedItem);
            if (item) {
                this.handleSingleSelection(item.key, item.kind, item.domain, item.parent);
            }
        }
        /**
         * Move focus to first item
         */
        moveFocusToFirst() {
            if (this.visibleItems.length === 0)
                return;
            this.focusedItem = this.visibleItems[0].key;
        }
        /**
         * Move focus to last item
         */
        moveFocusToLast() {
            if (this.visibleItems.length === 0)
                return;
            this.focusedItem = this.visibleItems[this.visibleItems.length - 1].key;
        }
        /**
         * Handle item click for selection
         */
        handleItemClick(event, key, kind, domain, parent) {
            event.preventDefault();
            event.stopPropagation();
            // Update focus when clicking
            this.focusedItem = key;
            const isCtrlClick = event.ctrlKey || event.metaKey;
            if (isCtrlClick) {
                this.handleMultiSelection(key, kind, domain, parent);
            }
            else {
                this.handleSingleSelection(key, kind, domain, parent);
            }
        }
        /**
         * Handle item receiving focus
         */
        handleItemFocus(key) {
            this.focusedItem = key;
        }
        focusOnCurrentItem() {
            if (!this.focusedItem)
                return;
            const itemElement = this.shadowRoot?.querySelector(`[data-key="${this.focusedItem}"]`);
            if (itemElement instanceof HTMLElement) {
                itemElement.focus();
                itemElement.scrollIntoView({ block: 'nearest', inline: 'nearest' });
            }
        }
        /**
         * Handle single item selection
         */
        handleSingleSelection(key, kind, domain, parent) {
            // Clear previous selection
            this.selectedItems.clear();
            const selectionInfo = { key, kind, domain, parent };
            this.selectedItems.add(selectionInfo);
            this.selectionType = kind;
            this.#selected = key;
            this.requestUpdate();
            this.dispatchSingleSelection(key, kind, domain, parent);
        }
        handleFieldSelection(key, kind, domain, parent) {
            // Clear previous selection
            this.selectedItems.clear();
            const selectionInfo = { key: parent, kind: DomainEntityKind, domain };
            this.selectedItems.add(selectionInfo);
            this.selectionType = DomainEntityKind;
            this.#selected = parent;
            this.requestUpdate();
            this.dispatchSingleSelection(key, kind, domain, parent);
        }
        /**
         * Handle multi-item selection with Ctrl+click
         */
        handleMultiSelection(key, kind, domain, parent) {
            // Check for mixed type selection
            if (this.selectionType && this.selectionType !== kind) {
                // Mixed selection not allowed - clear and start new selection
                this.handleSingleSelection(key, kind, domain, parent);
                return;
            }
            const selectionInfo = { key, kind, domain, parent };
            // Toggle selection
            if (this.isItemSelected(key)) {
                this.removeFromSelection(key);
                // If no items left, clear selection type
                if (this.selectedItems.size === 0) {
                    this.selectionType = undefined;
                }
            }
            else {
                this.selectedItems.add(selectionInfo);
                this.selectionType = kind;
            }
            this.requestUpdate();
            this.dispatchMultiSelection();
        }
        /**
         * Dispatch single selection event
         */
        dispatchSingleSelection(key, kind, domain, parent) {
            const detail = { key, kind, domain, parent };
            this.dispatchEvent(new CustomEvent('item-selected', { detail, bubbles: true }));
        }
        /**
         * Dispatch multi-selection event
         */
        dispatchMultiSelection() {
            const items = Array.from(this.selectedItems);
            const detail = {
                items,
                selectionType: this.selectionType || '',
            };
            this.dispatchEvent(new CustomEvent('items-selected', { detail, bubbles: true }));
        }
        /**
         * Dispatch selection cleared event
         */
        dispatchSelectionCleared() {
            this.dispatchEvent(new CustomEvent('selection-cleared', { bubbles: true }));
        }
        /**
         * Find item details by key
         */
        findItemDetails(key) {
            if (!this.root)
                return undefined;
            // Check if it's the root domain
            if (key === this.root.key) {
                return { key, kind: DataDomainKind, domain: this.root.key };
            }
            // Search in namespaces
            const namespace = this.root.findNamespace(key);
            if (namespace) {
                const parent = namespace.getParentInstance();
                return {
                    key,
                    kind: DomainNamespaceKind,
                    domain: this.root.key,
                    parent: parent?.key !== this.root.key ? parent?.key : undefined,
                };
            }
            // Search in models
            const model = this.root.findModel(key);
            if (model) {
                const parent = model.getParentInstance();
                return {
                    key,
                    kind: DomainModelKind,
                    domain: this.root.key,
                    parent: parent?.key !== this.root.key ? parent?.key : undefined,
                };
            }
            // Search in entities
            const entity = this.root.findEntity(key);
            if (entity) {
                const model = entity.getParentInstance();
                return {
                    key,
                    kind: DomainEntityKind,
                    domain: this.root.key,
                    parent: model?.key,
                };
            }
            return undefined;
        }
        /**
         * Handle drag start
         */
        handleDragStart(event, key) {
            if (!event.dataTransfer)
                return;
            let selectedItems = Array.from(this.selectedItems);
            if (!this.isItemSelected(key)) {
                // If the dragged item is not selected, select only this item
                selectedItems = [];
                const item = this.getItemDetailsForKey(key);
                if (item) {
                    selectedItems.push(item);
                }
            }
            // Set drag data
            this.draggedItems.clear();
            for (const selectedItem of selectedItems) {
                this.draggedItems.add(selectedItem);
            }
            const selectedKeys = selectedItems.map((item) => item.key);
            event.dataTransfer.setData('text/plain', selectedKeys.join(','));
            event.dataTransfer.setData('application/json', JSON.stringify({
                items: selectedItems,
            }));
            event.dataTransfer.effectAllowed = 'move';
            this.requestUpdate();
        }
        /**
         * Handle drag over
         */
        handleDragOver(event, key, kind) {
            if (!event.dataTransfer)
                return;
            // Check if this is a valid drop target
            if (this.isValidDropTarget(key, kind)) {
                event.preventDefault();
                this.dragTarget = key;
                this.requestUpdate();
            }
        }
        /**
         * Handle drag leave
         */
        handleDragLeave() {
            this.dragTarget = undefined;
            this.requestUpdate();
        }
        /**
         * Handle drop
         */
        handleDrop(event, targetKey, targetKind) {
            event.preventDefault();
            if (!event.dataTransfer)
                return;
            try {
                const dragData = JSON.parse(event.dataTransfer.getData('application/json'));
                let items = [];
                if (dragData.items) {
                    // New format with full item information
                    items = dragData.items;
                }
                else if (Array.isArray(dragData)) {
                    // Legacy format - just keys
                    items = dragData.map((key) => this.findItemDetails(key)).filter(Boolean);
                }
                else if (dragData.keys) {
                    // Fallback - extract keys and find details
                    items = dragData.keys.map((key) => this.findItemDetails(key)).filter(Boolean);
                }
                if (items.length > 0 && this.isValidDropTarget(targetKey, targetKind)) {
                    const dropDetail = {
                        items,
                        target: {
                            key: targetKey,
                            kind: targetKind,
                            parent: this.findItemDetails(targetKey)?.parent,
                            domain: this.root ? this.root.key : '',
                        },
                    };
                    this.dispatchEvent(new CustomEvent('items-dropped', { detail: dropDetail, bubbles: true }));
                }
            }
            catch {
                // Error handling drop - would normally log to error reporting service
            }
            // Clean up drag state
            this.draggedItems.clear();
            this.dragTarget = undefined;
            this.requestUpdate();
        }
        /**
         * Handle drag end
         */
        handleDragEnd() {
            this.draggedItems.clear();
            this.requestUpdate();
        }
        /**
         * Handle click on external (read-only) items
         */
        handleExternalItemClick(e, key, kind, domain, parent) {
            e.stopPropagation();
            if (e.ctrlKey || e.metaKey) {
                // Multi-selection
                this.handleExternalMultiSelection(key, kind, domain, parent);
            }
            else {
                // Single selection
                this.handleExternalSingleSelection(key, kind, domain, parent);
            }
        }
        /**
         * Handle single selection for external items
         */
        handleExternalSingleSelection(key, kind, domain, parent) {
            this.selectedItems.clear();
            const selectionInfo = { key, kind, domain, parent };
            this.selectedItems.add(selectionInfo);
            this.focusedItem = key;
            this.#selected = key;
            const event = {
                key,
                kind,
                domain,
                parent,
            };
            this.dispatchEvent(new CustomEvent('item-selected', { detail: event }));
            this.requestUpdate();
        }
        /**
         * Handle multi-selection for external items
         */
        handleExternalMultiSelection(key, kind, domain, parent) {
            // Check for mixed selection types
            if (this.selectedItems.size > 0) {
                // Get the kind of already selected items
                const firstSelectedItem = this.getFirstSelectedItemKind();
                if (firstSelectedItem && firstSelectedItem !== kind) {
                    // Mixed selection not allowed, replace selection
                    this.selectedItems.clear();
                    const selectionInfo = { key, kind, domain, parent };
                    this.selectedItems.add(selectionInfo);
                    this.focusedItem = key;
                    const event = {
                        key,
                        kind,
                        domain,
                        parent,
                    };
                    this.dispatchEvent(new CustomEvent('item-selected', { detail: event }));
                    this.requestUpdate();
                    return;
                }
            }
            const selectionInfo = { key, kind, domain, parent };
            // Toggle selection
            if (this.isItemSelected(key)) {
                this.removeFromSelection(key);
            }
            else {
                this.selectedItems.add(selectionInfo);
            }
            this.focusedItem = key;
            // Dispatch multi-selection event
            const items = Array.from(this.selectedItems);
            const event = {
                items,
                selectionType: kind,
            };
            this.dispatchEvent(new CustomEvent('items-selected', { detail: event }));
            this.requestUpdate();
        }
        /**
         * Get the kind of the first selected item
         */
        getFirstSelectedItemKind() {
            if (this.selectedItems.size === 0)
                return undefined;
            const firstItem = this.selectedItems.values().next().value;
            return firstItem?.kind;
        }
        /**
         * Get item details for a given key
         */
        getItemDetailsForKey(key) {
            // First try the main domain
            if (this.root) {
                const result = this.findItemInDomain(key, this.root);
                if (result)
                    return result;
            }
            // Then try external domains
            if (this.root?.dependencies) {
                for (const [, externalDomain] of this.root.dependencies) {
                    const result = this.findItemInDomain(key, externalDomain);
                    if (result)
                        return result;
                }
            }
            return undefined;
        }
        /**
         * Find item details within a specific domain
         */
        findItemInDomain(key, domain) {
            // Check if it's the domain itself
            if (domain.key === key) {
                return {
                    key: domain.key,
                    kind: domain.kind,
                    domain: domain.key,
                };
            }
            const ns = domain.findNamespace(key);
            if (ns) {
                return {
                    key: ns.key,
                    kind: DomainNamespaceKind,
                    domain: domain.key,
                    parent: ns.getParentInstance()?.key,
                };
            }
            const model = domain.findModel(key);
            if (model) {
                return {
                    key: model.key,
                    kind: DomainModelKind,
                    domain: domain.key,
                    parent: model.getParentInstance()?.key,
                };
            }
            const entity = domain.findEntity(key);
            if (entity) {
                const modelParent = entity.getParentInstance();
                return {
                    key: entity.key,
                    kind: DomainEntityKind,
                    domain: domain.key,
                    parent: modelParent?.key,
                };
            }
            return undefined;
        }
        /**
         * Find item in nested namespace structure
         */
        findItemInNamespace(key, namespace, domain) {
            const field = namespace.fields.find((field) => field.key === key);
            if (!field) {
                return undefined;
            }
            if (field.type === 'model') {
                return {
                    key: field.key,
                    kind: DomainModelKind,
                    domain,
                    parent: namespace.key,
                };
            }
            if (field.type === 'namespace') {
                return {
                    key: field.key,
                    kind: DomainNamespaceKind,
                    domain,
                    parent: namespace.key,
                };
            }
            return undefined;
        }
        /**
         * Check if a target is valid for dropping the current selection
         */
        isValidDropTarget(targetKey, targetKind) {
            if (!this.selectionType || this.isItemSelected(targetKey)) {
                return false;
            }
            // Entities can only be dropped on models
            if (this.selectionType === DomainEntityKind) {
                return targetKind === DomainModelKind;
            }
            // Models can be dropped on namespaces or root
            if (this.selectionType === DomainModelKind) {
                return targetKind === DomainNamespaceKind || targetKind === DataDomainKind;
            }
            // Namespaces can be dropped on other namespaces or root
            if (this.selectionType === DomainNamespaceKind) {
                return targetKind === DomainNamespaceKind || targetKind === DataDomainKind;
            }
            return false;
        }
        handleSearch(event) {
            const query = event.detail.input;
            this.searchDomain(query);
        }
        handleSearchClear() {
            this.clearSearch();
        }
        searchDomain(query) {
            const domain = this.root;
            if (!domain)
                return;
            this.searchQuery = query.trim();
            if (!this.searchQuery) {
                this.clearSearch();
                return;
            }
            const found = domain.search({
                query: this.searchQuery,
            });
            this.searchResults = found;
        }
        handleSearchResultClick(event, result) {
            event.preventDefault();
            event.stopPropagation();
            const { key, node } = result;
            const kind = node.kind;
            const domain = node.domain.key;
            // For now, just clear search and navigate to the item
            // Selection logic can be implemented later
            this.clearSearch();
            // Find the parent for proper selection info
            let parent;
            if (kind === DomainEntityKind) {
                const entity = node;
                const modelParent = entity.getParentInstance();
                parent = modelParent?.key;
                this.ensureVisibility(key);
                this.handleSingleSelection(key, kind, domain, parent);
            }
            else if (kind === DomainModelKind || kind === DomainNamespaceKind) {
                const parentInstance = node.getParentInstance();
                parent = parentInstance?.key !== domain ? parentInstance?.key : undefined;
                this.ensureVisibility(key);
                this.handleSingleSelection(key, kind, domain, parent);
            }
            else if (kind === DomainAssociationKind) {
                const association = node;
                const modelParent = association.getParentInstance();
                parent = modelParent?.key;
                if (parent) {
                    this.ensureVisibility(parent);
                    this.handleFieldSelection(key, kind, domain, parent);
                }
            }
            else if (kind === DomainPropertyKind) {
                const property = node;
                const modelParent = property.getParentInstance();
                parent = modelParent?.key;
                if (parent) {
                    this.ensureVisibility(parent);
                    this.handleFieldSelection(key, kind, domain, parent);
                }
            }
        }
        clearSearch() {
            this.searchQuery = undefined;
            this.searchResults = [];
        }
        handleSearchKeyDown(e) {
            e.stopPropagation();
            if (e.defaultPrevented) {
                return;
            }
        }
        render() {
            const { root } = this;
            if (!root) {
                return html `<div class="empty-state">No data domain available</div>`;
            }
            const hasFields = root.hasFields();
            const hasDependencies = root.dependencies?.size > 0;
            if (!hasFields && !hasDependencies) {
                return html `<div class="empty-state">No schemas to display</div>`;
            }
            return html `
      <div class="hierarchy-tree">
        ${this.cutItems.size > 0
                ? this.renderCutItemsInfo()
                : this.selectedItems.size > 1
                    ? this.renderMultiSelectionInfo()
                    : this.renderDomainHeader(root)}
        ${this.searchQuery ? this.renderSearchResults() : ''}
        ${hasFields ? this.renderDomainTree(root) : this.renderEmptyDomain()} ${this.renderExternalDomains()}
      </div>
    `;
        }
        renderEmptyDomain() {
            return html `<div class="empty-state">No data to render.</div>`;
        }
        renderCutItemsInfo() {
            const count = this.cutItems.size;
            const type = getDomainLabel(this.cutItemsType || 'items');
            return html `
      <div class="multi-selection-info cut-items">
        <span class="body-small"
          >${count} ${type}${count > 1 ? 's' : ''} cut - Select target and press Ctrl+V to paste</span
        >
        <ui-button size="xs" color="tonal" @click="${this.cancelCut}">Cancel</ui-button>
      </div>
    `;
        }
        renderDomainTitle(root) {
            return html `<h2 class="domain-title title-small">${root.info.getLabel()}</h2>`;
        }
        renderDomainHeader(root) {
            const hasCollapsibleItems = [...root.listNamespaces()].some((ns) => ns.hasFields()) || [...root.listModels()].some((m) => m.hasFields());
            return html `
      <div class="domain-header">
        <search-input
          class="search-input"
          placeholder="Search domain..."
          @search="${this.handleSearch}"
          @clear="${this.handleSearchClear}"
          @keydown="${this.handleSearchKeyDown}"
          value="${this.searchQuery || ''}"
        ></search-input>
        ${hasCollapsibleItems
                ? html `
              <div class="expand-controls">
                <ui-icon-button @click="${this.expandAll}" color="standard" shape="round" size="xs" title="Expand all"
                  ><ui-icon icon="add"></ui-icon
                ></ui-icon-button>
                <ui-icon-button
                  @click="${this.collapseAll}"
                  color="standard"
                  shape="round"
                  size="xs"
                  title="Collapse all"
                  ><ui-icon icon="remove"></ui-icon
                ></ui-icon-button>
              </div>
            `
                : ''}
      </div>
    `;
        }
        renderSearchResults() {
            if (!this.searchQuery || this.searchResults.length === 0) {
                return html `
        <div class="search-results-overlay">
          <div class="search-no-results">
            <span class="body-medium">No results found for "${this.searchQuery}"</span>
          </div>
        </div>
      `;
            }
            return html `
      <div class="search-results-overlay">
        <div class="search-results-list">
          ${this.searchResults.map((result) => this.renderSearchResultItem(result))}
        </div>
      </div>
    `;
        }
        getSearchIcon(item) {
            switch (item.kind) {
                case DomainAssociationKind:
                case DomainPropertyKind:
                    return getFieldIcon(item);
                default:
                    return getDomainIconType(item.kind);
            }
        }
        renderSearchResultItem(result) {
            const { node, key, isForeign, matchedFields } = result;
            const nodeInfo = node.info;
            const icon = this.getSearchIcon(node);
            return html `
      <div
        class="search-result-item"
        data-key="${key}"
        data-kind="${node.kind}"
        data-domain="${node.domain.key}"
        @click="${(e) => this.handleSearchResultClick(e, result)}"
      >
        <div class="search-result-content">
          <div class="search-result-main">
            <ui-icon class="search-result-icon" icon="${icon}"></ui-icon>
            <div class="search-result-info">
              <span class="search-result-name body-medium">${nodeInfo.getLabel()}</span>
              ${isForeign ? html `<span class="search-result-badge label-small">External</span>` : ''}
            </div>
          </div>
          ${nodeInfo.description
                ? html `<div class="search-result-description body-small">${nodeInfo.description}</div>`
                : ''}
          ${matchedFields.length > 0
                ? html `
                <div class="search-result-matches">
                  <span class="label-small">Matched: ${matchedFields.join(', ')}</span>
                </div>
              `
                : ''}
        </div>
      </div>
    `;
        }
        renderMultiSelectionInfo() {
            const count = this.selectedItems.size;
            const type = getDomainLabel(this.selectionType || 'items');
            return html `
      <div class="multi-selection-info">
        <span class="body-small">${count} ${type}${count > 1 ? 's' : ''} selected</span>
        <ui-button size="xs" color="tonal" @click="${this.clearSelection}">Clear Selection</ui-button>
      </div>
    `;
        }
        renderDomainTree(root) {
            const items = [];
            // Render namespaces
            for (const namespace of root.listNamespaces()) {
                items.push(this.renderNamespaceItem(namespace, root));
            }
            // Render models
            for (const model of root.listModels()) {
                items.push(this.renderModelItem(model, root));
            }
            return html `<div class="tree-items">${items}</div>`;
        }
        /**
         * Render external data domains from dependencies
         */
        renderExternalDomains() {
            if (!this.root?.dependencies?.size) {
                return html ``;
            }
            const externalDomains = [];
            for (const [, externalDomain] of this.root.dependencies) {
                externalDomains.push(this.renderExternalDomain(externalDomain));
            }
            return html `
      <div class="external-domains">
        <ui-divider></ui-divider>
        <div class="external-domains-header">
          <h3 class="external-domains-title title-medium">External Dependencies</h3>
        </div>
        ${externalDomains}
      </div>
    `;
        }
        /**
         * Render a single external domain
         */
        renderExternalDomain(domain) {
            return html `
      <div class="external-domain">
        <div class="external-domain-header">
          <h4 class="external-domain-title title-small">${domain.info.getLabel()}</h4>
          <span class="external-domain-badge label-medium">Read-only</span>
        </div>
        ${this.renderExternalDomainTree(domain)}
      </div>
    `;
        }
        /**
         * Render external domain tree (read-only)
         */
        renderExternalDomainTree(domain) {
            const items = [];
            // Render namespaces
            for (const namespace of domain.listNamespaces()) {
                items.push(this.renderExternalNamespaceItem(namespace, domain));
            }
            // Render models
            for (const model of domain.listModels()) {
                items.push(this.renderExternalModelItem(model, domain));
            }
            return html `<div class="external-tree-items">${items}</div>`;
        }
        renderNamespaceItem(namespace, parent) {
            const hasChildren = namespace.hasFields();
            const isSelected = this.isItemSelected(namespace.key);
            const isMultiSelected = isSelected && this.selectedItems.size > 1;
            const isDragSource = this.isItemDragged(namespace.key);
            const isDragTarget = this.dragTarget === namespace.key;
            const isCollapsed = this.isCollapsed(namespace.key);
            const isCut = this.isItemCut(namespace.key);
            const isFocused = this.focusedItem === namespace.key;
            return html `
      <div class="tree-item" role="treeitem">
        <div
          class="item-content ${classMap({
                'selected': isSelected && !isMultiSelected,
                'multi-selected': isMultiSelected,
                'drag-source': isDragSource,
                'drag-over': isDragTarget,
                'cut': isCut,
                'focused': isFocused,
                'highlighted': this.highlighted === namespace.key,
            })}"
          tabindex="${isFocused ? '0' : '-1'}"
          draggable="true"
          data-key="${namespace.key}"
          data-kind="${namespace.kind}"
          data-domain="${namespace.domain.key}"
          data-parent="${parent.key !== namespace.domain.key ? parent.key : ''}"
          @click="${(e) => this.handleItemClick(e, namespace.key, namespace.kind, namespace.domain.key, parent.key !== namespace.domain.key ? parent.key : undefined)}"
          @focus="${() => this.handleItemFocus(namespace.key)}"
          @dragstart="${(e) => this.handleDragStart(e, namespace.key)}"
          @dragover="${(e) => this.handleDragOver(e, namespace.key, namespace.kind)}"
          @dragleave="${() => this.handleDragLeave()}"
          @drop="${(e) => this.handleDrop(e, namespace.key, namespace.kind)}"
          @dragend="${() => this.handleDragEnd()}"
        >
          ${hasChildren
                ? html `
                <ui-icon
                  class="expand-icon ${isCollapsed ? '' : 'expanded'}"
                  icon="chevronRight"
                  @click="${(e) => this.toggleCollapsed(namespace.key, e)}"
                ></ui-icon>
              `
                : html `<span class="expand-placeholder"></span>`}
          <ui-icon class="item-icon" icon="${getDomainIconType(namespace.kind)}"></ui-icon>
          <span class="item-label">${namespace.info.getLabel()}</span>
        </div>
        ${hasChildren && !isCollapsed ? html ` <div class="children">${this.renderDomainTree(namespace)}</div>` : ''}
      </div>
    `;
        }
        renderModelItem(model, parent) {
            const hasEntities = model.hasFields();
            const isSelected = this.isItemSelected(model.key);
            const isMultiSelected = this.selectedItems.size > 1 && isSelected;
            const isDragSource = this.isItemDragged(model.key);
            const isDragTarget = this.dragTarget === model.key;
            const isCollapsed = this.isCollapsed(model.key);
            const isCut = this.isItemCut(model.key);
            const isFocused = this.focusedItem === model.key;
            return html `
      <div class="tree-item" role="treeitem">
        <div
          class="item-content ${classMap({
                'selected': isSelected && !isMultiSelected,
                'multi-selected': isMultiSelected,
                'drag-source': isDragSource,
                'drag-over': isDragTarget,
                'cut': isCut,
                'focused': isFocused,
                'highlighted': this.highlighted === model.key,
            })}"
          tabindex="${isFocused ? '0' : '-1'}"
          draggable="true"
          data-key="${model.key}"
          data-kind="${model.kind}"
          data-domain="${model.domain.key}"
          data-parent="${parent.key !== model.domain.key ? parent.key : ''}"
          @click="${(e) => this.handleItemClick(e, model.key, model.kind, model.domain.key, parent.key !== model.domain.key ? parent.key : undefined)}"
          @focus="${() => this.handleItemFocus(model.key)}"
          @dragstart="${(e) => this.handleDragStart(e, model.key)}"
          @dragover="${(e) => this.handleDragOver(e, model.key, model.kind)}"
          @dragleave="${() => this.handleDragLeave()}"
          @drop="${(e) => this.handleDrop(e, model.key, model.kind)}"
          @dragend="${() => this.handleDragEnd()}"
        >
          ${hasEntities
                ? html `
                <ui-icon
                  class="expand-icon ${isCollapsed ? '' : 'expanded'}"
                  icon="chevronRight"
                  @click="${(e) => this.toggleCollapsed(model.key, e)}"
                ></ui-icon>
              `
                : html `<span class="expand-placeholder"></span>`}
          <ui-icon class="item-icon" icon="${getDomainIconType(model.kind)}"></ui-icon>
          <span class="item-label">${model.info.getLabel()}</span>
        </div>
        ${hasEntities && !isCollapsed ? html ` <div class="children">${this.renderEntityList(model)}</div>` : ''}
      </div>
    `;
        }
        renderEntityList(model) {
            const entities = [];
            for (const entity of model.listEntities()) {
                entities.push(this.renderEntityItem(entity, model));
            }
            return html `<div class="entity-items">${entities}</div>`;
        }
        renderEntityItem(entity, parent) {
            const isSelected = this.isItemSelected(entity.key);
            const isMultiSelected = isSelected && this.selectedItems.size > 1;
            const isDragSource = this.isItemDragged(entity.key);
            const isCut = this.isItemCut(entity.key);
            const isFocused = this.focusedItem === entity.key;
            return html `
      <div class="tree-item" role="treeitem">
        <div
          class="item-content ${classMap({
                'selected': isSelected && !isMultiSelected,
                'multi-selected': isMultiSelected,
                'drag-source': isDragSource,
                'cut': isCut,
                'focused': isFocused,
                'highlighted': this.highlighted === entity.key,
            })}"
          tabindex="${isFocused ? '0' : '-1'}"
          draggable="true"
          data-key="${entity.key}"
          data-kind="${entity.kind}"
          data-domain="${entity.domain.key}"
          data-parent="${parent.key !== entity.domain.key ? parent.key : ''}"
          @click="${(e) => this.handleItemClick(e, entity.key, entity.kind, entity.domain.key, parent.key)}"
          @focus="${() => this.handleItemFocus(entity.key)}"
          @dragstart="${(e) => this.handleDragStart(e, entity.key)}"
          @dragend="${() => this.handleDragEnd()}"
        >
          <span class="expand-placeholder"></span>
          <ui-icon class="item-icon" icon="${getDomainIconType(entity.kind)}"></ui-icon>
          <span class="item-label">${entity.info.getLabel()}</span>
        </div>
      </div>
    `;
        }
        /**
         * Render external namespace item (read-only)
         */
        renderExternalNamespaceItem(namespace, parent) {
            const hasChildren = namespace.hasFields();
            const isSelected = this.isItemSelected(namespace.key);
            const isMultiSelected = this.selectedItems.size > 1 && isSelected;
            const isCollapsed = this.isCollapsed(namespace.key);
            const isFocused = this.focusedItem === namespace.key;
            return html `
      <div class="tree-item external-item" role="treeitem">
        <div
          class="item-content external-item-content ${classMap({
                'selected': isSelected && !isMultiSelected,
                'multi-selected': isMultiSelected,
                'focused': isFocused,
                'highlighted': this.highlighted === namespace.key,
            })}"
          tabindex="${isFocused ? '0' : '-1'}"
          draggable="true"
          data-key="${namespace.key}"
          data-kind="${namespace.kind}"
          data-domain="${namespace.domain.key}"
          data-parent="${parent.key !== namespace.domain.key ? parent.key : ''}"
          @click="${(e) => this.handleExternalItemClick(e, namespace.key, namespace.kind, namespace.domain.key, parent.key !== namespace.domain.key ? parent.key : undefined)}"
          @focus="${() => this.handleItemFocus(namespace.key)}"
          @dragstart="${(e) => this.handleDragStart(e, namespace.key)}"
          @dragend="${() => this.handleDragEnd()}"
        >
          ${hasChildren
                ? html `
                <ui-icon
                  class="expand-icon ${isCollapsed ? '' : 'expanded'}"
                  icon="chevronRight"
                  @click="${(e) => this.toggleCollapsed(namespace.key, e)}"
                ></ui-icon>
              `
                : html `<span class="expand-placeholder"></span>`}
          <ui-icon class="item-icon" icon="${getDomainIconType(namespace.kind)}"></ui-icon>
          <span class="item-label">${namespace.info.getLabel()}</span>
        </div>
        ${hasChildren && !isCollapsed
                ? html ` <div class="children">${this.renderExternalDomainTree(namespace)}</div>`
                : ''}
      </div>
    `;
        }
        /**
         * Render external model item (read-only)
         */
        renderExternalModelItem(model, parent) {
            const hasEntities = model.hasFields();
            const isSelected = this.isItemSelected(model.key);
            const isMultiSelected = this.selectedItems.size > 1 && isSelected;
            const isCollapsed = this.isCollapsed(model.key);
            const isFocused = this.focusedItem === model.key;
            return html `
      <div class="tree-item external-item" role="treeitem">
        <div
          class="item-content external-item-content ${classMap({
                'selected': isSelected && !isMultiSelected,
                'multi-selected': isMultiSelected,
                'focused': isFocused,
                'highlighted': this.highlighted === model.key,
            })}"
          tabindex="${isFocused ? '0' : '-1'}"
          draggable="true"
          data-key="${model.key}"
          data-kind="${model.kind}"
          data-domain="${model.domain.key}"
          data-parent="${parent.key !== model.domain.key ? parent.key : ''}"
          @click="${(e) => this.handleExternalItemClick(e, model.key, model.kind, model.domain.key, parent.key !== model.domain.key ? parent.key : undefined)}"
          @focus="${() => this.handleItemFocus(model.key)}"
          @dragstart="${(e) => this.handleDragStart(e, model.key)}"
          @dragend="${() => this.handleDragEnd()}"
        >
          ${hasEntities
                ? html `
                <ui-icon
                  class="expand-icon ${isCollapsed ? '' : 'expanded'}"
                  icon="chevronRight"
                  @click="${(e) => this.toggleCollapsed(model.key, e)}"
                ></ui-icon>
              `
                : html `<span class="expand-placeholder"></span>`}
          <ui-icon class="item-icon" icon="${getDomainIconType(model.kind)}"></ui-icon>
          <span class="item-label">${model.info.getLabel()}</span>
        </div>
        ${hasEntities && !isCollapsed ? html ` <div class="children">${this.renderExternalEntityList(model)}</div>` : ''}
      </div>
    `;
        }
        /**
         * Render external entity list
         */
        renderExternalEntityList(model) {
            const entities = [];
            for (const entity of model.listEntities()) {
                entities.push(this.renderExternalEntityItem(entity, model));
            }
            return html `<div class="external-entity-items">${entities}</div>`;
        }
        /**
         * Render external entity item (read-only)
         */
        renderExternalEntityItem(entity, parent) {
            const isSelected = this.isItemSelected(entity.key);
            const isMultiSelected = this.selectedItems.size > 1 && isSelected;
            const isFocused = this.focusedItem === entity.key;
            return html `
      <div class="tree-item external-item" role="treeitem">
        <div
          class="item-content external-item-content ${classMap({
                'selected': isSelected && !isMultiSelected,
                'multi-selected': isMultiSelected,
                'focused': isFocused,
                'highlighted': this.highlighted === entity.key,
            })}"
          tabindex="${isFocused ? '0' : '-1'}"
          draggable="true"
          data-key="${entity.key}"
          data-kind="${entity.kind}"
          data-domain="${entity.domain.key}"
          data-parent="${parent.key !== entity.domain.key ? parent.key : ''}"
          @click="${(e) => this.handleExternalItemClick(e, entity.key, entity.kind, entity.domain.key, parent.key)}"
          @focus="${() => this.handleItemFocus(entity.key)}"
          @dragstart="${(e) => this.handleDragStart(e, entity.key)}"
          @dragend="${() => this.handleDragEnd()}"
        >
          <span class="expand-placeholder"></span>
          <ui-icon class="item-icon" icon="${getDomainIconType(entity.kind)}"></ui-icon>
          <span class="item-label">${entity.info.getLabel()}</span>
        </div>
      </div>
    `;
        }
    };
})();
/**
 * A new navigation element for DataDomain hierarchy that supports:
 * - Single click selection with selection events
 * - Ctrl+click multi-selection
 * - Drag and drop operations with proper validation
 * - Mixed selection type prevention
 *
 * @fires items-selected {CustomEvent<DomainMultiSelectionEventDetail>} - when multiple items are selected
 * @fires items-dropped {CustomEvent<DomainDragDropEventDetail>} - when items are dropped (or pasted)
 * @fires item-selected {CustomEvent<DomainSelectionInfo>} - when a single item is selected
 * @fires selection-cleared {CustomEvent<void>} - when selection is cleared
 * @fires items-cut {CustomEvent<{ items: DomainSelectionInfo[], cutItemsType: string }>} - when items are cut
 */
export default DomainNavigation;
//# sourceMappingURL=DomainNavigation.js.map