/**
 * Chart legend overlay
 * @countermeasure/web-components/charts/legend
 */

import type { LegendConfig, LegendItem } from './types'

/** HTML-based chart legend overlay positioned relative to a container */
export class ChartLegend {
  private element: HTMLDivElement
  private items: LegendItem[] = []
  private toggleCallback: ((index: number, active: boolean) => void) | null = null

  constructor(container: HTMLElement, config?: LegendConfig) {
    const position = config?.position ?? 'top'
    const visible = config?.visible ?? true

    this.element = document.createElement('div')
    this.element.className = `cmm-chart-legend cmm-chart-legend--${position}`

    this.element.style.display = visible ? 'flex' : 'none'
    this.element.style.flexWrap = 'wrap'
    this.element.style.gap = '8px'
    this.element.style.padding = '4px 0'
    this.element.style.fontSize = '12px'
    this.element.style.fontFamily = 'system-ui, sans-serif'

    if (position === 'top' || position === 'bottom') {
      this.element.style.justifyContent = 'center'
    } else {
      this.element.style.flexDirection = 'column'
    }

    if (position === 'top') {
      container.insertBefore(this.element, container.firstChild)
    } else {
      container.appendChild(this.element)
    }
  }

  /** Render legend items with color indicators and labels */
  update(items: LegendItem[]): void {
    this.items = items
    this.element.innerHTML = ''

    for (let i = 0; i < items.length; i++) {
      const item = items[i]
      if (item === undefined) continue

      const entry = document.createElement('span')
      entry.style.display = 'inline-flex'
      entry.style.alignItems = 'center'
      entry.style.gap = '4px'
      entry.style.cursor = 'pointer'
      entry.style.userSelect = 'none'
      entry.style.opacity = item.active === false ? '0.4' : '1'

      const dot = document.createElement('span')
      dot.style.width = '10px'
      dot.style.height = '10px'
      dot.style.borderRadius = '50%'
      dot.style.backgroundColor = item.color
      dot.style.display = 'inline-block'
      dot.style.flexShrink = '0'

      const label = document.createElement('span')
      label.style.color = '#334155'
      label.textContent = item.label

      entry.appendChild(dot)
      entry.appendChild(label)

      const index = i
      entry.addEventListener('click', () => {
        this.handleToggle(index)
      })

      this.element.appendChild(entry)
    }
  }

  /** Register a callback invoked when a legend item is clicked */
  onToggle(callback: (index: number, active: boolean) => void): void {
    this.toggleCallback = callback
  }

  /** Remove the legend element from the DOM */
  destroy(): void {
    this.element.remove()
  }

  private handleToggle(index: number): void {
    const item = this.items[index]
    if (item === undefined) return

    const nowActive = item.active === false
    item.active = nowActive
    this.update(this.items)

    if (this.toggleCallback !== null) {
      this.toggleCallback(index, nowActive)
    }
  }
}
