// ==========================================
// Switchboard Core — SDK: Slot System
// ==========================================
// Named shell regions where extensions inject UI.
//
// Factory: createSlots(emitFn)
// ==========================================

/**
 * Create the slot registry.
 *
 * @param {Function} emitFn — events.emit for change notifications
 * @returns {object} slots
 */
export function createSlots(emitFn) {
    /** @type {Map<string, Array<{id:string, component:Function, priority:number}>>} */
    const _registry = new Map();

    function _sort(arr) {
        arr.sort((a, b) => a.priority - b.priority);
    }

    return {
        /**
         * Register a component into a named slot.
         * @param {string} name — slot name (e.g. 'toolbar', 'statusbar')
         * @param {object} entry — { id, component, priority? }
         * @returns {Function} unregister
         */
        register(name, { id, component, priority = 100 }) {
            if (!_registry.has(name)) _registry.set(name, []);
            const list = _registry.get(name);

            // Prevent duplicate ids in same slot
            const idx = list.findIndex(e => e.id === id);
            if (idx !== -1) list.splice(idx, 1);

            list.push({ id, component, priority });
            _sort(list);

            emitFn('slots.changed', { slot: name, action: 'register', id }, { localOnly: true });

            return () => this.unregister(name, id);
        },

        /**
         * Remove a component from a slot.
         */
        unregister(name, id) {
            const list = _registry.get(name);
            if (!list) return;
            const idx = list.findIndex(e => e.id === id);
            if (idx !== -1) {
                list.splice(idx, 1);
                if (list.length === 0) _registry.delete(name);
                emitFn('slots.changed', { slot: name, action: 'unregister', id }, { localOnly: true });
            }
        },

        /**
         * Get sorted entries for a slot.
         * @param {string} name
         * @returns {Array<{id:string, component:Function, priority:number}>}
         */
        get(name) {
            return _registry.get(name) || [];
        },

        /**
         * List all slot names that have content.
         * @returns {string[]}
         */
        names() {
            return [..._registry.keys()];
        },
    };
}
