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

const TOOLTIP_OFFSET = 12
const TOOLTIP_CLASS = 'cmm-chart-tooltip'

/** Structured tooltip content for safe rendering */
export interface TooltipContent {
  /** Optional title/header */
  title?: string
  /** Data items to display */
  items?: {
    label: string
    value: string | number
    color?: string
  }[]
}

/** HTML-based tooltip overlay that follows the cursor within a chart container */
export class ChartTooltip {
  private element: HTMLDivElement
  private container: HTMLElement

  constructor(container: HTMLElement) {
    this.container = container

    this.element = document.createElement('div')
    this.element.className = TOOLTIP_CLASS
    this.element.style.position = 'absolute'
    this.element.style.display = 'none'
    this.element.style.pointerEvents = 'none'
    this.element.style.backgroundColor = '#1e293b'
    this.element.style.color = '#f8fafc'
    this.element.style.padding = '6px 10px'
    this.element.style.borderRadius = '4px'
    this.element.style.fontSize = '12px'
    this.element.style.fontFamily = 'system-ui, sans-serif'
    this.element.style.lineHeight = '1.4'
    this.element.style.whiteSpace = 'nowrap'
    this.element.style.zIndex = '1000'
    this.element.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)'
    this.element.style.transition = 'opacity 0.15s ease'

    // Ensure container is a positioning context
    const containerPosition = window.getComputedStyle(this.container).position
    if (containerPosition === 'static') {
      this.container.style.position = 'relative'
    }

    this.container.appendChild(this.element)
  }

  /** Position and display the tooltip with the given content, flipping if near edges */
  show(x: number, y: number, content: string | TooltipContent): void {
    // Clear previous content safely
    this.element.textContent = ''

    if (typeof content === 'string') {
      // Plain text content - escape HTML
      this.element.textContent = content
    } else {
      // Structured content - build safely with DOM APIs
      if (content.title !== undefined) {
        const titleEl = document.createElement('div')
        titleEl.style.fontWeight = '600'
        titleEl.style.marginBottom = content.items !== undefined ? '4px' : '0'
        titleEl.textContent = content.title
        this.element.appendChild(titleEl)
      }

      if (content.items !== undefined) {
        for (const item of content.items) {
          const itemEl = document.createElement('div')
          itemEl.style.display = 'flex'
          itemEl.style.alignItems = 'center'
          itemEl.style.gap = '6px'

          if (item.color !== undefined) {
            const dot = document.createElement('span')
            dot.style.width = '8px'
            dot.style.height = '8px'
            dot.style.borderRadius = '50%'
            dot.style.backgroundColor = item.color
            itemEl.appendChild(dot)
          }

          const labelEl = document.createElement('span')
          labelEl.textContent = item.label
          itemEl.appendChild(labelEl)

          const valueEl = document.createElement('span')
          valueEl.style.marginLeft = 'auto'
          valueEl.style.fontWeight = '600'
          valueEl.textContent = String(item.value)
          itemEl.appendChild(valueEl)

          this.element.appendChild(itemEl)
        }
      }
    }

    this.element.style.display = 'block'

    const containerRect = this.container.getBoundingClientRect()
    const tooltipWidth = this.element.offsetWidth
    const tooltipHeight = this.element.offsetHeight

    let left = x + TOOLTIP_OFFSET
    let top = y - tooltipHeight - TOOLTIP_OFFSET

    // Flip horizontally if too close to right edge
    if (left + tooltipWidth > containerRect.width) {
      left = x - tooltipWidth - TOOLTIP_OFFSET
    }

    // Flip vertically if too close to top edge
    if (top < 0) {
      top = y + TOOLTIP_OFFSET
    }

    this.element.style.left = `${String(Math.max(0, left))}px`
    this.element.style.top = `${String(Math.max(0, top))}px`
  }

  /** Hide the tooltip */
  hide(): void {
    this.element.style.display = 'none'
  }

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