class CustomComponentHandlerManager {
    constructor() {
        this.blockHandlers = [];
        this.itemHandlers = [];
    }

    registerBlockHandlers(handlersArray) {
        handlersArray.forEach(({ customComponentName, handlerFunction, priorityId = 0 }) => {
            this.blockHandlers.push({ customComponentName, handlerFunction, priorityId });
        });
    }

    registerItemHandlers(handlersArray) {
        handlersArray.forEach(({ customComponentName, handlerFunction, priorityId = 0 }) => {
            this.itemHandlers.push({ customComponentName, handlerFunction, priorityId });
        });
    }

    applyHandlers(initEvent) {
        const groupedBlockHandlers = this._groupAndSortHandlers(this.blockHandlers);
        const groupedItemHandlers = this._groupAndSortHandlers(this.itemHandlers);

        for (const [name, handlers] of Object.entries(groupedBlockHandlers)) {
            const handlerObject = {};
            Object.keys(handlers).forEach(eventName => {
                handlerObject[eventName] = (event) => {
                    handlers[eventName].forEach(func => func(event));
                };
            });
            initEvent.blockComponentRegistry.registerCustomComponent(name, handlerObject);
        }

        for (const [name, handlers] of Object.entries(groupedItemHandlers)) {
            const handlerObject = {};
            Object.keys(handlers).forEach(eventName => {
                handlerObject[eventName] = (event) => {
                    handlers[eventName].forEach(func => func(event));
                };
            });
            initEvent.itemComponentRegistry.registerCustomComponent(name, handlerObject);
        }
    }

    _groupAndSortHandlers(handlersArray) {
        const groupedHandlers = {};

        handlersArray.forEach(({ customComponentName, handlerFunction, priorityId }) => {
            if (!groupedHandlers[customComponentName]) {
                groupedHandlers[customComponentName] = {};
            }
            Object.keys(handlerFunction).forEach(eventName => {
                if (!groupedHandlers[customComponentName][eventName]) {
                    groupedHandlers[customComponentName][eventName] = [];
                }
                groupedHandlers[customComponentName][eventName].push({ func: handlerFunction[eventName], priorityId });
            });
        });

        for (const name in groupedHandlers) {
            for (const eventName in groupedHandlers[name]) {
                groupedHandlers[name][eventName].sort((a, b) => b.priorityId - a.priorityId);
                groupedHandlers[name][eventName] = groupedHandlers[name][eventName].map(h => h.func);
            }
        }

        return groupedHandlers;
    }
}

export default CustomComponentHandlerManager;
