import { type ReactNode, Children, isValidElement } from 'react'
import {
  Search,
  X,
  ChevronsLeft,
  ChevronsRight,
} from 'lucide-react'
import styles from './Sidebar.module.css'
import { SidebarContext, useSidebarContext } from './SidebarContext'

// ── Sub-component props ─────────────────────────────────────────────────────

interface SidebarHeaderProps {
  logo: ReactNode
  title: string
  version?: string
  onClick?: () => void
  className?: string
}

interface SidebarSectionProps {
  icon: ReactNode
  label: string
  open: boolean
  onToggle: () => void
  active?: boolean
  children: ReactNode
  className?: string
}

interface SidebarFooterProps {
  children: ReactNode
  className?: string
}

interface SidebarFooterLinkProps {
  icon: ReactNode
  label: string
  active?: boolean
  onClick?: () => void
  className?: string
}

interface SidebarRootProps {
  collapsed?: boolean
  onCollapseToggle?: () => void
  searchValue?: string
  onSearchChange?: (query: string) => void
  children: ReactNode
  className?: string
}

// ── Sub-components ──────────────────────────────────────────────────────────

function SidebarHeader({ logo, title, version, onClick, className }: SidebarHeaderProps) {
  const { collapsed } = useSidebarContext()

  return (
    <div
      className={`${styles.logo} ${className ?? ''}`}
      onClick={onClick}
      style={onClick ? { cursor: 'pointer' } : undefined}
      role={onClick ? 'button' : undefined}
      tabIndex={onClick ? 0 : undefined}
      onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') onClick() } : undefined}
    >
      {logo}
      {!collapsed && (
        <div>
          <span className={styles.brand}>{title}</span>
          {version && <span className={styles.version}>{version}</span>}
        </div>
      )}
    </div>
  )
}

function SidebarSection({
  icon,
  label,
  open,
  onToggle,
  active,
  children,
  className,
}: SidebarSectionProps) {
  const { collapsed, onCollapseToggle } = useSidebarContext()

  // In icon-rail (collapsed) mode, render a centered icon with tooltip
  if (collapsed) {
    return (
      <div
        className={`${styles.sectionRailItem} ${active ? styles.sectionRailItemActive : ''} ${className ?? ''}`}
        title={label}
        onClick={() => {
          // Expand sidebar and open the section
          onCollapseToggle?.()
          onToggle()
        }}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            onCollapseToggle?.()
            onToggle()
          }
        }}
      >
        <span className={styles.sectionIcon}>{icon}</span>
      </div>
    )
  }

  return (
    <div className={`${styles.treeSection} ${active ? styles.treeSectionActive : ''} ${className ?? ''}`}>
      <div
        className={styles.treeSectionToggle}
        onClick={onToggle}
        role="button"
        tabIndex={0}
        aria-expanded={open}
        aria-label={open ? `Collapse ${label}` : `Expand ${label}`}
        onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onToggle() } }}
      >
        {icon && <span className={styles.sectionIcon}>{icon}</span>}
        <span className={styles.treeSectionLabel}>{label}</span>
      </div>
      {open && children}
    </div>
  )
}

function SidebarFooter({ children, className }: SidebarFooterProps) {
  return (
    <div className={`${styles.bottom} ${className ?? ''}`}>
      {children}
    </div>
  )
}

function SidebarFooterLink({ icon, label, active, onClick, className }: SidebarFooterLinkProps) {
  const { collapsed } = useSidebarContext()

  return (
    <div
      className={[
        styles.bottomItem,
        active ? styles.bottomItemActive : '',
        className ?? '',
      ].filter(Boolean).join(' ')}
      onClick={onClick}
      role="button"
      tabIndex={0}
      title={collapsed ? label : undefined}
      onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') onClick() } : undefined}
    >
      <span className={styles.bottomIcon}>{icon}</span>
      {!collapsed && (
        <div className={styles.itemInfo}>
          <div className={styles.itemName}>{label}</div>
        </div>
      )}
    </div>
  )
}

// ── Root component ──────────────────────────────────────────────────────────

function SidebarRoot({
  collapsed = false,
  onCollapseToggle,
  searchValue,
  onSearchChange,
  children,
  className,
}: SidebarRootProps) {
  return (
    <SidebarContext.Provider value={{ collapsed, onCollapseToggle }}>
      <aside
        className={[
          styles.sidebar,
          collapsed ? styles.sidebarCollapsed : '',
          className ?? '',
        ].filter(Boolean).join(' ')}
      >
        {/* Collapse toggle */}
        {onCollapseToggle && (
          <button
            className={styles.collapseToggle}
            onClick={onCollapseToggle}
            aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
          >
            {collapsed ? <ChevronsRight size={14} /> : <ChevronsLeft size={14} />}
          </button>
        )}

        {/* Render Header first, then search, then remaining children */}
        {(() => {
          const childArray = Children.toArray(children)
          const headerIdx = childArray.findIndex(
            (child) => isValidElement(child) && child.type === SidebarHeader,
          )
          const header = headerIdx >= 0 ? childArray[headerIdx] : null
          const rest = headerIdx >= 0
            ? [...childArray.slice(0, headerIdx), ...childArray.slice(headerIdx + 1)]
            : childArray

          return (
            <>
              {header}
              {onSearchChange && !collapsed && (
                <div className={styles.searchWrap}>
                  <div className={styles.searchInner}>
                    <span className={styles.searchIcon} aria-hidden="true">
                      <Search size={12} />
                    </span>
                    <input
                      className={styles.searchInput}
                      type="text"
                      placeholder="Filter..."
                      value={searchValue ?? ''}
                      onChange={(e) => onSearchChange(e.target.value)}
                    />
                    {searchValue && (
                      <button
                        type="button"
                        className={styles.searchClear}
                        onClick={() => onSearchChange('')}
                        aria-label="Clear search"
                      >
                        <X size={12} />
                      </button>
                    )}
                  </div>
                </div>
              )}
              {rest}
            </>
          )
        })()}
      </aside>
    </SidebarContext.Provider>
  )
}

// ── Compound export ─────────────────────────────────────────────────────────

export const Sidebar = Object.assign(SidebarRoot, {
  Header: SidebarHeader,
  Section: SidebarSection,
  Footer: SidebarFooter,
  FooterLink: SidebarFooterLink,
})
