export interface CreateDismissOptions {
  /** Returns the content container element. */
  getContainer: () => HTMLElement | null;
  /** Called when a dismiss event occurs. */
  onDismiss: () => void;
  /** Whether Escape key triggers dismiss. Default: true. */
  dismissOnEscape?: boolean;
  /** Whether pointer outside container triggers dismiss. Default: true. */
  dismissOnPointerOutside?: boolean;
}

export interface Dismiss {
  attach: () => void;
  detach: () => void;
}

// Global stack of active dismiss handlers (topmost is last)
const layerStack: Dismiss[] = [];

/**
 * Handles dismiss interactions: Escape key and pointer-outside.
 * Uses a global layer stack so nested overlays only dismiss the topmost layer.
 */
export function createDismiss(options: CreateDismissOptions): Dismiss {
  const dismissOnEscape = options.dismissOnEscape ?? true;
  const dismissOnPointerOutside = options.dismissOnPointerOutside ?? true;

  /** Dismisses on Escape if this is the topmost layer and escape is enabled. */
  const handleKeyDown = (e: KeyboardEvent) => {
    if (!dismissOnEscape) return;
    if (e.key !== "Escape") return;
    if (layerStack[layerStack.length - 1] !== dismiss) return;
    e.preventDefault();
    options.onDismiss();
  };

  /** Dismisses on pointer-outside if this is the topmost layer and pointer-outside is enabled. */
  const handlePointerDown = (e: PointerEvent) => {
    if (!dismissOnPointerOutside) return;
    if (layerStack[layerStack.length - 1] !== dismiss) return;
    const container = options.getContainer();
    if (!container) return;
    if (container.contains(e.target as Node)) return;
    options.onDismiss();
  };

  let attached = false;

  const dismiss: Dismiss = {
    attach() {
      if (attached) return;
      attached = true;
      layerStack.push(dismiss);
      document.addEventListener("keydown", handleKeyDown);
      document.addEventListener("pointerdown", handlePointerDown);
    },
    detach() {
      if (!attached) return;
      attached = false;
      const index = layerStack.indexOf(dismiss);
      if (index !== -1) layerStack.splice(index, 1);
      document.removeEventListener("keydown", handleKeyDown);
      document.removeEventListener("pointerdown", handlePointerDown);
    },
  };

  return dismiss;
}
