"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.d = (exports1, definition)=>{
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
    __webpack_require__.r = (exports1)=>{
        if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    NodeTypeRegistry: ()=>NodeTypeRegistry
});
const index_cjs_namespaceObject = require("../utils/index.cjs");
const external_CategoryTree_cjs_namespaceObject = require("./CategoryTree.cjs");
const external_CategoryTreeAdapter_cjs_namespaceObject = require("./CategoryTreeAdapter.cjs");
class NodeTypeRegistry {
    categoryById = new Map();
    nodeByType = new Map();
    nodeHandles = new Map();
    categoriesByParent = new Map();
    nodesByCategory = new Map();
    categoryAncestors = new Map();
    categoryDescendants = new Map();
    categoryTree = null;
    registerNodeManifests(nodes) {
        const categoryMap = new Map();
        for (const node of nodes){
            const categoryId = node.category;
            if (categoryId) categoryMap.set(categoryId, {
                id: categoryId,
                name: categoryId.charAt(0).toUpperCase() + categoryId.slice(1),
                sortOrder: 0,
                tags: [],
                color: node.display.color ?? 'transparent',
                colorDark: 'transparent',
                icon: node.display.icon ?? 'box'
            });
        }
        this.registerManifest(nodes, Array.from(categoryMap.values()));
    }
    registerManifest(nodeManifests, categoryManifests) {
        this.categoryById = new Map(categoryManifests.map((c)=>[
                c.id,
                c
            ]));
        this.nodeByType = new Map(nodeManifests.map((n)=>[
                n.nodeType,
                n
            ]));
        this.nodeHandles = new Map(nodeManifests.map((n)=>[
                n.nodeType,
                n.handleConfiguration.flatMap((hc)=>hc.handles).reduce((acc, handle)=>{
                    if (!acc[handle.type]) acc[handle.type] = [];
                    acc[handle.type]?.push(handle);
                    return acc;
                }, {})
            ]));
        this.categoriesByParent = new Map();
        for (const cat of categoryManifests){
            const siblings = this.categoriesByParent.get(cat.parentId) ?? [];
            siblings.push(cat);
            this.categoriesByParent.set(cat.parentId, siblings);
        }
        this.categoryAncestors = new Map();
        for (const cat of categoryManifests){
            const ancestors = [];
            let currentId = cat.parentId;
            while(currentId){
                ancestors.push(currentId);
                currentId = this.categoryById.get(currentId)?.parentId;
            }
            this.categoryAncestors.set(cat.id, ancestors);
        }
        this.categoryDescendants = new Map();
        for (const cat of categoryManifests){
            const descendants = [];
            const queue = [
                cat.id
            ];
            while(queue.length > 0){
                const current = queue.shift();
                const children = this.categoriesByParent.get(current) ?? [];
                for (const child of children){
                    descendants.push(child.id);
                    queue.push(child.id);
                }
            }
            this.categoryDescendants.set(cat.id, descendants);
        }
        this.nodesByCategory = new Map();
        for (const node of nodeManifests){
            const categoryKey = node.category ?? void 0;
            const nodes = this.nodesByCategory.get(categoryKey) ?? [];
            nodes.push(node);
            this.nodesByCategory.set(categoryKey, nodes);
        }
        this.categoryTree = new external_CategoryTree_cjs_namespaceObject.CategoryTree(categoryManifests, nodeManifests);
    }
    getManifest(nodeType) {
        return this.nodeByType.get(nodeType);
    }
    getAllManifests() {
        return Array.from(this.nodeByType.values());
    }
    getAllCategories() {
        return Array.from(this.categoryById.keys());
    }
    getAllNodeTypes() {
        return Array.from(this.nodeByType.keys());
    }
    getHandlesByNodeType(nodeType) {
        return this.nodeHandles.get(nodeType) ?? {};
    }
    getDefaultHandle(nodeType, handleType) {
        const handles = this.nodeHandles.get(nodeType)?.[handleType];
        return handles?.find((h)=>h.isDefaultForType) ?? handles?.[0];
    }
    createDefaultData(nodeType, label) {
        const manifest = this.getManifest(nodeType);
        if (!manifest) return {
            nodeType,
            version: '1.0.0',
            display: {
                label: label || nodeType
            }
        };
        const display = {
            ...label ? {
                label
            } : {},
            icon: manifest.display.icon,
            shape: manifest.display.shape,
            color: manifest.display.color,
            background: manifest.display.background,
            iconBackground: manifest.display.iconBackground,
            iconBackgroundDark: manifest.display.iconBackgroundDark
        };
        return {
            nodeType,
            version: manifest.version,
            parameters: manifest.defaultProperties ?? {},
            display: display
        };
    }
    getCategoryTree() {
        return this.categoryTree;
    }
    clear() {
        this.nodesByCategory.clear();
        this.nodeHandles.clear();
        this.nodeByType.clear();
        this.categoryById.clear();
        this.categoryAncestors.clear();
        this.categoryDescendants.clear();
        this.categoriesByParent.clear();
        this.categoryTree = null;
    }
    isValidCategoryForConnection(categoryId, previewNodeConnectionInfo) {
        if (!previewNodeConnectionInfo || 0 === previewNodeConnectionInfo.length) return true;
        const descendantCategories = this.categoryDescendants.get(categoryId) ?? [];
        const categoriesToCheck = [
            categoryId,
            ...descendantCategories
        ];
        for (const connection of previewNodeConnectionInfo){
            const existingHandleConstraints = connection.existingHandleManifest?.constraints;
            if (!existingHandleConstraints) continue;
            const allowedCategories = connection.addNewNodeAsSource ? existingHandleConstraints.allowedSourceCategories : existingHandleConstraints.allowedTargetCategories;
            const forbiddenCategories = connection.addNewNodeAsSource ? existingHandleConstraints.forbiddenSourceCategories : existingHandleConstraints.forbiddenTargetCategories;
            const hasValidDescendant = categoriesToCheck.some((catId)=>(0, index_cjs_namespaceObject.checkCategoryConstraint)(catId, allowedCategories, forbiddenCategories));
            if (!hasValidDescendant) return false;
        }
        return true;
    }
    isValidNodeForConnection(nodeType, previewNodeConnectionInfo) {
        if (!previewNodeConnectionInfo || 0 === previewNodeConnectionInfo.length) return true;
        const nodeItemManifest = this.nodeByType.get(nodeType);
        if (!nodeItemManifest) return false;
        for (const connection of previewNodeConnectionInfo){
            const { existingNodeManifest, existingHandleManifest } = connection;
            if (!existingNodeManifest || !existingHandleManifest) return false;
            const existingNodeData = {
                type: existingNodeManifest.nodeType,
                category: existingNodeManifest.category
            };
            const nodeToValidateData = {
                type: nodeItemManifest.nodeType,
                category: nodeItemManifest.category
            };
            const defaultNodeItemHandle = this.getDefaultHandle(nodeType, connection.addNewNodeAsSource ? 'source' : 'target');
            if (!defaultNodeItemHandle) return false;
            const connectionValidationData = connection.addNewNodeAsSource ? {
                sourceNode: nodeToValidateData,
                sourceHandle: defaultNodeItemHandle,
                targetNode: existingNodeData,
                targetHandle: existingHandleManifest
            } : {
                sourceNode: existingNodeData,
                sourceHandle: existingHandleManifest,
                targetNode: nodeToValidateData,
                targetHandle: defaultNodeItemHandle
            };
            const isValidConnection = (0, index_cjs_namespaceObject.validateConnection)(connectionValidationData).valid;
            if (!isValidConnection) return false;
        }
        return true;
    }
    createConnectionValidator(connectionInfo) {
        return {
            isValidCategoryForConnection: (categoryId)=>this.isValidCategoryForConnection(categoryId, connectionInfo),
            canNodeConnect: (nodeType)=>this.isValidNodeForConnection(nodeType, connectionInfo)
        };
    }
    getNodeOptions(options) {
        const { connections, category, search, flattenAll = false, flattenSinglePath = false } = options;
        let tree = this.getCategoryTree();
        if (!tree) return [];
        if (category) tree = tree.getSubtree(category);
        if (connections) {
            const validator = this.createConnectionValidator(connections);
            tree = tree.filterByConnections(validator);
        }
        if (search) tree = tree.filterBySearch(search);
        if (flattenAll) tree = tree.flatten();
        else if (flattenSinglePath) tree = tree.flattenSinglePath();
        const adapter = new external_CategoryTreeAdapter_cjs_namespaceObject.CategoryTreeAdapter(tree);
        return adapter.toListItems();
    }
}
exports.NodeTypeRegistry = __webpack_exports__.NodeTypeRegistry;
for(var __rspack_i in __webpack_exports__)if (-1 === [
    "NodeTypeRegistry"
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
Object.defineProperty(exports, '__esModule', {
    value: true
});
