/**
 * Label - Form label component
 * @countermeasure/web-components/primitives/label
 */

import { resolveContainer } from '../utils'

export interface LabelConfig {
  container?: HTMLElement | string
  text: string
  htmlFor?: string
  required?: boolean
  className?: string
}

export class Label {
  public readonly el: HTMLLabelElement

  private textNode: Text
  private requiredEl: HTMLSpanElement | null = null

  constructor(config: LabelConfig) {
    // Create the label element
    this.el = document.createElement('label')
    this.el.className = 'cmm-label'

    if (config.className) {
      this.el.classList.add(config.className)
    }

    if (config.htmlFor !== undefined) {
      this.el.htmlFor = config.htmlFor
    }

    // Create text node for the label text
    this.textNode = document.createTextNode(config.text)
    this.el.appendChild(this.textNode)

    // Add required indicator if needed
    if (config.required === true) {
      this.appendRequiredIndicator()
    }

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

  /** Update the label text */
  setText(text: string): void {
    this.textNode.textContent = text
  }

  /** Toggle the required indicator */
  setRequired(required: boolean): void {
    if (required && this.requiredEl === null) {
      this.appendRequiredIndicator()
    } else if (!required && this.requiredEl !== null) {
      this.requiredEl.remove()
      this.requiredEl = null
    }
  }

  /** Update the htmlFor attribute */
  setFor(id: string): void {
    this.el.htmlFor = id
  }

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

  private appendRequiredIndicator(): void {
    this.requiredEl = document.createElement('span')
    this.requiredEl.className = 'cmm-label__required'
    this.requiredEl.setAttribute('aria-hidden', 'true')
    this.requiredEl.textContent = '*'
    this.el.appendChild(this.requiredEl)
  }
}
