/**
 * SeverityIndicator - Visual severity level display for CVEs, alerts, etc.
 * @countermeasure/web-components/display/severity-indicator
 */

import { type SeverityIndicatorConfig, type SeverityLevel } from './types'
import { resolveContainer, uniqueId } from '../../primitives/utils'

export type { SeverityIndicatorConfig, SeverityLevel } from './types'

/** Capitalized labels for each severity level */
const LEVEL_LABELS: Record<SeverityLevel, string> = {
  critical: 'Critical',
  high: 'High',
  medium: 'Medium',
  low: 'Low',
  info: 'Info',
  none: 'None',
}

export class SeverityIndicator {
  public readonly el: HTMLDivElement

  private readonly indicatorId: string
  private currentLevel: SeverityLevel
  private iconEl: HTMLSpanElement | null = null
  private labelEl: HTMLSpanElement | null = null
  private readonly showLabel: boolean
  private readonly showIcon: boolean
  private readonly compact: boolean

  constructor(config: SeverityIndicatorConfig) {
    this.indicatorId = uniqueId('cmm-severity')
    this.currentLevel = config.level
    this.showLabel = config.showLabel !== false
    this.showIcon = config.showIcon !== false
    this.compact = config.compact === true

    // Create root element
    this.el = document.createElement('div')
    this.el.id = this.indicatorId
    this.el.className = this.buildClassName(config.className)
    this.el.setAttribute('role', 'status')
    this.el.setAttribute('aria-label', `Severity: ${LEVEL_LABELS[this.currentLevel]}`)

    // Create icon (colored dot)
    if (this.showIcon) {
      this.iconEl = document.createElement('span')
      this.iconEl.className = 'cmm-severity__icon'
      this.iconEl.setAttribute('aria-hidden', 'true')
      this.el.appendChild(this.iconEl)
    }

    // Create label
    if (this.showLabel) {
      this.labelEl = document.createElement('span')
      this.labelEl.className = 'cmm-severity__label'
      this.labelEl.textContent = LEVEL_LABELS[this.currentLevel]
      this.el.appendChild(this.labelEl)
    }

    // Mount if container provided
    if (config.container !== undefined) {
      const parent = resolveContainer(config.container)
      parent.appendChild(this.el)
    }
  }

  /** Update the displayed severity level */
  setLevel(level: SeverityLevel): void {
    this.el.classList.remove(`cmm-severity--${this.currentLevel}`)
    this.currentLevel = level
    this.el.classList.add(`cmm-severity--${this.currentLevel}`)
    this.el.setAttribute('aria-label', `Severity: ${LEVEL_LABELS[this.currentLevel]}`)

    if (this.labelEl !== null) {
      this.labelEl.textContent = LEVEL_LABELS[this.currentLevel]
    }
  }

  /** Remove the element from the DOM and clean up */
  destroy(): void {
    this.el.remove()
  }

  private buildClassName(extra?: string): string {
    const classes = ['cmm-severity', `cmm-severity--${this.currentLevel}`]
    if (this.compact) {
      classes.push('cmm-severity--compact')
    }
    if (extra) {
      classes.push(extra)
    }
    return classes.join(' ')
  }
}
