/**
 * SidebarComponent - Programmatic sidebar with sections, badges, and footer
 * @countermeasure/web-components/sidebar/component
 *
 * Unlike sidebar/enhance (which enhances server-rendered HTML), this module
 * builds the sidebar DOM from a config object. Use it when the sidebar
 * structure is driven entirely by client-side data.
 *
 * Usage:
 *   import { SidebarComponent } from '@countermeasure/web-components/sidebar/component'
 *
 *   const sidebar = new SidebarComponent({
 *     container: '#sidebar-root',
 *     sections: [{ id: 'main', label: 'Nav', items: [...] }],
 *     user: { name: 'Alice' },
 *     onNavigate: item => console.log(item.id),
 *   })
 *   sidebar.setActive('dashboard')
 */

import { getIconSvgInner, type IconSet } from '../icons/index'
import { resolveContainer } from '../primitives/utils'
import { type SidebarComponentConfig } from './types'

/** Create an SVG element populated with icon content from the registry. */
function createIconSvg(iconSet: IconSet, name: string): SVGElement {
  const svgNs = 'http://www.w3.org/2000/svg'
  const svg = document.createElementNS(svgNs, 'svg')
  svg.setAttribute('xmlns', svgNs)
  svg.setAttribute('width', '18')
  svg.setAttribute('height', '18')
  svg.setAttribute('viewBox', '0 0 24 24')
  svg.setAttribute('fill', 'none')
  svg.setAttribute('stroke', 'currentColor')
  svg.setAttribute('stroke-width', '2')
  svg.setAttribute('stroke-linecap', 'round')
  svg.setAttribute('stroke-linejoin', 'round')
  svg.classList.add('sidebar__item-icon')
  svg.setAttribute('data-icon', name)
  svg.setAttribute('aria-hidden', 'true')

  const inner = getIconSvgInner(iconSet, name)
  if (inner) {
    svg.innerHTML = inner
  }

  return svg
}

export class SidebarComponent {
  private readonly container: HTMLElement
  private readonly aside: HTMLElement
  private readonly config: SidebarComponentConfig
  private readonly iconSet: IconSet

  constructor(config: SidebarComponentConfig) {
    this.config = config
    this.container = resolveContainer(config.container)
    this.iconSet = config.iconSet ?? 'lucide'

    this.aside = document.createElement('aside')
    this.aside.classList.add('sidebar')
    this.aside.setAttribute('data-sidebar', config.variant ?? 'app')

    this.render()
    this.container.appendChild(this.aside)
  }

  private render(): void {
    for (const section of this.config.sections) {
      const sectionEl = document.createElement('div')
      sectionEl.classList.add('sidebar__section')

      if (section.label) {
        const labelEl = document.createElement('div')
        labelEl.classList.add('sidebar__section-label')
        labelEl.textContent = section.label
        sectionEl.appendChild(labelEl)
      }

      for (const item of section.items) {
        const link = document.createElement('a')
        link.classList.add('sidebar__item')
        link.setAttribute('data-item-id', item.id)

        if (item.icon) {
          const icon = createIconSvg(this.iconSet, item.icon)
          link.appendChild(icon)
        }

        const label = document.createElement('span')
        label.classList.add('sidebar__item-label')
        label.textContent = item.label
        link.appendChild(label)

        if (item.badge !== undefined && item.badge > 0) {
          const badge = document.createElement('span')
          badge.classList.add('sidebar__badge')
          badge.setAttribute('data-badge', item.id)
          badge.textContent = String(item.badge)
          link.appendChild(badge)
        }

        link.addEventListener('click', () => {
          if (this.config.onNavigate) {
            this.config.onNavigate(item)
          }
          if (item.onClick) {
            item.onClick()
          }
        })

        sectionEl.appendChild(link)
      }

      this.aside.appendChild(sectionEl)
    }

    this.renderFooter()
  }

  private renderFooter(): void {
    const hasUser = this.config.user !== undefined
    const hasActions =
      this.config.footerActions !== undefined && this.config.footerActions.length > 0

    if (!hasUser && !hasActions) {
      return
    }

    const footer = document.createElement('div')
    footer.classList.add('sidebar__footer')

    const footerBar = document.createElement('div')
    footerBar.classList.add('sidebar__footer-bar')

    if (hasUser && this.config.user) {
      const userSpan = document.createElement('span')
      userSpan.classList.add('sidebar__footer-user')

      const nameSpan = document.createElement('span')
      nameSpan.classList.add('sidebar__footer-name')
      nameSpan.textContent = this.config.user.name
      userSpan.appendChild(nameSpan)

      footerBar.appendChild(userSpan)
    }

    if (hasActions && this.config.footerActions) {
      const iconsSpan = document.createElement('span')
      iconsSpan.classList.add('sidebar__footer-icons')

      for (const action of this.config.footerActions) {
        const button = document.createElement('button')
        button.classList.add('sidebar__footer-icon')
        if (action.danger === true) {
          button.classList.add('sidebar__footer-icon--danger')
        }
        button.setAttribute('aria-label', action.label)

        const icon = createIconSvg(this.iconSet, action.icon)
        button.appendChild(icon)

        if (action.onClick) {
          const handler = action.onClick
          button.addEventListener('click', () => {
            handler()
          })
        }

        iconsSpan.appendChild(button)
      }

      footerBar.appendChild(iconsSpan)
    }

    footer.appendChild(footerBar)
    this.aside.appendChild(footer)
  }

  /** Mark a nav item as active, removing active state from all others. */
  setActive(itemId: string): void {
    this.aside.querySelectorAll<HTMLElement>('.sidebar__item').forEach(el => {
      el.classList.remove('sidebar__item--active')
    })

    const target = this.aside.querySelector<HTMLElement>(`[data-item-id="${itemId}"]`)
    if (target) {
      target.classList.add('sidebar__item--active')
    }
  }

  /** Update the badge count for a nav item (empty string when count is 0). */
  updateBadge(itemId: string, count: number): void {
    const badge = this.aside.querySelector<HTMLElement>(`[data-badge="${itemId}"]`)
    if (badge) {
      badge.textContent = count > 0 ? String(count) : ''
    }
  }

  /** Toggle the sidebar between collapsed and expanded states. */
  toggleCollapse(): void {
    const isCollapsed = this.aside.classList.toggle('sidebar--collapsed')
    if (this.config.onCollapse) {
      this.config.onCollapse(isCollapsed)
    }
  }

  /** Collapse the sidebar. */
  collapse(): void {
    this.aside.classList.add('sidebar--collapsed')
  }

  /** Expand the sidebar. */
  expand(): void {
    this.aside.classList.remove('sidebar--collapsed')
  }

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