import React, { useLayoutEffect, useRef, useState } from 'react'

export interface SidebarNavItem {
  label: string
  icon: string
  href?: string
  badge?: number
  children?: SidebarNavItem[]
  disabled?: boolean
  active?: boolean
}

export interface SidebarNavGroup {
  title?: string
  children: SidebarNavItem[]
}

export interface SidebarNavProps {
  items: SidebarNavGroup[]
  activePath?: string
  onItemClick?: (item: SidebarNavItem) => void
  header?: React.ReactNode
  footer?: React.ReactNode
  showLogo?: boolean
  showUser?: boolean
}

export const SidebarNav: React.FC<SidebarNavProps> = ({
  items,
  activePath,
  onItemClick,
  header,
  footer,
  showLogo = true,
  showUser = true,
}) => {
  const [expanded, setExpanded] = useState<Set<number>>(new Set())
  const navRef = useRef<HTMLElement>(null)
  const [indicator, setIndicator] = useState<{ top: number; left: number; width: number; height: number } | null>(null)

  const toggleExpanded = (key: number) => {
    setExpanded(prev => {
      const next = new Set(prev)
      if (next.has(key)) next.delete(key)
      else next.add(key)
      return next
    })
  }

  useLayoutEffect(() => {
    const nav = navRef.current
    if (!nav) return
    const active = nav.querySelector<HTMLElement>('[data-active="true"]')
    if (!active) { setIndicator(null); return }
    const navRect = nav.getBoundingClientRect()
    const aRect = active.getBoundingClientRect()
    setIndicator({
      top: aRect.top - navRect.top + nav.scrollTop,
      left: aRect.left - navRect.left,
      width: aRect.width,
      height: aRect.height,
    })
  }, [activePath, expanded, items])

  return (
    <aside className="w-[220px] bg-slate-50 border-r border-slate-100 flex flex-col py-4 flex-shrink-0">
      {header ?? (showLogo && (
        <div className="px-4 mb-5 flex items-center gap-2.5">
          <div className="w-8 h-8 rounded-[10px] bg-gradient-to-br from-teal-400 to-teal-500 flex items-center justify-center">
            <span className="text-white text-sm font-black">CP</span>
          </div>
          <div>
            <div className="text-body-sm font-extrabold text-slate-900">Console</div>
            <div className="text-caption text-slate-400 font-semibold">Admin Panel</div>
          </div>
        </div>
      ))}

      <nav ref={navRef} className="relative flex-1 px-2 overflow-y-auto">
        {indicator && (
          <div
            className="absolute bg-teal-50 rounded-[10px] pointer-events-none"
            style={{
              top: indicator.top,
              left: indicator.left,
              width: indicator.width,
              height: indicator.height,
              transition: 'top 0.2s ease-out, left 0.2s ease-out',
            }}
          />
        )}
        {items.map((group, groupIndex) => (
          <div key={groupIndex} className={groupIndex > 0 ? 'mt-4' : ''}>
            {group.title && (
              <p className="px-3 mb-1.5 text-caption text-slate-400 font-bold uppercase tracking-widest">
                {group.title}
              </p>
            )}
            {group.children?.map((item, itemIndex) => {
              const key = groupIndex * 1000 + itemIndex
              const isActive = item.active ?? (activePath ? activePath === item.href : false)
              const hasChildren = (item.children?.length ?? 0) > 0
              const isExpanded = expanded.has(key)
              const isDisabled = item.disabled ?? false
              const useButton = !!onItemClick || isDisabled

              const itemClass = `relative z-10 flex items-center gap-2.5 px-3 py-2 rounded-[10px] mb-0.5 transition-colors w-full text-left
                ${isActive ? 'text-teal-600' : isDisabled ? 'text-slate-300 cursor-not-allowed' : 'text-slate-500 hover:text-slate-800 hover:bg-slate-100 cursor-pointer'}
              `

              const handleClick = (e: React.MouseEvent) => {
                if (isDisabled) return
                if (hasChildren) { e.preventDefault(); toggleExpanded(key); return }
                onItemClick?.(item)
              }

              const navItemContent = (
                <>
                  <span className={`material-symbols-outlined text-h2 ${isActive ? 'text-teal-600' : ''}`}>
                    {item.icon}
                  </span>
                  <span className={`text-xs flex-1 ${isActive ? 'font-bold' : 'font-semibold'}`}>
                    {item.label}
                  </span>
                  {item.badge != null && (
                    <span className="text-caption bg-teal-500 text-white rounded-full px-1.5 py-0.5 font-bold">
                      {item.badge}
                    </span>
                  )}
                  {hasChildren && (
                    <span className={`material-symbols-outlined text-body-lg transition-transform duration-150 ${isExpanded ? 'rotate-180' : ''}`}>
                      expand_more
                    </span>
                  )}
                </>
              )

              return (
                <div key={itemIndex}>
                  {useButton ? (
                    <button
                      type="button"
                      data-active={isActive || undefined}
                      disabled={isDisabled}
                      onClick={handleClick}
                      className={itemClass}
                    >
                      {navItemContent}
                    </button>
                  ) : (
                    <a
                      data-active={isActive || undefined}
                      href={hasChildren ? undefined : (item.href ?? '#')}
                      onClick={hasChildren ? (e) => { e.preventDefault(); toggleExpanded(key) } : undefined}
                      className={itemClass}
                    >
                      {navItemContent}
                    </a>
                  )}
                  {hasChildren && isExpanded && (
                    <div className="ml-4 mb-0.5">
                      {item.children!.map((child, childIndex) => {
                        const isChildActive = child.active ?? (activePath ? activePath === child.href : false)
                        return (
                          <a
                            key={childIndex}
                            data-active={isChildActive || undefined}
                            href={child.href ?? '#'}
                            className={`relative z-10 flex items-center gap-2 px-3 py-1.5 rounded-[10px] mb-0.5 transition-colors ${
                              isChildActive
                                ? 'text-teal-600'
                                : 'text-slate-400 hover:text-slate-700 hover:bg-slate-100'
                            }`}
                          >
                            <span className={`material-symbols-outlined text-body-lg ${isChildActive ? 'text-teal-600' : ''}`}>
                              {child.icon}
                            </span>
                            <span className={`text-caption flex-1 ${isChildActive ? 'font-bold' : 'font-semibold'}`}>
                              {child.label}
                            </span>
                            {child.badge != null && (
                              <span className="text-caption bg-teal-500 text-white rounded-full px-1.5 py-0.5 font-bold">
                                {child.badge}
                              </span>
                            )}
                          </a>
                        )
                      })}
                    </div>
                  )}
                </div>
              )
            })}
          </div>
        ))}
      </nav>

      {footer ?? (showUser && (
        <div className="px-2 border-t border-slate-100 pt-3">
          <div className="flex items-center gap-2.5 px-3 py-2">
            <div className="w-7 h-7 rounded-lg bg-slate-200 flex items-center justify-center text-caption font-bold text-slate-500">
              사
            </div>
            <div>
              <div className="text-caption font-bold text-slate-900">사용자</div>
              <div className="text-caption text-slate-400">팀</div>
            </div>
          </div>
        </div>
      ))}
    </aside>
  )
}
