/**
 * UptimeBar - Horizontal bar showing uptime/downtime segments over time
 * @countermeasure/web-components/display/uptime-bar
 */

import { type UptimeBarConfig, type UptimeSegment } from './types'
import { resolveContainer, uniqueId } from '../../primitives/utils'

export type { UptimeBarConfig, UptimeSegment, UptimeSegmentStatus } from './types'

/** Calculate uptime percentage from segments */
function calculateUptimePercent(segments: UptimeSegment[]): string {
  if (segments.length === 0) {
    return '0.0'
  }
  let upCount = 0
  for (const segment of segments) {
    if (segment.status === 'up') {
      upCount += 1
    }
  }
  return ((upCount / segments.length) * 100).toFixed(1)
}

export class UptimeBar {
  public readonly el: HTMLDivElement

  private readonly barId: string
  private segmentsEl: HTMLDivElement
  private labelEl: HTMLDivElement | null = null
  private readonly showLabels: boolean
  private readonly height: number

  constructor(config: UptimeBarConfig) {
    this.barId = uniqueId('cmm-uptime-bar')
    this.showLabels = config.showLabels !== false
    this.height = config.height ?? 32

    // Create root element
    this.el = document.createElement('div')
    this.el.id = this.barId
    this.el.className = this.buildClassName(config.className)
    this.el.setAttribute('role', 'img')
    this.el.setAttribute('aria-label', 'Uptime status bar')

    // Create segments container
    this.segmentsEl = document.createElement('div')
    this.segmentsEl.className = 'cmm-uptime-bar__segments'
    this.segmentsEl.style.height = `${String(this.height)}px`
    this.el.appendChild(this.segmentsEl)

    // Create label
    if (this.showLabels) {
      this.labelEl = document.createElement('div')
      this.labelEl.className = 'cmm-uptime-bar__label'
      this.el.appendChild(this.labelEl)
    }

    // Render initial segments
    this.renderSegments(config.segments)

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

  /** Replace all segments with a new set */
  setSegments(segments: UptimeSegment[]): void {
    this.renderSegments(segments)
  }

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

  private renderSegments(segments: UptimeSegment[]): void {
    // Clear existing segments
    this.segmentsEl.textContent = ''

    for (const segment of segments) {
      const segEl = document.createElement('div')
      segEl.className = `cmm-uptime-bar__segment cmm-uptime-bar__segment--${segment.status}`

      if (segment.tooltip !== undefined) {
        segEl.title = segment.tooltip
      }

      this.segmentsEl.appendChild(segEl)
    }

    // Update label
    if (this.labelEl !== null) {
      const percent = calculateUptimePercent(segments)
      this.labelEl.textContent = `${percent}% uptime`
      this.el.setAttribute('aria-label', `Uptime status bar: ${percent}% uptime`)
    }
  }

  private buildClassName(extra?: string): string {
    const classes = ['cmm-uptime-bar']
    if (extra) {
      classes.push(extra)
    }
    return classes.join(' ')
  }
}
