/**
 * Glass Slider — surface-transparency slider that drives `transparency` on the
 * theme engine; the engine writes `--bg-glass`, `--bg-glass-2`, `--bg-glass-3`.
 *
 * Mirrors Theme.jsx applyTheme L354-358:
 *   const t = clamp(transparency, 0, 0.30);
 *   root.style.setProperty('--bg-glass',   `rgba(${tint}, ${t * 0.5})`);
 *   root.style.setProperty('--bg-glass-2', `rgba(${tint}, ${t})`);
 *   root.style.setProperty('--bg-glass-3', `rgba(${tint}, ${t * 1.75})`);
 */

import { getTheme, setThemePartial } from '../../services/theme-engine'

function clamp(v: number, min: number, max: number): number {
  return Math.max(min, Math.min(max, v))
}

const MIN = 0
const MAX = 0.2
const STEP = 0.01

interface GlassSliderOptions {
  /** When true, render an inline "Solid · slider · Frosted" layout (Theme Studio body). */
  expanded?: boolean
}

export class GlassSlider {
  public readonly el: HTMLElement
  private readonly input: HTMLInputElement
  private readonly value: HTMLSpanElement
  private readonly _onThemeChange: () => void

  constructor(options: GlassSliderOptions = {}) {
    const expanded = options.expanded === true
    const initial = clamp(getTheme().transparency, MIN, MAX)

    this.el = document.createElement('div')
    this.el.className = expanded
      ? 'preview-glass-slider preview-glass-slider--expanded'
      : 'preview-glass-slider'

    if (!expanded) {
      const label = document.createElement('span')
      label.className = 'preview-glass-slider__label'
      label.textContent = 'Glass'
      this.el.appendChild(label)
    }

    const row = document.createElement('div')
    row.className = 'preview-glass-slider__row'

    if (expanded) {
      const left = document.createElement('span')
      left.className = 'preview-glass-slider__edge'
      left.textContent = 'Solid'
      row.appendChild(left)
    }

    this.input = document.createElement('input')
    this.input.type = 'range'
    this.input.min = String(MIN)
    this.input.max = String(MAX)
    this.input.step = String(STEP)
    this.input.value = String(initial)
    this.input.className = 'preview-glass-slider__input'
    this.input.setAttribute('aria-label', 'Surface transparency')
    const valueId = `cm-glass-value-${Math.random().toString(36).slice(2, 8)}`
    this.input.setAttribute('aria-describedby', valueId)
    this.input.setAttribute('aria-valuetext', `${Math.round(initial * 100)}% transparency`)
    row.appendChild(this.input)

    if (expanded) {
      const right = document.createElement('span')
      right.className = 'preview-glass-slider__edge'
      right.textContent = 'Frosted'
      row.appendChild(right)
    }

    this.value = document.createElement('span')
    this.value.className = 'preview-glass-slider__value'
    this.value.id = valueId
    this.value.setAttribute('aria-live', 'polite')
    this.value.textContent = formatLevel(initial)
    row.appendChild(this.value)

    this.el.appendChild(row)
    this.applySliderFill(initial)

    this.input.addEventListener('input', () => {
      const next = clamp(Number(this.input.value), MIN, MAX)
      setThemePartial({ transparency: next })
    })

    this._onThemeChange = () => {
      const t = clamp(getTheme().transparency, MIN, MAX)
      if (this.input.value !== String(t)) this.input.value = String(t)
      this.input.setAttribute('aria-valuetext', `${Math.round(t * 100)}% transparency`)
      this.value.textContent = formatLevel(t)
      this.applySliderFill(t)
    }
    document.addEventListener('cm:theme-change', this._onThemeChange)
  }

  destroy(): void {
    document.removeEventListener('cm:theme-change', this._onThemeChange)
  }

  private applySliderFill(level: number): void {
    const pct = ((level - MIN) / (MAX - MIN)) * 100
    this.input.style.setProperty('--slider-pct', `${pct}%`)
  }
}

function formatLevel(level: number): string {
  return `${Math.round(level * 100)}%`
}
