/**
 * InputGroup - Groups an input with prefix/suffix elements
 * @countermeasure/web-components/primitives/input
 */

import { type InputGroupConfig } from './types'
import { resolveContainer } from '../utils'

export class InputGroup {
  public readonly el: HTMLDivElement

  private prefixEl: HTMLDivElement | null = null
  private suffixEl: HTMLDivElement | null = null
  private readonly contentEl: HTMLDivElement

  constructor(config: InputGroupConfig) {
    this.el = document.createElement('div')
    this.el.className = 'cmm-input-group'

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

    // Content area where the input is placed
    this.contentEl = document.createElement('div')
    this.contentEl.className = 'cmm-input-group__content'
    this.el.appendChild(this.contentEl)

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

  /** Set a prefix element or text before the input */
  setPrefix(content: HTMLElement | string): void {
    if (this.prefixEl !== null) {
      this.prefixEl.remove()
    }

    this.prefixEl = document.createElement('div')
    this.prefixEl.className = 'cmm-input-group__prefix'

    if (typeof content === 'string') {
      this.prefixEl.textContent = content
    } else {
      this.prefixEl.appendChild(content)
    }

    // Insert before content area
    this.el.insertBefore(this.prefixEl, this.contentEl)
  }

  /** Set a suffix element or text after the input */
  setSuffix(content: HTMLElement | string): void {
    if (this.suffixEl !== null) {
      this.suffixEl.remove()
    }

    this.suffixEl = document.createElement('div')
    this.suffixEl.className = 'cmm-input-group__suffix'

    if (typeof content === 'string') {
      this.suffixEl.textContent = content
    } else {
      this.suffixEl.appendChild(content)
    }

    // Insert after content area
    this.el.appendChild(this.suffixEl)
  }

  /** Get the content area element to append an input to */
  getContentEl(): HTMLDivElement {
    return this.contentEl
  }

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