/**
 * StripOverlayLayer — Single overlay container for all positioned overlays.
 *
 * Owns: DOM element with position: absolute; inset: 0; pointer-events: none; overflow: visible
 * Children restore pointer-events: auto
 * Used by: ActionPopover (Story 1.5), ConfirmationBar (Story 3.2)
 *
 * Import rule: may import from src/core/, src/contracts/, src/utils/ ONLY.
 * Constructors are side-effect free — call init() from module.js Hooks.once('ready').
 *
 * Story 1.5: Original creation for ActionPopover support
 * Story 3.2: Extended to support ConfirmationBar
 *
 * @module ui/shared/StripOverlayLayer
 */

/**
 * Single overlay container for all positioned overlays.
 * Provides a common parent element with pointer-events: none that allows
 * children to restore pointer-events: auto for specific interactive areas.
 */
export class StripOverlayLayer {
  /**
   * @param {import('../../foundry/FoundryAdapter.js').FoundryAdapter} adapter
   *   Injected FoundryAdapter surface.
   */
  constructor(adapter) {
    this._adapter = adapter;
    /** @type {HTMLElement|null} The overlay container element */
    this._element = null;
    /** @type {Map<string, HTMLElement>} Track rendered overlays by key */
    this._overlays = new Map();
  }

  /**
   * Initializes the StripOverlayLayer by creating the DOM element.
   * Side-effect: Creates and appends the overlay container to the ScryingPoolStrip.
   */
  init() {
    // Create overlay container element
    this._element = document.createElement('div');
    this._element.className = 'sp-strip__overlay-layer';
    this._element.setAttribute('aria-hidden', 'true');
    
    // Critical styles per UX-DR6
    this._element.style.cssText = `
      position: absolute;
      inset: 0;
      pointer-events: none;
      overflow: visible;
    `;

    // Try to find the ScryingPoolStrip element to append to
    // The strip is created in Story 1.5 as a floating Application window
    const stripElement = document.querySelector?.('.scrying-pool-strip');
    if (stripElement) {
      stripElement.appendChild(this._element);
    } else {
      // Fallback: if strip not found, append to body (shouldn't happen in normal flow)
      console.warn('[ScryingPool] StripOverlayLayer: ScryingPoolStrip not found, appending to body');
      document.body.appendChild(this._element);
    }
  }

  /**
   * Returns the overlay container element.
   * @returns {HTMLElement|null} The overlay element.
   */
  get element() {
    return this._element;
  }

  /**
   * Renders content into the overlay layer.
   * The content will have pointer-events: auto to allow interaction.
   *
   * @param {string|HTMLElement} content - HTML string or DOM element to render.
   * @param {string} [key] - Optional key to track this overlay for replacement.
   * @returns {HTMLElement|null} The rendered element, or null if failed.
   */
  render(content, key = null) {
    if (!this._element) {
      console.warn('[ScryingPool] StripOverlayLayer: Cannot render, element not initialized');
      return null;
    }

    // Remove previous overlay if key is provided
    if (key && this._overlays.has(key)) {
      const previous = this._overlays.get(key);
      if (previous && previous.parentNode) {
        previous.parentNode.removeChild(previous);
      }
      this._overlays.delete(key);
    }

    // Create container for the content
    const container = document.createElement('div');
    container.style.pointerEvents = 'auto';

    // Set content
    if (typeof content === 'string') {
      container.innerHTML = content;
    } else if (content instanceof HTMLElement) {
      container.appendChild(content);
    } else {
      console.warn('[ScryingPool] StripOverlayLayer: Invalid content type');
      return null;
    }

    // Append to overlay layer
    this._element.appendChild(container);

    // Track by key if provided
    if (key) {
      this._overlays.set(key, container);
    }

    return container;
  }

  /**
   * Removes an overlay by key.
   *
   * @param {string} key - The key of the overlay to remove.
   */
  remove(key) {
    if (!this._overlays.has(key)) {
      return;
    }

    const overlay = this._overlays.get(key);
    if (overlay && overlay.parentNode) {
      overlay.parentNode.removeChild(overlay);
    }
    this._overlays.delete(key);
  }

  /**
   * Removes all overlays from the layer.
   */
  clearAll() {
    for (const [, overlay] of this._overlays) {
      if (overlay && overlay.parentNode) {
        overlay.parentNode.removeChild(overlay);
      }
    }
    this._overlays.clear();
  }

  /**
   * Cleans up the StripOverlayLayer by removing the DOM element.
   * Safe to call multiple times.
   */
  teardown() {
    this.clearAll();
    
    if (this._element && this._element.parentNode) {
      this._element.parentNode.removeChild(this._element);
    }
    this._element = null;
  }
}
