import { getTheme } from '../../services/theme-engine'
import type { IconSetId } from '../../services/theme-engine'
import { LUCIDE_ICON_NAMES, getLucideIconPath } from '../../icons/lucide'

type GalleryIconStyle = {
  label: string
  strokeWidth: number
  linecap: 'round' | 'square' | 'butt'
  linejoin: 'round' | 'miter' | 'bevel'
  brand: boolean
}

type GallerySection = {
  section: HTMLElement
  grid: HTMLElement
}

function getGalleryIconStyle(id: IconSetId): GalleryIconStyle {
  switch (id) {
    case 'heroicons':
      return {
        label: 'Heroicons',
        strokeWidth: 2.4,
        linecap: 'round',
        linejoin: 'round',
        brand: false,
      }
    case 'phosphor':
      return {
        label: 'Phosphor',
        strokeWidth: 1.5,
        linecap: 'round',
        linejoin: 'round',
        brand: false,
      }
    case 'material':
      return {
        label: 'Material',
        strokeWidth: 2,
        linecap: 'square',
        linejoin: 'miter',
        brand: false,
      }
    case 'countermeasure':
      return {
        label: 'CounterMeasure',
        strokeWidth: 1.75,
        linecap: 'round',
        linejoin: 'round',
        brand: true,
      }
    case 'lucide':
      return { label: 'Lucide', strokeWidth: 2, linecap: 'round', linejoin: 'round', brand: false }
  }
}

function buildGalleryIcon(name: string, pathData: string, set: GalleryIconStyle): HTMLElement {
  const cell = document.createElement('div')
  cell.className = 'theme-studio-icon-gallery__cell'
  cell.tabIndex = 0
  cell.setAttribute('role', 'img')
  cell.setAttribute('aria-label', name)

  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  svg.setAttribute('viewBox', '0 0 24 24')
  svg.setAttribute('width', '28')
  svg.setAttribute('height', '28')
  svg.setAttribute('fill', 'none')
  svg.setAttribute('stroke', 'currentColor')
  svg.setAttribute('stroke-width', String(set.strokeWidth))
  svg.setAttribute('stroke-linecap', set.linecap)
  svg.setAttribute('stroke-linejoin', set.linejoin)
  svg.setAttribute('aria-hidden', 'true')

  for (const segment of pathData.split(/(?=M)/g)) {
    const trimmed = segment.trim()
    if (!trimmed) continue
    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
    path.setAttribute('d', trimmed)
    svg.appendChild(path)
  }

  cell.appendChild(svg)

  const label = document.createElement('span')
  label.className = 'theme-studio-icon-gallery__label'
  label.textContent = name
  cell.appendChild(label)

  return cell
}

export class IconGalleryBrowser {
  public readonly el: HTMLElement
  private gallery: HTMLElement | null = null
  private toggle: HTMLButtonElement | null = null
  private expanded = false
  private readonly onThemeChange: () => void

  constructor() {
    this.el = document.createElement('div')
    this.el.className = 'theme-studio-icon-gallery-browser'
    this.render()
    this.onThemeChange = () => {
      if (this.expanded) this.renderGallery()
    }
    document.addEventListener('cm:theme-change', this.onThemeChange)
  }

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

  private render(): void {
    this.el.replaceChildren()

    const toggle = document.createElement('button')
    toggle.type = 'button'
    toggle.className = 'theme-studio-icon-gallery__toggle'
    const toggleText = document.createElement('span')
    toggleText.className = 'theme-studio-icon-gallery__toggle-text'
    toggleText.textContent = 'Browse all icons'
    toggle.appendChild(toggleText)

    const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
    icon.setAttribute('aria-hidden', 'true')
    icon.setAttribute('focusable', 'false')
    icon.setAttribute('width', '14')
    icon.setAttribute('height', '14')
    icon.setAttribute('viewBox', '0 0 24 24')
    icon.setAttribute('fill', 'none')
    icon.setAttribute('stroke', 'currentColor')
    icon.setAttribute('stroke-width', '2')
    icon.setAttribute('stroke-linecap', 'round')
    icon.setAttribute('stroke-linejoin', 'round')
    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
    path.setAttribute('d', 'm6 9 6 6 6-6')
    icon.appendChild(path)
    toggle.appendChild(icon)

    toggle.setAttribute('aria-expanded', 'false')
    toggle.addEventListener('click', () => this.toggleGallery())
    this.toggle = toggle
    this.el.appendChild(toggle)

    this.gallery = document.createElement('div')
    this.gallery.className = 'theme-studio-icon-gallery'
    this.gallery.hidden = true
    this.el.appendChild(this.gallery)
  }

  private toggleGallery(): void {
    this.expanded = !this.expanded
    if (this.gallery) {
      this.gallery.hidden = !this.expanded
      if (this.expanded) this.renderGallery()
    }
    if (this.toggle) {
      this.toggle.setAttribute('aria-expanded', String(this.expanded))
      this.toggle.classList.toggle('is-expanded', this.expanded)
      const label = this.toggle.querySelector('.theme-studio-icon-gallery__toggle-text')
      if (label) label.textContent = this.expanded ? 'Hide icons' : 'Browse all icons'
    }
  }

  private renderGallery(): void {
    if (!this.gallery) return
    this.gallery.replaceChildren()

    const style = getGalleryIconStyle(getTheme().iconSet)
    const section = style.brand
      ? this.buildBrandGallerySection(style)
      : this.buildGallerySection(style)
    this.gallery.appendChild(section)
  }

  private buildBrandGallerySection(style: GalleryIconStyle): HTMLElement {
    const shell = this.buildSectionShell('CounterMeasure Brand Icons')
    shell.grid.appendChild(buildGalleryIcon('Search', 'M11 4l5 3v6l-5 3-5-3V7z M20 21l-4-4', style))
    shell.grid.appendChild(
      buildGalleryIcon(
        'Shield',
        'M12 2l9 4-3 11-6 5-6-5-3-11z M12 7v10 M7.5 10l9 4 M16.5 10l-9 4',
        style
      )
    )
    shell.grid.appendChild(
      buildGalleryIcon(
        'Settings',
        'M12 2l1.5 2.6L16 4l.5 3 3 .5L19 10l2.6 1.5L20 14l1 3-3 1-1 3-3-1-1.5 2.6L11 20l-1 2-3-1L6 18l-3-1 1-3-2.6-1.5L4 11 2 9.5 5 8l-1-3 3-1z M12 9l3 3-3 3-3-3z',
        style
      )
    )
    return shell.section
  }

  private buildGallerySection(style: GalleryIconStyle): HTMLElement {
    const shell = this.buildSectionShell(`All Icons — ${style.label} style`)
    for (const name of LUCIDE_ICON_NAMES) {
      const pathData = getLucideIconPath(name)
      if (pathData) shell.grid.appendChild(buildGalleryIcon(name, pathData, style))
    }
    return shell.section
  }

  private buildSectionShell(title: string): GallerySection {
    const section = document.createElement('div')
    section.className = 'theme-studio-icon-gallery__section'

    const heading = document.createElement('div')
    heading.className = 'theme-studio-icon-gallery__heading'
    heading.textContent = title
    section.appendChild(heading)

    const grid = document.createElement('div')
    grid.className = 'theme-studio-icon-gallery__grid'
    section.appendChild(grid)

    return { section, grid }
  }
}
