'use strict';

var React = require('react');

/**
 * plugins.ts — Plugin system for @nice2dev/ui-graphics editors.
 *
 * Allows third-party extensions to register custom tools, filters,
 * export formats, and UI panels for any editor.
 */
// ── Plugin Registry ─────────────────────────────────────────────
class PluginRegistryImpl {
    constructor() {
        this.plugins = new Map();
        this.listeners = new Map();
    }
    /** Register a plugin. Calls onInit if defined. */
    register(plugin) {
        var _a;
        if (this.plugins.has(plugin.id)) {
            console.warn(`[PluginRegistry] Plugin "${plugin.id}" already registered, replacing.`);
            this.unregister(plugin.id);
        }
        this.plugins.set(plugin.id, plugin);
        (_a = plugin.onInit) === null || _a === void 0 ? void 0 : _a.call(plugin);
        this.emit("register", plugin);
    }
    /** Unregister a plugin. Calls onDestroy if defined. */
    unregister(pluginId) {
        var _a;
        const plugin = this.plugins.get(pluginId);
        if (plugin) {
            (_a = plugin.onDestroy) === null || _a === void 0 ? void 0 : _a.call(plugin);
            this.plugins.delete(pluginId);
            this.emit("unregister", plugin);
        }
    }
    /** Get a registered plugin by ID. */
    get(pluginId) {
        return this.plugins.get(pluginId);
    }
    /** Get all registered plugins. */
    getAll() {
        return Array.from(this.plugins.values());
    }
    /** Get plugins for a specific editor type. */
    getForEditor(editor) {
        return this.getAll().filter((p) => !p.editors || p.editors.length === 0 || p.editors.includes(editor));
    }
    /** Get all tools from plugins for a specific editor. */
    getTools(editor) {
        return this.getForEditor(editor).flatMap((p) => { var _a; return (_a = p.tools) !== null && _a !== void 0 ? _a : []; });
    }
    /** Get all filters from plugins for a specific editor. */
    getFilters(editor) {
        return this.getForEditor(editor).flatMap((p) => { var _a; return (_a = p.filters) !== null && _a !== void 0 ? _a : []; });
    }
    /** Get all exporters from plugins for a specific editor. */
    getExporters(editor) {
        return this.getForEditor(editor).flatMap((p) => { var _a; return (_a = p.exporters) !== null && _a !== void 0 ? _a : []; });
    }
    /** Get all panels from plugins for a specific editor. */
    getPanels(editor) {
        return this.getForEditor(editor).flatMap((p) => { var _a; return (_a = p.panels) !== null && _a !== void 0 ? _a : []; });
    }
    /** Get all menu actions from plugins for a specific editor. */
    getMenuActions(editor) {
        return this.getForEditor(editor).flatMap((p) => { var _a; return (_a = p.menuActions) !== null && _a !== void 0 ? _a : []; });
    }
    /** Subscribe to registry events. */
    on(event, handler) {
        if (!this.listeners.has(event))
            this.listeners.set(event, new Set());
        this.listeners.get(event).add(handler);
        return () => { var _a; return (_a = this.listeners.get(event)) === null || _a === void 0 ? void 0 : _a.delete(handler); };
    }
    emit(event, plugin) {
        var _a;
        (_a = this.listeners.get(event)) === null || _a === void 0 ? void 0 : _a.forEach((h) => h(plugin));
    }
    /** Clear all plugins. */
    clear() {
        var _a;
        for (const plugin of this.plugins.values()) {
            (_a = plugin.onDestroy) === null || _a === void 0 ? void 0 : _a.call(plugin);
        }
        this.plugins.clear();
    }
}
/** Global plugin registry singleton. */
const PluginRegistry = new PluginRegistryImpl();
// ── React Hook ──────────────────────────────────────────────────
/** React hook that returns plugins for a specific editor, re-renders on changes. */
function usePlugins(editor) {
    const [, setTick] = React.useState(0);
    React.useEffect(() => {
        const unsub1 = PluginRegistry.on("register", () => setTick((t) => t + 1));
        const unsub2 = PluginRegistry.on("unregister", () => setTick((t) => t + 1));
        return () => { unsub1(); unsub2(); };
    }, []);
    return {
        plugins: PluginRegistry.getForEditor(editor),
        tools: PluginRegistry.getTools(editor),
        filters: PluginRegistry.getFilters(editor),
        exporters: PluginRegistry.getExporters(editor),
        panels: PluginRegistry.getPanels(editor),
        menuActions: PluginRegistry.getMenuActions(editor),
    };
}
// ── Plugin Context (React) ──────────────────────────────────────
const PluginContext = React.createContext(PluginRegistry);
const NicePluginProvider = ({ plugins, children }) => {
    React.useEffect(() => {
        if (plugins) {
            plugins.forEach((p) => PluginRegistry.register(p));
            return () => plugins.forEach((p) => PluginRegistry.unregister(p.id));
        }
    }, [plugins]);
    return React.createElement(PluginContext.Provider, { value: PluginRegistry }, children);
};
function usePluginRegistry() {
    return React.useContext(PluginContext);
}

exports.NicePluginProvider = NicePluginProvider;
exports.PluginRegistry = PluginRegistry;
exports.usePluginRegistry = usePluginRegistry;
exports.usePlugins = usePlugins;
//# sourceMappingURL=plugins.js.map
