import { resetTheme } from '../../services/theme-engine'
import { AccentSwitcher } from './accent-switcher'
import { DensitySwitcher } from './density-switcher'
import { FontStackPicker } from './font-stack-picker'
import { GlassSlider } from './glass-slider'
import { IconGalleryBrowser } from './icon-gallery-browser'
import { IconSetPicker } from './icon-set-picker'
import { IconUsageMatrix } from './icon-usage-matrix'
import { RadiusSlider } from './radius-slider'
import { ThemePresetGrid } from './theme-preset-grid'
import { ThemePreviewTile } from './theme-preview-tile'
import { ThemeSwitcher } from './theme-switcher'

export interface ThemeStudioOptions {
  showTabs?: boolean
  showHeader?: boolean
  showBrandSection?: boolean
}

const DEFAULT_OPTIONS: Required<ThemeStudioOptions> = {
  showTabs: true,
  showHeader: true,
  showBrandSection: true,
}

function el<K extends keyof HTMLElementTagNameMap>(
  tag: K,
  className?: string,
  text?: string
): HTMLElementTagNameMap[K] {
  const node = document.createElement(tag)
  if (className) node.className = className
  if (text !== undefined) node.textContent = text
  return node
}

function buildSection(
  title: string,
  helper: string,
  body: HTMLElement,
  rightSlot?: HTMLElement
): HTMLElement {
  const section = el('section', 'theme-studio-section')
  const head = el('div', 'theme-studio-section__head')
  const titles = el('div', 'theme-studio-section__titles')
  titles.appendChild(el('h3', 'theme-studio-section__title', title))
  titles.appendChild(el('div', 'theme-studio-section__helper', helper))
  head.appendChild(titles)
  if (rightSlot) head.appendChild(rightSlot)
  section.appendChild(head)
  section.appendChild(body)
  return section
}

function buildTabStrip(): HTMLElement {
  const strip = el('div', 'theme-studio-tabs')
  const tabs = ['Profile', 'Organization', 'Appearance', 'About'] as const
  for (const tab of tabs) {
    const button = el('button', 'theme-studio-tab', tab)
    button.type = 'button'
    if (tab === 'Appearance') button.classList.add('is-active')
    button.disabled = tab !== 'Appearance'
    strip.appendChild(button)
  }
  return strip
}

function buildResetLink(): HTMLButtonElement {
  const button = el('button', 'theme-studio-link', 'Reset to default')
  button.type = 'button'
  button.addEventListener('click', () => {
    resetTheme()
  })
  return button
}

export class ThemeStudio {
  public readonly el: HTMLElement
  private readonly options: Required<ThemeStudioOptions>
  private children: Array<{ el: HTMLElement; destroy?: () => void }> = []

  constructor(options: ThemeStudioOptions = {}) {
    this.options = { ...DEFAULT_OPTIONS, ...options }
    this.el = document.createElement('section')
    this.el.className = 'theme-studio-pane'
    this.render()
  }

  render(): void {
    for (const child of this.children) child.destroy?.()
    this.children = []

    this.el.replaceChildren()

    if (this.options.showTabs) {
      this.el.appendChild(buildTabStrip())
    }

    if (this.options.showHeader) {
      const header = el('header', 'theme-studio-pane__header')
      header.appendChild(el('h1', 'theme-studio-pane__title', 'Appearance'))
      header.appendChild(
        el(
          'p',
          'theme-studio-pane__subtitle',
          'Customize how CounterMeasure looks. Pick a preset, tweak the color mode, accent, transparency, typography, and icons. Changes apply immediately and persist on this device.'
        )
      )
      this.el.appendChild(header)
    }

    const presetGrid = new ThemePresetGrid()
    this.children.push(presetGrid)
    this.el.appendChild(
      buildSection(
        'Start from a preset',
        'Curated combinations of mode, accent, font, and icon style.',
        presetGrid.el,
        buildResetLink()
      )
    )

    const previewTile = new ThemePreviewTile()
    this.children.push(previewTile)
    this.el.appendChild(
      buildSection(
        'Live preview',
        'A miniature app shell that re-renders as you tweak settings below.',
        previewTile.el
      )
    )

    const themeSwitcher = new ThemeSwitcher()
    this.children.push(themeSwitcher)
    this.el.appendChild(
      buildSection('Color Mode', 'Choose how the interface looks.', themeSwitcher.el)
    )

    const accentSwitcher = new AccentSwitcher()
    this.children.push(accentSwitcher)
    this.el.appendChild(
      buildSection(
        'Accent Color',
        'Pick a color that highlights actions and links.',
        accentSwitcher.el
      )
    )

    const glassSlider = new GlassSlider({ expanded: true })
    this.children.push(glassSlider)
    this.el.appendChild(
      buildSection(
        'Surface Transparency',
        'How translucent panels, hover states, and overlays appear.',
        glassSlider.el
      )
    )

    const fontStackPicker = new FontStackPicker()
    this.children.push(fontStackPicker)
    this.el.appendChild(
      buildSection('Typography', 'Select the typeface used throughout the app.', fontStackPicker.el)
    )

    const iconSetPicker = new IconSetPicker()
    const iconGalleryBrowser = new IconGalleryBrowser()
    this.children.push(iconSetPicker)
    this.children.push(iconGalleryBrowser)
    const iconSetBody = el('div', 'theme-studio-iconsets-wrap')
    iconSetBody.appendChild(iconSetPicker.el)
    iconSetBody.appendChild(iconGalleryBrowser.el)
    this.el.appendChild(
      buildSection('Icon Set', 'Choose the icon style for navigation and content.', iconSetBody)
    )

    if (this.options.showBrandSection) {
      const brandBody = el('div', 'theme-studio-brand-note')
      brandBody.appendChild(
        el(
          'p',
          'theme-studio-brand-note__text',
          'Brand assets live under design-system brand resources. Switch icon sets to CounterMeasure above to apply the bespoke security glyphs.'
        )
      )
      this.el.appendChild(
        buildSection('Brand', 'Logo, wordmark, and brand glyph references.', brandBody)
      )
    }
    this.el.appendChild(this.buildAdvancedSection())
  }

  private buildAdvancedSection(): HTMLElement {
    const details = document.createElement('details')
    details.className = 'theme-studio-section theme-studio-section--advanced'

    const summary = document.createElement('summary')
    summary.className = 'theme-studio-section__head theme-studio-section__head--summary'

    const titles = el('div', 'theme-studio-section__titles')
    titles.appendChild(el('h3', 'theme-studio-section__title', 'Advanced'))
    titles.appendChild(
      el('div', 'theme-studio-section__helper', 'Density, corner radius, and per-icon overrides')
    )
    summary.appendChild(titles)

    const toggle = el('span', 'theme-studio-section__chev', 'Show')
    summary.appendChild(toggle)

    details.appendChild(summary)
    details.appendChild(this.buildAdvanced())

    details.addEventListener('toggle', () => {
      toggle.textContent = details.open ? 'Hide' : 'Show'
    })

    return details
  }

  private buildAdvanced(): HTMLElement {
    const wrap = el('div', 'theme-studio-advanced')

    const densitySwitcher = new DensitySwitcher()
    this.children.push(densitySwitcher)
    const densityRow = el('div', 'theme-studio-advanced__row')
    densityRow.appendChild(densitySwitcher.el)
    wrap.appendChild(densityRow)

    const radiusSlider = new RadiusSlider()
    this.children.push(radiusSlider)
    const radiusRow = el('div', 'theme-studio-advanced__row')
    radiusRow.appendChild(radiusSlider.el)
    wrap.appendChild(radiusRow)

    const matrixHead = el('div', 'theme-studio-advanced__matrix-head')
    matrixHead.appendChild(el('h4', 'theme-studio-advanced__matrix-title', 'Per-icon mapping'))
    matrixHead.appendChild(
      el(
        'p',
        'theme-studio-advanced__matrix-helper',
        'Rebind any icon slot. Useful if your team thinks of detection as a bug instead of a shield.'
      )
    )
    wrap.appendChild(matrixHead)

    const iconUsageMatrix = new IconUsageMatrix()
    this.children.push(iconUsageMatrix)
    wrap.appendChild(iconUsageMatrix.el)
    return wrap
  }

  destroy(): void {
    for (const child of this.children) child.destroy?.()
    this.children = []
  }
}

export function renderThemeStudio(
  container: HTMLElement,
  options?: ThemeStudioOptions
): ThemeStudio {
  const studio = new ThemeStudio(options)
  container.replaceChildren()
  container.appendChild(studio.el)
  return studio
}
