import { reactive, computed } from "vue";

/**
 * Context configuration for sub-sidebar.
 * @typedef {Object} SubSidebarContextConfig
 * @property {string} key - Unique identifier for the context
 * @property {string} label - Display label for the context (shown in sub-sidebar header if needed)
 * @property {string} [description] - Optional description shown below the title in the sub-sidebar header card
 * @property {Array<Object>} items - Menu items for the sub-sidebar (same structure as menuModel items)
 * @property {string} [parentPath] - Optional base path for relative item paths
 */

/**
 * Registry of available context configurations.
 * Contexts can be registered here or loaded from external configuration.
 */
const contextRegistry = reactive(new Map());

/**
 * Currently active context configuration.
 * Set to null when no context is active (no sub-sidebar shown).
 */
const activeContextKey = reactive({ value: null });

/**
 * Helper functions for route guards (can be called outside of component setup).
 * These directly manipulate the module-level state.
 */
export function activateContextFromGuard(key) {
  if (!contextRegistry.has(key)) {
    console.warn(`Context "${key}" is not registered`);
    return;
  }
  activeContextKey.value = key;
}

export function deactivateContextFromGuard() {
  activeContextKey.value = null;
}

/**
 * Composable for managing sub-sidebar contexts.
 *
 * This system allows you to:
 * - Register context configurations (key, label, items)
 * - Activate/deactivate contexts
 * - Query the active context
 *
 * The layout uses this to determine if a sub-sidebar should be shown,
 * without knowing anything about routes, pages, or domains.
 */
export function useSubSidebarContext() {
  /**
   * Register a context configuration.
   * @param {string} key - Unique identifier for the context
   * @param {SubSidebarContextConfig} config - Context configuration object
   */
  function registerContext(key, config) {
    if (!key || typeof key !== "string") {
      throw new Error("Context key must be a non-empty string");
    }
    if (!config || !config.label) {
      throw new Error("Context config must have a label");
    }
    if (!Array.isArray(config.items)) {
      throw new Error("Context config must have an items array");
    }

    contextRegistry.set(key, {
      key,
      label: config.label,
      description: config.description ?? null,
      items: config.items,
      parentPath: config.parentPath || "",
    });
  }

  /**
   * Unregister a context configuration.
   * @param {string} key - Context key to remove
   */
  function unregisterContext(key) {
    contextRegistry.delete(key);
    // If the active context is being unregistered, deactivate it
    if (activeContextKey.value === key) {
      activeContextKey.value = null;
    }
  }

  /**
   * Activate a context by key.
   * @param {string} key - Context key to activate
   */
  function activateContext(key) {
    if (!contextRegistry.has(key)) {
      console.warn(`Context "${key}" is not registered`);
      return;
    }
    activeContextKey.value = key;
  }

  /**
   * Deactivate the current context (hide sub-sidebar).
   */
  function deactivateContext() {
    activeContextKey.value = null;
  }

  /**
   * Get the active context configuration, or null if none is active.
   * @returns {SubSidebarContextConfig|null}
   */
  const activeContext = computed(() => {
    if (!activeContextKey.value) return null;
    return contextRegistry.get(activeContextKey.value) || null;
  });

  /**
   * Check if a context is currently active.
   * @returns {boolean}
   */
  const hasActiveContext = computed(() => activeContextKey.value !== null);

  /**
   * Get all registered context keys.
   * @returns {string[]}
   */
  const registeredKeys = computed(() => Array.from(contextRegistry.keys()));

  /**
   * Check if a context key is registered.
   * @param {string} key - Context key to check
   * @returns {boolean}
   */
  function isRegistered(key) {
    return contextRegistry.has(key);
  }

  /**
   * Get a context configuration by key.
   * @param {string} key - Context key
   * @returns {SubSidebarContextConfig|undefined}
   */
  function getContext(key) {
    return contextRegistry.get(key);
  }

  /**
   * Clear all registered contexts and deactivate any active context.
   */
  function clearAll() {
    contextRegistry.clear();
    activeContextKey.value = null;
  }

  return {
    // State
    activeContext,
    hasActiveContext,
    registeredKeys,

    // Methods
    registerContext,
    unregisterContext,
    activateContext,
    deactivateContext,
    isRegistered,
    getContext,
    clearAll,
  };
}
