/**
 * Central z-index management for consistent stacking order
 * Higher numbers appear on top of lower numbers
 */

export const zIndexLayers = {
  // Base layer: Regular content
  base: {
    content: 'auto',
    inputElements: 1,
  },

  // Fixed UI elements
  fixed: {
    appBar: 10,
    sideMenu: 10,
    mobileNav: 250,
  },

  // Overlay backdrops (semi-transparent backgrounds)
  backdrop: {
    dropdown: 1999,  // Below modals but above fixed elements
    modal: 2999,     // Below dropdowns on modals
    contextMenu: 3999, // Below critical overlays
  },

  // Interactive overlays
  overlay: {
    dropdown: 2000,     // Dropdowns and select menus
    modal: 3000,        // Modal dialogs
    contextMenu: 4000,  // Context menus and tooltips
    toast: 5000,        // Toast notifications (highest priority)
  },

  // Special cases for nested elements
  modalDropdown: 3500,    // Dropdowns inside modals
  wysiwygMenus: 4500,     // Editor formatting menus
} as const;

// Helper function to get z-index value
export function getZIndex(category: keyof typeof zIndexLayers, subcategory?: string): number | string {
  const categoryObj = zIndexLayers[category];
  if (typeof categoryObj === 'object' && subcategory) {
    return categoryObj[subcategory as keyof typeof categoryObj] || 'auto';
  }
  return typeof categoryObj === 'number' ? categoryObj : 'auto';
}

// Z-index assignments for components
export const componentZIndex = {
  'dees-modal': zIndexLayers.overlay.modal,
  'dees-windowlayer': zIndexLayers.overlay.dropdown,
  'dees-contextmenu': zIndexLayers.overlay.contextMenu,
  'dees-toast': zIndexLayers.overlay.toast,
  'dees-appui-mainmenu': zIndexLayers.fixed.appBar,
  'dees-mobilenavigation': zIndexLayers.fixed.mobileNav,
  'dees-slash-menu': zIndexLayers.wysiwygMenus,
  'dees-formatting-menu': zIndexLayers.wysiwygMenus,
} as const;

/**
 * Z-Index Registry for managing stacked elements
 * Simple incremental z-index assignment based on creation order
 */
export class ZIndexRegistry {
  private static instance: ZIndexRegistry;
  private activeElements = new Set<HTMLElement>();
  private elementZIndexMap = new WeakMap<HTMLElement, number>();
  private currentZIndex = 1000; // Starting z-index
  
  private constructor() {}
  
  public static getInstance(): ZIndexRegistry {
    if (!ZIndexRegistry.instance) {
      ZIndexRegistry.instance = new ZIndexRegistry();
    }
    return ZIndexRegistry.instance;
  }
  
  /**
   * Get the next available z-index
   * @returns The next available z-index
   */
  public getNextZIndex(): number {
    this.currentZIndex += 10;
    return this.currentZIndex;
  }
  
  /**
   * Register an element with the z-index registry
   * @param element - The HTML element to register
   * @param zIndex - The z-index assigned to this element
   */
  public register(element: HTMLElement, zIndex: number): void {
    this.activeElements.add(element);
    this.elementZIndexMap.set(element, zIndex);
  }
  
  /**
   * Unregister an element from the z-index registry
   * @param element - The HTML element to unregister
   */
  public unregister(element: HTMLElement): void {
    this.activeElements.delete(element);
    this.elementZIndexMap.delete(element);
    
    // If no more active elements, reset counter to base
    if (this.activeElements.size === 0) {
      this.currentZIndex = 1000;
    }
  }
  
  /**
   * Get the z-index for a specific element
   * @param element - The HTML element
   * @returns The z-index or undefined if not registered
   */
  public getElementZIndex(element: HTMLElement): number | undefined {
    return this.elementZIndexMap.get(element);
  }
  
  /**
   * Get count of active elements
   * @returns Number of active elements
   */
  public getActiveCount(): number {
    return this.activeElements.size;
  }
  
  /**
   * Get the current highest z-index
   * @returns The current z-index value
   */
  public getCurrentZIndex(): number {
    return this.currentZIndex;
  }
  
  /**
   * Clear all registrations (useful for testing)
   */
  public clear(): void {
    this.activeElements.clear();
    this.elementZIndexMap = new WeakMap();
    this.currentZIndex = 1000;
  }
  
  /**
   * Get all active elements in z-index order
   * @returns Array of elements sorted by z-index
   */
  public getActiveElementsInOrder(): HTMLElement[] {
    return Array.from(this.activeElements).sort((a, b) => {
      const aZ = this.elementZIndexMap.get(a) || 0;
      const bZ = this.elementZIndexMap.get(b) || 0;
      return aZ - bZ;
    });
  }
}

// Export singleton instance for convenience
export const zIndexRegistry = ZIndexRegistry.getInstance();