import type { CoreService } from '../core/tokens'
import type { FixItConfig, MaskOverlayHandler } from '../types'
import { getThemeMode, isDarkMode } from '../utils'

/**
 * Core module — shared state initialization and mask overlay management.
 *
 * Responsibilities:
 * - Load and expose page/site configuration from `window.config`.
 * - Track theme mode (light/dark) and provide `isDark` / `themeMode` accessors.
 * - Manage mask overlay visibility for search and menu drawers.
 */
export class CoreModule implements CoreService {
  readonly config: FixItConfig
  readonly version: string
  themeMode: string
  isDark: boolean

  private activeMaskOverlay: string | null = null
  private readonly maskOverlays = new Map<string, MaskOverlayHandler>()

  constructor() {
    this.config = window.config
    this.version = this.config.version
    this.themeMode = getThemeMode()
    this.isDark = isDarkMode()

    window.objectFitImages?.()
  }

  /** Register a named mask overlay with open/close/isActive handlers. */
  registerMaskOverlay(name: string, handlers: MaskOverlayHandler) {
    this.maskOverlays.set(name, handlers)
  }

  /** Toggle the mask element's blur class based on active overlay state. */
  syncMaskState() {
    document.getElementById('mask')?.classList.toggle('is-blur', Boolean(this.activeMaskOverlay))
  }

  /** Open a named mask overlay, closing any previously active one. */
  openMaskOverlay(name: string) {
    const overlay = this.maskOverlays.get(name)
    if (!overlay)
      return
    if (this.activeMaskOverlay && this.activeMaskOverlay !== name) {
      this.closeMaskOverlay(this.activeMaskOverlay, true)
    }
    overlay.onOpen?.()
    this.activeMaskOverlay = name
    this.syncMaskState()
  }

  /** Close a named mask overlay and optionally skip mask state sync. */
  closeMaskOverlay(name: string, skipSync = false) {
    const overlay = this.maskOverlays.get(name)
    if (!overlay)
      return
    overlay.onClose?.()
    if (this.activeMaskOverlay === name) {
      this.activeMaskOverlay = null
    }
    !skipSync && this.syncMaskState()
  }

  /** Toggle a named mask overlay open/closed. */
  toggleMaskOverlay(name: string) {
    const overlay = this.maskOverlays.get(name)
    if (!overlay)
      return
    const isActive = overlay.isActive?.() ?? this.activeMaskOverlay === name
    if (this.activeMaskOverlay === name && isActive) {
      this.closeMaskOverlay(name)
      return
    }
    this.openMaskOverlay(name)
  }

  /** Close whichever mask overlay is currently active. */
  closeActiveMaskOverlay() {
    if (!this.activeMaskOverlay) {
      this.syncMaskState()
      return
    }
    this.closeMaskOverlay(this.activeMaskOverlay)
  }
}
