import {
  PLUGIN_REGISTRY,
  ROUTE_METADATA,
  PLUGIN_METADATA
} from "@nextsparkjs/registries/plugin-registry";
const DEBUG_PLUGINS = process.env.NEXTSPARK_DEBUG_PLUGINS === "true";
const globalCache = globalThis;
class PluginService {
  // ============================================================================
  // Core Query Methods (14)
  // ============================================================================
  /**
   * Get all registered plugins
   *
   * @returns Array of PluginConfig objects
   *
   * @example
   * ```typescript
   * const plugins = PluginService.getAll()
   * // [{ name: 'ai', version: '1.0.0', ... }, ...]
   * ```
   */
  static getAll() {
    return Object.values(PLUGIN_REGISTRY).map((entry) => entry.config);
  }
  /**
   * Get a specific plugin by name
   *
   * @param name - Plugin name
   * @returns PluginConfig or undefined if not found
   *
   * @example
   * ```typescript
   * const plugin = PluginService.get('ai')
   * // { name: 'ai', version: '1.0.0', ... }
   * ```
   */
  static get(name) {
    var _a;
    return (_a = PLUGIN_REGISTRY[name]) == null ? void 0 : _a.config;
  }
  /**
   * Get full plugin registry entry by name
   *
   * @param name - Plugin name
   * @returns PluginRegistryEntry or undefined if not found
   *
   * @example
   * ```typescript
   * const entry = PluginService.getEntry('ai')
   * // { name: 'ai', config: {...}, hasAPI: true, ... }
   * ```
   */
  static getEntry(name) {
    return PLUGIN_REGISTRY[name];
  }
  /**
   * Get all plugins that have API capabilities
   *
   * @returns Array of PluginRegistryEntry objects with API
   *
   * @example
   * ```typescript
   * const apiPlugins = PluginService.getWithAPI()
   * // [{ name: 'ai', hasAPI: true, ... }]
   * ```
   */
  static getWithAPI() {
    return Object.values(PLUGIN_REGISTRY).filter((entry) => entry.hasAPI);
  }
  /**
   * Get all plugins that have entities
   *
   * @returns Array of PluginRegistryEntry objects with entities
   *
   * @example
   * ```typescript
   * const pluginsWithEntities = PluginService.getWithEntities()
   * // [{ name: 'crm', entities: [...], ... }]
   * ```
   */
  static getWithEntities() {
    return Object.values(PLUGIN_REGISTRY).filter(
      (entry) => entry.entities && entry.entities.length > 0
    );
  }
  /**
   * Get all entities across all plugins
   *
   * @returns Array of all PluginEntity objects
   *
   * @example
   * ```typescript
   * const entities = PluginService.getAllEntities()
   * // [{ name: 'Contact', pluginContext: {...}, ... }, ...]
   * ```
   */
  static getAllEntities() {
    return Object.values(PLUGIN_REGISTRY).flatMap((entry) => entry.entities || []);
  }
  /**
   * Get entities for a specific plugin
   *
   * @param pluginName - Plugin name
   * @returns Array of PluginEntity objects for the plugin
   *
   * @example
   * ```typescript
   * const entities = PluginService.getEntities('crm')
   * // [{ name: 'Contact', ... }, { name: 'Deal', ... }]
   * ```
   */
  static getEntities(pluginName) {
    var _a;
    return ((_a = PLUGIN_REGISTRY[pluginName]) == null ? void 0 : _a.entities) || [];
  }
  /**
   * Get all route file endpoints across all plugins
   *
   * @returns Array of all RouteFileEndpoint objects
   *
   * @example
   * ```typescript
   * const endpoints = PluginService.getAllRouteEndpoints()
   * // [{ path: '/api/plugins/ai/generate', methods: ['POST'], ... }]
   * ```
   */
  static getAllRouteEndpoints() {
    return Object.values(PLUGIN_REGISTRY).flatMap((entry) => entry.routeFiles || []);
  }
  /**
   * Find a specific route endpoint by path
   *
   * @param path - Route path to find
   * @returns RouteFileEndpoint or undefined if not found
   *
   * @example
   * ```typescript
   * const endpoint = PluginService.findRouteEndpoint('/api/plugins/ai/generate')
   * // { path: '/api/plugins/ai/generate', methods: ['POST'], ... }
   * ```
   */
  static findRouteEndpoint(path) {
    return this.getAllRouteEndpoints().find((endpoint) => endpoint.path === path);
  }
  /**
   * Get route metadata for a specific path
   *
   * @param path - Route path
   * @returns RouteMetadata or null if not found
   *
   * @example
   * ```typescript
   * const metadata = PluginService.getRouteMetadata('/api/plugins/ai/generate')
   * // { plugin: 'ai', methods: ['POST'], filePath: '...' }
   * ```
   */
  static getRouteMetadata(path) {
    const metadata = ROUTE_METADATA[path];
    return metadata || null;
  }
  /**
   * Check if a route exists (optionally with specific method)
   *
   * @param path - Route path
   * @param method - Optional HTTP method to check
   * @returns True if route exists
   *
   * @example
   * ```typescript
   * PluginService.hasRoute('/api/plugins/ai/generate') // true
   * PluginService.hasRoute('/api/plugins/ai/generate', 'POST') // true
   * PluginService.hasRoute('/api/plugins/ai/generate', 'DELETE') // false
   * ```
   */
  static hasRoute(path, method) {
    const metadata = ROUTE_METADATA[path];
    if (!metadata) return false;
    return method ? metadata.methods.includes(method) : true;
  }
  /**
   * Get all plugin names
   *
   * @returns Array of plugin name strings
   *
   * @example
   * ```typescript
   * const names = PluginService.getNames()
   * // ['ai', 'crm', 'analytics']
   * ```
   */
  static getNames() {
    return Object.keys(PLUGIN_REGISTRY);
  }
  /**
   * Get total plugin count
   *
   * @returns Number of registered plugins
   *
   * @example
   * ```typescript
   * const count = PluginService.getCount()
   * // 3
   * ```
   */
  static getCount() {
    return Object.keys(PLUGIN_REGISTRY).length;
  }
  /**
   * Check if a plugin exists
   *
   * @param name - Plugin name
   * @returns True if plugin exists
   *
   * @example
   * ```typescript
   * PluginService.exists('ai') // true
   * PluginService.exists('invalid') // false
   * ```
   */
  static exists(name) {
    return name in PLUGIN_REGISTRY;
  }
  // ============================================================================
  // Plugin Function Access (3)
  // ============================================================================
  /**
   * Get a specific function from a plugin's API
   *
   * Supports nested API objects (e.g., AIAPI.generateText)
   *
   * @param pluginName - Plugin name
   * @param functionName - Function name to retrieve
   * @returns Function or undefined if not found
   *
   * @example
   * ```typescript
   * const generateText = PluginService.getFunction('ai', 'generateText')
   * if (generateText) {
   *   const result = await generateText('Hello')
   * }
   * ```
   */
  static getFunction(pluginName, functionName) {
    var _a;
    try {
      const plugin = PLUGIN_REGISTRY[pluginName];
      if (!((_a = plugin == null ? void 0 : plugin.config) == null ? void 0 : _a.api)) return void 0;
      const api = plugin.config.api;
      if (typeof api[functionName] === "function") {
        return api[functionName];
      }
      for (const value of Object.values(api)) {
        if (typeof value === "object" && value !== null && functionName in value) {
          const nestedFunc = value[functionName];
          if (typeof nestedFunc === "function") {
            return nestedFunc;
          }
        }
      }
      return void 0;
    } catch {
      return void 0;
    }
  }
  /**
   * Get all available function names from a plugin's API
   *
   * @param pluginName - Plugin name
   * @returns Array of function name strings
   *
   * @example
   * ```typescript
   * const functions = PluginService.getFunctions('ai')
   * // ['generateText', 'enhanceText', 'analyzeText']
   * ```
   */
  static getFunctions(pluginName) {
    var _a;
    try {
      const plugin = PLUGIN_REGISTRY[pluginName];
      if (!((_a = plugin == null ? void 0 : plugin.config) == null ? void 0 : _a.api)) {
        return [];
      }
      const api = plugin.config.api;
      const functions = [];
      Object.entries(api).forEach(([key, value]) => {
        if (typeof value === "function") {
          functions.push(key);
        } else if (typeof value === "object" && value !== null) {
          Object.entries(value).forEach(([nestedKey, nestedValue]) => {
            if (typeof nestedValue === "function") {
              functions.push(nestedKey);
            }
          });
        }
      });
      return functions;
    } catch {
      return [];
    }
  }
  /**
   * Check if a plugin has a specific function
   *
   * @param pluginName - Plugin name
   * @param functionName - Function name to check
   * @returns True if function exists
   *
   * @example
   * ```typescript
   * PluginService.hasFunction('ai', 'generateText') // true
   * PluginService.hasFunction('ai', 'invalid') // false
   * ```
   */
  static hasFunction(pluginName, functionName) {
    return this.getFunction(pluginName, functionName) !== void 0;
  }
  // ============================================================================
  // Server Initialization (1)
  // ============================================================================
  /**
   * Initialize all plugins by executing their onLoad hooks
   *
   * Server-side only. Executes async onLoad hooks for all plugins.
   * Continues with other plugins if one fails.
   * Uses globalThis cache to prevent re-initialization.
   *
   * @returns Promise that resolves when all plugins are initialized
   *
   * @example
   * ```typescript
   * // In server-side initialization code
   * await PluginService.initializeAll()
   * ```
   */
  static async initializeAll() {
    var _a;
    if (typeof window !== "undefined") {
      return;
    }
    if (globalCache.__nextspark_plugins_initialized) {
      if (DEBUG_PLUGINS) {
        console.log("[Plugin Registry] Already initialized, skipping");
      }
      return;
    }
    if (DEBUG_PLUGINS) {
      console.log("[Plugin Registry] Initializing plugin system...");
    }
    const pluginEntries = Object.values(PLUGIN_REGISTRY);
    if (DEBUG_PLUGINS) {
      console.log(`[Plugin Registry] Found ${pluginEntries.length} plugins to initialize`);
    }
    for (const pluginEntry of pluginEntries) {
      try {
        const plugin = pluginEntry.config;
        if ((_a = plugin.hooks) == null ? void 0 : _a.onLoad) {
          if (DEBUG_PLUGINS) {
            console.log(`[Plugin Registry] Loading plugin: ${plugin.name}`);
          }
          await plugin.hooks.onLoad();
          if (DEBUG_PLUGINS) {
            console.log(`[Plugin Registry] Plugin ${plugin.name} loaded successfully`);
          }
        }
      } catch (error) {
        console.error(`[Plugin Registry] Error loading plugin ${pluginEntry.name}:`, error);
      }
    }
    globalCache.__nextspark_plugins_initialized = true;
    if (DEBUG_PLUGINS) {
      console.log("[Plugin Registry] Plugin system initialized successfully");
    }
  }
  // ============================================================================
  // Metadata & Helpers (3)
  // ============================================================================
  /**
   * Get plugin metadata
   *
   * @returns Plugin system metadata object
   *
   * @example
   * ```typescript
   * const metadata = PluginService.getMetadata()
   * // { totalPlugins: 3, pluginsWithAPI: 2, ... }
   * ```
   */
  static getMetadata() {
    return PLUGIN_METADATA;
  }
  /**
   * Get plugin route endpoints (alias for getAllRouteEndpoints)
   *
   * @returns Array of all RouteFileEndpoint objects
   *
   * @example
   * ```typescript
   * const endpoints = PluginService.getPluginRouteEndpoints()
   * // [{ path: '/api/plugins/ai/generate', methods: ['POST'], ... }]
   * ```
   */
  static getPluginRouteEndpoints() {
    return this.getAllRouteEndpoints();
  }
  /**
   * Validate plugin configuration structure
   *
   * @param name - Plugin name
   * @returns True if plugin has valid configuration
   *
   * @example
   * ```typescript
   * PluginService.isValid('ai') // true
   * PluginService.isValid('invalid') // false
   * ```
   */
  static isValid(name) {
    const plugin = PLUGIN_REGISTRY[name];
    return !!plugin && !!plugin.config && !!plugin.config.name;
  }
  /**
   * Get the raw plugin registry object
   *
   * @returns The complete PLUGIN_REGISTRY object
   *
   * @example
   * ```typescript
   * const registry = PluginService.getRegistry()
   * // { ai: {...}, crm: {...}, ... }
   * ```
   */
  static getRegistry() {
    return PLUGIN_REGISTRY;
  }
}
function usePlugin(pluginName) {
  var _a;
  const plugin = PLUGIN_REGISTRY[pluginName];
  if (!plugin) {
    if (DEBUG_PLUGINS) {
      console.warn(`[Plugin Registry] Plugin '${pluginName}' not found`);
    }
    return createPluginStubs(pluginName, "NOT_FOUND");
  }
  if (!((_a = plugin.config) == null ? void 0 : _a.api)) {
    if (DEBUG_PLUGINS) {
      console.debug(
        `[Plugin Registry] Plugin '${pluginName}' has no API (normal for config/style/component plugins)`
      );
    }
    return {
      isAvailable: () => true,
      // Plugin exists, just has no API
      getStatus: () => ({
        available: true,
        pluginName,
        hasAPI: false,
        message: `Plugin '${pluginName}' is available but has no API functions`
      })
    };
  }
  const api = plugin.config.api;
  const pluginAPI = {};
  Object.entries(api).forEach(([key, value]) => {
    if (typeof value === "function") {
      pluginAPI[key] = value;
    } else if (typeof value === "object" && value !== null) {
      Object.entries(value).forEach(([nestedKey, nestedValue]) => {
        if (typeof nestedValue === "function") {
          pluginAPI[nestedKey] = nestedValue;
        }
      });
    }
  });
  pluginAPI.isAvailable = () => true;
  pluginAPI.getStatus = () => ({
    available: true,
    pluginName,
    hasAPI: true,
    functionCount: Object.keys(pluginAPI).filter((key) => typeof pluginAPI[key] === "function").length - 2,
    // -2 for status helpers
    message: `Plugin '${pluginName}' is available with ${Object.keys(pluginAPI).length - 2} API functions`
  });
  return pluginAPI;
}
function createPluginStubs(pluginName, reason) {
  const message = reason === "NOT_FOUND" ? `Plugin '${pluginName}' is not available or has been disabled` : `Plugin '${pluginName}' has no API available`;
  const commonFunctions = [
    "generateText",
    "enhanceText",
    "analyzeText",
    "getSuggestions",
    "isContentSafe",
    "estimateRequestCost",
    "processEntity",
    "create",
    "update",
    "delete",
    "get",
    "list"
  ];
  const stubs = {};
  commonFunctions.forEach((funcName) => {
    stubs[funcName] = async (...args) => {
      if (DEBUG_PLUGINS) {
        console.warn(`[Plugin '${pluginName}'] ${message}`);
      }
      return {
        error: true,
        message,
        pluginName,
        reason,
        suggestion: reason === "NOT_FOUND" ? "Verify that the plugin is installed and enabled" : "Contact the system administrator"
      };
    };
  });
  stubs.isAvailable = () => false;
  stubs.getStatus = () => ({
    available: false,
    pluginName,
    hasAPI: false,
    reason,
    message
  });
  return stubs;
}
const getRegisteredPlugins = PluginService.getAll;
const getPlugin = PluginService.get;
const getPluginsWithAPI = PluginService.getWithAPI;
const getPluginsWithEntities = PluginService.getWithEntities;
const getAllPluginEntities = PluginService.getAllEntities;
const getPluginEntitiesByName = PluginService.getEntities;
const getAllRouteEndpoints = PluginService.getAllRouteEndpoints;
const findRouteEndpoint = (path) => PluginService.findRouteEndpoint(path);
const getPluginRouteEndpoints = () => PluginService.getPluginRouteEndpoints();
const getPluginFunction = PluginService.getFunction;
const getPluginFunctions = PluginService.getFunctions;
const hasPluginFunction = (pluginName, functionName) => PluginService.hasFunction(pluginName, functionName);
const getRouteMetadata = PluginService.getRouteMetadata;
const hasRoute = PluginService.hasRoute;
const initializeAllPlugins = PluginService.initializeAll;
export {
  PluginService,
  findRouteEndpoint,
  getAllPluginEntities,
  getAllRouteEndpoints,
  getPlugin,
  getPluginEntitiesByName,
  getPluginFunction,
  getPluginFunctions,
  getPluginRouteEndpoints,
  getPluginsWithAPI,
  getPluginsWithEntities,
  getRegisteredPlugins,
  getRouteMetadata,
  hasPluginFunction,
  hasRoute,
  initializeAllPlugins,
  usePlugin
};
