// src/services/dynamic-plugin-manager.ts
var DynamicPluginManager = class {
  constructor(db) {
    this.db = db;
  }
  plugins = /* @__PURE__ */ new Map();
  registeredRoutes = /* @__PURE__ */ new Map();
  adminPages = /* @__PURE__ */ new Map();
  eventHooks = /* @__PURE__ */ new Map();
  templates = /* @__PURE__ */ new Map();
  /**
   * Register a plugin
   */
  async registerPlugin(plugin) {
    console.log(`[PluginManager] Registering plugin: ${plugin.name}`);
    this.plugins.set(plugin.name, plugin);
    await this.savePluginToDatabase(plugin);
    const context = {
      db: this.db,
      env: {},
      // Will be populated at runtime
      logger: {
        info: (msg) => console.log(`[${plugin.name}] ${msg}`),
        error: (msg) => console.error(`[${plugin.name}] ${msg}`),
        warn: (msg) => console.warn(`[${plugin.name}] ${msg}`)
      }
    };
    try {
      if (plugin.install) {
        await plugin.install(context);
      }
      if (plugin.activate) {
        await plugin.activate(context);
      }
      if (plugin.routes) {
        for (const route of plugin.routes) {
          this.registeredRoutes.set(`${plugin.name}:${route.path}`, route);
          console.log(`[PluginManager] Registered route: ${route.path}`);
        }
      }
      if (plugin.adminPages) {
        for (const page of plugin.adminPages) {
          this.adminPages.set(`${plugin.name}:${page.path}`, page);
          console.log(`[PluginManager] Registered admin page: ${page.path}`);
        }
      }
      if (plugin.hooks) {
        for (const hook of plugin.hooks) {
          if (!this.eventHooks.has(hook.name)) {
            this.eventHooks.set(hook.name, []);
          }
          this.eventHooks.get(hook.name).push(hook);
          console.log(`[PluginManager] Registered hook: ${hook.name}`);
        }
      }
      console.log(`[PluginManager] Plugin ${plugin.name} registered successfully`);
    } catch (error) {
      console.error(`[PluginManager] Failed to register plugin ${plugin.name}:`, error);
      throw error;
    }
  }
  /**
   * Get all registered routes
   */
  getRoutes() {
    return this.registeredRoutes;
  }
  /**
   * Get all admin pages
   */
  getAdminPages() {
    return this.adminPages;
  }
  /**
   * Get event hooks for a specific event
   */
  getHooks(eventName) {
    return this.eventHooks.get(eventName) || [];
  }
  /**
   * Trigger event hooks
   */
  async triggerHooks(eventName, data, context) {
    const hooks = this.getHooks(eventName);
    let result = data;
    for (const hook of hooks) {
      try {
        result = await hook.handler(result, context);
      } catch (error) {
        console.error(`[PluginManager] Hook ${eventName} failed:`, error);
      }
    }
    return result;
  }
  /**
   * Get plugin by name
   */
  getPlugin(name) {
    return this.plugins.get(name);
  }
  /**
   * Get all registered plugins
   */
  getAllPlugins() {
    return Array.from(this.plugins.values());
  }
  /**
   * Save plugin to database
   */
  async savePluginToDatabase(plugin, status = "active") {
    try {
      const pluginId = crypto.randomUUID();
      await this.db.prepare(`
                INSERT OR REPLACE INTO dynamic_plugins 
                (id, name, version, description, author_name, author_email, status, manifest, updated_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            `).bind(
        pluginId,
        plugin.name,
        plugin.version,
        plugin.description || "",
        plugin.author?.name || "",
        plugin.author?.email || "",
        status,
        JSON.stringify(plugin),
        Date.now()
      ).run();
      if (plugin.adminPages) {
        for (const page of plugin.adminPages) {
          await this.db.prepare(`
                        INSERT OR REPLACE INTO plugin_admin_pages
                        (id, plugin_id, path, title, icon, description, menu_label, menu_path, menu_icon, menu_order, menu_parent)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    `).bind(
            crypto.randomUUID(),
            pluginId,
            page.path,
            page.title,
            page.icon || "",
            page.description || "",
            page.menuItem?.label || page.title,
            page.menuItem?.path || `/admin${page.path}`,
            page.menuItem?.icon || page.icon || "",
            page.menuItem?.order || 100,
            page.menuItem?.parent || ""
          ).run();
        }
      }
      if (plugin.routes) {
        for (const route of plugin.routes) {
          await this.db.prepare(`
                        INSERT OR REPLACE INTO plugin_routes
                        (id, plugin_id, path, description, requires_auth)
                        VALUES (?, ?, ?, ?, ?)
                    `).bind(
            crypto.randomUUID(),
            pluginId,
            route.path,
            route.description || "",
            route.requiresAuth ? 1 : 0
          ).run();
        }
      }
      if (plugin.hooks) {
        for (const hook of plugin.hooks) {
          await this.db.prepare(`
                        INSERT OR REPLACE INTO plugin_hooks
                        (id, plugin_id, hook_name, description)
                        VALUES (?, ?, ?, ?)
                    `).bind(
            crypto.randomUUID(),
            pluginId,
            hook.name,
            `Hook for ${hook.name} event`
          ).run();
        }
      }
      if (plugin.templates) {
        for (const [templateName, templateContent] of Object.entries(plugin.templates)) {
          await this.db.prepare(`
                        INSERT OR REPLACE INTO plugin_templates
                        (id, plugin_id, template_name, template_content, updated_at)
                        VALUES (?, ?, ?, ?, ?)
                    `).bind(
            crypto.randomUUID(),
            pluginId,
            templateName,
            templateContent,
            Date.now()
          ).run();
        }
      }
      console.log(`[PluginManager] Plugin ${plugin.name} saved to database`);
    } catch (error) {
      console.error(`[PluginManager] Failed to save plugin ${plugin.name} to database:`, error);
    }
  }
  /**
   * Get active admin pages from database
   */
  async getActiveAdminPages() {
    try {
      const result = await this.db.prepare(`
                SELECT 
                    pap.*,
                    dp.name as plugin_name,
                    dp.status as plugin_status
                FROM plugin_admin_pages pap
                JOIN dynamic_plugins dp ON pap.plugin_id = dp.id
                WHERE pap.is_active = 1 AND dp.status = 'active'
                ORDER BY pap.menu_order ASC, pap.title ASC
            `).all();
      return result.results || [];
    } catch (error) {
      console.error("[PluginManager] Failed to get active admin pages:", error);
      return [];
    }
  }
  /**
   * Get all plugins from database
   */
  async getPluginsFromDatabase() {
    try {
      const result = await this.db.prepare(`
                SELECT * FROM dynamic_plugins ORDER BY name ASC
            `).all();
      return result.results || [];
    } catch (error) {
      console.error("[PluginManager] Failed to get plugins from database:", error);
      return [];
    }
  }
  /**
   * Enable/disable plugin
   */
  async setPluginStatus(pluginName, status) {
    try {
      await this.db.prepare(`
                UPDATE dynamic_plugins 
                SET status = ?, updated_at = ?
                WHERE name = ?
            `).bind(status, Date.now(), pluginName).run();
      console.log(`[PluginManager] Plugin ${pluginName} status set to ${status}`);
    } catch (error) {
      console.error(`[PluginManager] Failed to set plugin ${pluginName} status:`, error);
    }
  }
  /**
   * Get plugin templates
   */
  async getPluginTemplates(pluginName) {
    try {
      let query = `
                SELECT pt.template_name, pt.template_content
                FROM plugin_templates pt
                JOIN dynamic_plugins dp ON pt.plugin_id = dp.id
                WHERE pt.is_active = 1 AND dp.status = 'active'
            `;
      const params = [];
      if (pluginName) {
        query += ` AND dp.name = ?`;
        params.push(pluginName);
      }
      const result = await this.db.prepare(query).bind(...params).all();
      const templates = /* @__PURE__ */ new Map();
      for (const row of result.results || []) {
        templates.set(row.template_name, row.template_content);
      }
      return templates;
    } catch (error) {
      console.error("[PluginManager] Failed to get plugin templates:", error);
      return /* @__PURE__ */ new Map();
    }
  }
  /**
   * Install a plugin (first time setup)
   */
  async installPlugin(plugin) {
    console.log(`[PluginManager] Installing plugin: ${plugin.name}`);
    const existingPlugins = await this.getPluginsFromDatabase();
    const existing = existingPlugins.find((p) => p.name === plugin.name);
    if (existing) {
      throw new Error(`Plugin ${plugin.name} is already installed`);
    }
    const context = {
      db: this.db,
      env: {},
      logger: {
        info: (msg) => console.log(`[${plugin.name}] ${msg}`),
        error: (msg) => console.error(`[${plugin.name}] ${msg}`),
        warn: (msg) => console.warn(`[${plugin.name}] ${msg}`)
      }
    };
    try {
      if (plugin.install) {
        await plugin.install(context);
        console.log(`[PluginManager] Plugin ${plugin.name} install hook completed`);
      }
      await this.savePluginToDatabase(plugin, "installed");
      await this.registerPluginFromDatabase(plugin);
      console.log(`[PluginManager] Plugin ${plugin.name} installed successfully`);
    } catch (error) {
      console.error(`[PluginManager] Failed to install plugin ${plugin.name}:`, error);
      throw error;
    }
  }
  /**
   * Uninstall a plugin (complete removal)
   */
  async uninstallPlugin(name) {
    console.log(`[PluginManager] Uninstalling plugin: ${name}`);
    const plugin = this.plugins.get(name);
    if (!plugin) {
      const dbPlugins = await this.getPluginsFromDatabase();
      const dbPlugin = dbPlugins.find((p) => p.name === name);
      if (!dbPlugin) {
        throw new Error(`Plugin ${name} not found`);
      }
    }
    const context = {
      db: this.db,
      env: {},
      logger: {
        info: (msg) => console.log(`[${name}] ${msg}`),
        error: (msg) => console.error(`[${name}] ${msg}`),
        warn: (msg) => console.warn(`[${name}] ${msg}`)
      }
    };
    try {
      await this.disablePlugin(name);
      if (plugin && plugin.uninstall) {
        await plugin.uninstall(context);
        console.log(`[PluginManager] Plugin ${name} uninstall hook completed`);
      }
      await this.removePluginFromDatabase(name);
      console.log(`[PluginManager] Plugin ${name} uninstalled successfully`);
    } catch (error) {
      console.error(`[PluginManager] Failed to uninstall plugin ${name}:`, error);
      throw error;
    }
  }
  /**
   * Enable a plugin (activate functionality)
   */
  async enablePlugin(name) {
    console.log(`[PluginManager] Enabling plugin: ${name}`);
    const dbPlugins = await this.getPluginsFromDatabase();
    const dbPlugin = dbPlugins.find((p) => p.name === name);
    if (!dbPlugin) {
      throw new Error(`Plugin ${name} not found`);
    }
    if (dbPlugin.status === "active") {
      console.log(`[PluginManager] Plugin ${name} is already enabled`);
      return;
    }
    try {
      const plugin = JSON.parse(dbPlugin.manifest);
      const context = {
        db: this.db,
        env: {},
        logger: {
          info: (msg) => console.log(`[${name}] ${msg}`),
          error: (msg) => console.error(`[${name}] ${msg}`),
          warn: (msg) => console.warn(`[${name}] ${msg}`)
        }
      };
      if (plugin.activate) {
        await plugin.activate(context);
        console.log(`[PluginManager] Plugin ${name} activate hook completed`);
      }
      await this.setPluginStatus(name, "active");
      await this.registerPluginFromDatabase(plugin);
      console.log(`[PluginManager] Plugin ${name} enabled successfully`);
    } catch (error) {
      console.error(`[PluginManager] Failed to enable plugin ${name}:`, error);
      throw error;
    }
  }
  /**
   * Disable a plugin (deactivate functionality)
   */
  async disablePlugin(name) {
    console.log(`[PluginManager] Disabling plugin: ${name}`);
    const plugin = this.plugins.get(name);
    const context = {
      db: this.db,
      env: {},
      logger: {
        info: (msg) => console.log(`[${name}] ${msg}`),
        error: (msg) => console.error(`[${name}] ${msg}`),
        warn: (msg) => console.warn(`[${name}] ${msg}`)
      }
    };
    try {
      if (plugin && plugin.deactivate) {
        await plugin.deactivate(context);
        console.log(`[PluginManager] Plugin ${name} deactivate hook completed`);
      }
      await this.setPluginStatus(name, "inactive");
      await this.unregisterPluginFromMemory(name);
      console.log(`[PluginManager] Plugin ${name} disabled successfully`);
    } catch (error) {
      console.error(`[PluginManager] Failed to disable plugin ${name}:`, error);
      throw error;
    }
  }
  /**
   * Unregister a plugin from memory only
   */
  async unregisterPluginFromMemory(name) {
    console.log(`[PluginManager] Unregistering plugin from memory: ${name}`);
    this.plugins.delete(name);
    for (const [key] of this.registeredRoutes) {
      if (key.startsWith(`${name}:`)) {
        this.registeredRoutes.delete(key);
      }
    }
    for (const [key] of this.adminPages) {
      if (key.startsWith(`${name}:`)) {
        this.adminPages.delete(key);
      }
    }
    for (const [eventName, hooks] of this.eventHooks) {
      const filtered = hooks.filter((hook) => !hook.name.startsWith(`${name}:`));
      if (filtered.length === 0) {
        this.eventHooks.delete(eventName);
      } else {
        this.eventHooks.set(eventName, filtered);
      }
    }
    console.log(`[PluginManager] Plugin ${name} unregistered from memory`);
  }
  /**
   * Remove plugin completely from database
   */
  async removePluginFromDatabase(name) {
    try {
      const result = await this.db.prepare(`
                SELECT id FROM dynamic_plugins WHERE name = ?
            `).bind(name).first();
      if (!result) {
        console.warn(`[PluginManager] Plugin ${name} not found in database`);
        return;
      }
      const pluginId = result.id;
      await this.db.prepare(`DELETE FROM plugin_templates WHERE plugin_id = ?`).bind(pluginId).run();
      await this.db.prepare(`DELETE FROM plugin_hooks WHERE plugin_id = ?`).bind(pluginId).run();
      await this.db.prepare(`DELETE FROM plugin_routes WHERE plugin_id = ?`).bind(pluginId).run();
      await this.db.prepare(`DELETE FROM plugin_admin_pages WHERE plugin_id = ?`).bind(pluginId).run();
      await this.db.prepare(`DELETE FROM dynamic_plugins WHERE id = ?`).bind(pluginId).run();
      console.log(`[PluginManager] Plugin ${name} removed from database`);
    } catch (error) {
      console.error(`[PluginManager] Failed to remove plugin ${name} from database:`, error);
      throw error;
    }
  }
  /**
   * Get plugin status
   */
  async getPluginStatus(name) {
    try {
      const result = await this.db.prepare(`
                SELECT status FROM dynamic_plugins WHERE name = ?
            `).bind(name).first();
      return result ? result.status : null;
    } catch (error) {
      console.error(`[PluginManager] Failed to get plugin ${name} status:`, error);
      return null;
    }
  }
  /**
   * Check if plugin exists
   */
  async pluginExists(name) {
    try {
      const result = await this.db.prepare(`
                SELECT COUNT(*) as count FROM dynamic_plugins WHERE name = ?
            `).bind(name).first();
      return result ? result.count > 0 : false;
    } catch (error) {
      console.error(`[PluginManager] Failed to check if plugin ${name} exists:`, error);
      return false;
    }
  }
  /**
   * Legacy unregister method (kept for compatibility)
   */
  async unregisterPlugin(name) {
    console.warn(`[PluginManager] unregisterPlugin is deprecated, use disablePlugin instead`);
    await this.disablePlugin(name);
  }
  /**
   * Load and register all active plugins from database
   */
  async loadAndRegisterActivePlugins() {
    try {
      console.log("[PluginManager] Loading active plugins from database...");
      const plugins = await this.getPluginsFromDatabase();
      const activePlugins = plugins.filter((p) => p.status === "active");
      console.log(`[PluginManager] Found ${activePlugins.length} active plugins`);
      for (const pluginData of activePlugins) {
        try {
          if (!pluginData.manifest) {
            console.warn(`[PluginManager] Plugin ${pluginData.name} has no manifest, skipping`);
            continue;
          }
          let plugin;
          try {
            plugin = JSON.parse(pluginData.manifest);
          } catch (parseError) {
            console.error(`[PluginManager] Failed to parse manifest for plugin ${pluginData.name}:`, parseError);
            continue;
          }
          if (!plugin || !plugin.name) {
            console.warn(`[PluginManager] Invalid plugin manifest for ${pluginData.name}, skipping`);
            continue;
          }
          if (this.plugins.has(plugin.name)) {
            console.log(`[PluginManager] Plugin ${plugin.name} already registered, skipping`);
            continue;
          }
          console.log(`[PluginManager] Loading plugin: ${plugin.name}`);
          await this.registerPluginFromDatabase(plugin);
        } catch (error) {
          console.error(`[PluginManager] Failed to load plugin ${pluginData.name}:`, error);
        }
      }
      console.log("[PluginManager] Active plugins loaded successfully");
    } catch (error) {
      console.error("[PluginManager] Failed to load active plugins:", error);
    }
  }
  /**
   * Register a plugin from database (skip install/activate)
   */
  async registerPluginFromDatabase(plugin) {
    console.log(`[PluginManager] Registering plugin from database: ${plugin.name}`);
    this.plugins.set(plugin.name, plugin);
    try {
      if (plugin.routes) {
        for (const route of plugin.routes) {
          this.registeredRoutes.set(`${plugin.name}:${route.path}`, route);
          console.log(`[PluginManager] Registered route: ${route.path}`);
        }
      }
      if (plugin.adminPages) {
        for (const page of plugin.adminPages) {
          this.adminPages.set(`${plugin.name}:${page.path}`, page);
          console.log(`[PluginManager] Registered admin page: ${page.path}`);
        }
      }
      if (plugin.hooks) {
        for (const hook of plugin.hooks) {
          if (!this.eventHooks.has(hook.name)) {
            this.eventHooks.set(hook.name, []);
          }
          this.eventHooks.get(hook.name).push(hook);
          console.log(`[PluginManager] Registered hook: ${hook.name}`);
        }
      }
      console.log(`[PluginManager] Plugin ${plugin.name} registered from database successfully`);
    } catch (error) {
      console.error(`[PluginManager] Failed to register plugin ${plugin.name} from database:`, error);
      throw error;
    }
  }
};
var globalPluginManager = null;
function getPluginManager(db) {
  if (!globalPluginManager && db) {
    globalPluginManager = new DynamicPluginManager(db);
  }
  if (!globalPluginManager) {
    throw new Error("Plugin manager not initialized. Call with db parameter first.");
  }
  return globalPluginManager;
}

export { DynamicPluginManager, getPluginManager };
//# sourceMappingURL=chunk-V46U3POI.js.map
//# sourceMappingURL=chunk-V46U3POI.js.map