import { useCallback, useEffect, useRef, useState, type PointerEvent as ReactPointerEvent } from 'react'
import { Link, useLocation } from 'react-router-dom'
import type { LucideIcon } from 'lucide-react'
import {
  LayoutGrid, Clock, AlertTriangle, GitBranch, Code2, Wand2,
  ListChecks, Download, BarChart3,
  Settings, Pin, PinOff,
  History, FileText, Network,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
import { sidebarApi } from '@/api'
import type { SidebarStatsResponse } from '@/api/sidebar'
import { prefetchForRoute } from '@/lib/routePrefetch'

/* ── Types ──────────────────────────────────────────── */

interface NavSubItem {
  href: string
  label: string
  count?: number
}

interface NavEntry {
  href: string
  icon: LucideIcon
  label: string
  shortLabel: string
  badge?: number
  matchPaths?: string[]
  children?: NavSubItem[]
}

interface NavSection {
  title: string
  items: NavEntry[]
}

/* ── Sidebar component ──────────────────────────────── */

export function Sidebar() {
  const location = useLocation()
  const sidebarPinned = useUserPreferencesStore(s => s.sidebarPinned)
  const toggleSidebarPinned = useUserPreferencesStore(s => s.toggleSidebarPinned)

  const [stats, setStats] = useState<SidebarStatsResponse | null>(null)
  // Phase 6: pending-drafts badge on the Scripts nav. Fetched independently
  // of the main stats endpoint so backend changes aren't coupled — worst
  // case the badge doesn't show, rest of the sidebar still renders.
  const [pendingDraftCount, setPendingDraftCount] = useState<number>(0)
  const [flyoutIndex, setFlyoutIndex] = useState<string | null>(null)
  const flyoutTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
  const sidebarRef = useRef<HTMLElement>(null)
  const statsRequestId = useRef(0)

  /* ── Stats fetching ───────────────────────────────── */

  const refreshStats = useCallback(() => {
    const requestId = ++statsRequestId.current
    sidebarApi.getStats()
      .then(data => { if (requestId === statsRequestId.current) setStats(data) })
      .catch(() => {})
    // Phase 6: pending draft templates — soft-fail, optional import keeps
    // the sidebar robust if the endpoint is momentarily unavailable.
    import('@/api/draftTemplates').then(({ draftTemplatesApi }) => {
      draftTemplatesApi.list(true)
        .then(drafts => setPendingDraftCount(drafts.length))
        .catch(() => {})
    }).catch(() => {})
  }, [])

  useEffect(() => { refreshStats() }, [location.pathname, refreshStats])

  useEffect(() => {
    window.addEventListener('session-changed', refreshStats)
    return () => window.removeEventListener('session-changed', refreshStats)
  }, [refreshStats])

  /* ── Navigation data ──────────────────────────────── */

  /* ── Grouped nav: 5 top-level icons (Sentry-style) ── */

  const railGroups: NavEntry[] = [
    {
      href: '/', icon: LayoutGrid, label: 'Home', shortLabel: 'Home',
      matchPaths: ['/'],
    },
    {
      href: '/sessions', icon: History, label: 'History', shortLabel: 'History',
      badge: stats?.active_count || undefined,
      matchPaths: ['/sessions', '/escalations', '/pilot'],
      children: [
        { href: '/sessions', label: 'Session History', count: stats?.active_count || undefined },
        { href: '/escalations', label: 'Escalations', count: stats?.escalation_count || undefined },
      ],
    },
    {
      href: '/trees', icon: GitBranch, label: 'Flows', shortLabel: 'Flows',
      badge: stats?.tree_counts.total || undefined,
      matchPaths: ['/trees', '/flows', '/my-trees', '/step-library', '/review-queue', '/network-diagrams'],
      children: [
        { href: '/trees', label: 'Flow Library', count: stats?.tree_counts.total || undefined },
        { href: '/trees?type=procedural', label: 'Projects', count: stats?.tree_counts.procedural || undefined },
        { href: '/network-diagrams', label: 'Network Maps' },
        { href: '/step-library', label: 'Solutions Library' },
        { href: '/review-queue', label: 'Review Queue' },
      ],
    },
    {
      href: '/scripts', icon: FileText, label: 'Scripts', shortLabel: 'Scripts',
      badge: pendingDraftCount || undefined,
      matchPaths: ['/scripts', '/script-builder'],
      children: [
        { href: '/scripts', label: 'Script Library', count: pendingDraftCount || undefined },
        { href: '/script-builder', label: 'Script Builder' },
      ],
    },
    {
      href: '/analytics', icon: BarChart3, label: 'Insights', shortLabel: 'Data',
      matchPaths: ['/analytics', '/shares'],
      children: [
        { href: '/analytics', label: 'Analytics' },
        { href: '/shares', label: 'Exports' },
      ],
    },
  ]

  /* Pinned mode still uses the detailed section layout */
  const sections: NavSection[] = [
    {
      title: 'RESOLVE',
      items: [
        { href: '/', icon: LayoutGrid, label: 'Dashboard', shortLabel: 'Dash' },
        { href: '/sessions', icon: Clock, label: 'Session History', shortLabel: 'History', badge: stats?.active_count || undefined, matchPaths: ['/sessions'] },
        { href: '/escalations', icon: AlertTriangle, label: 'Escalations', shortLabel: 'Escal', badge: stats?.escalation_count || undefined },
      ],
    },
    {
      title: 'KNOWLEDGE',
      items: [
        {
          href: '/trees', icon: GitBranch, label: 'Flow Library', shortLabel: 'Flows',
          badge: stats?.tree_counts.total || undefined,
          matchPaths: ['/trees', '/flows', '/my-trees'],
          children: [
            { href: '/trees', label: 'Flow Library' },
            { href: '/trees?type=procedural', label: 'Projects', count: stats?.tree_counts.procedural || undefined },
          ],
        },
        { href: '/network-diagrams', icon: Network, label: 'Network Maps', shortLabel: 'NetMap', matchPaths: ['/network-diagrams'] },
        { href: '/scripts', icon: Code2, label: 'Scripts', shortLabel: 'Scripts' },
        { href: '/script-builder', icon: Wand2, label: 'Script Builder', shortLabel: 'Builder' },
        { href: '/review-queue', icon: ListChecks, label: 'Review Queue', shortLabel: 'Review' },
      ],
    },
    {
      title: 'INSIGHTS',
      items: [
        { href: '/analytics', icon: BarChart3, label: 'Analytics', shortLabel: 'Stats' },
        { href: '/shares', icon: Download, label: 'Exports', shortLabel: 'Export' },
      ],
    },
  ]

  const footerItems: NavEntry[] = [
    { href: '/account', icon: Settings, label: 'Account', shortLabel: 'Acct' },
  ]

  /* ── Active detection ─────────────────────────────── */

  const isActive = (item: NavEntry) => {
    if (item.matchPaths) return item.matchPaths.some(p =>
      p === '/' ? location.pathname === '/' : location.pathname.startsWith(p)
    )
    if (item.href === '/') return location.pathname === '/'
    return location.pathname.startsWith(item.href)
  }

  const isChildActive = (child: NavSubItem) => {
    const fullPath = location.pathname + location.search
    return fullPath === child.href || fullPath.startsWith(child.href + '&')
  }

  /* ── Flyout management ────────────────────────────── */

  const openFlyout = (key: string) => {
    if (flyoutTimeout.current) clearTimeout(flyoutTimeout.current)
    setFlyoutIndex(key)
  }

  const closeFlyout = () => {
    flyoutTimeout.current = setTimeout(() => setFlyoutIndex(null), 400)
  }

  const keepFlyout = () => {
    if (flyoutTimeout.current) clearTimeout(flyoutTimeout.current)
  }

  /* ── Drawer resize ───────────────────────────────── */

  const [drawerWidth, setDrawerWidth] = useState(240)
  const isResizing = useRef(false)

  const handleResizeStart = (e: ReactPointerEvent) => {
    e.preventDefault()
    isResizing.current = true
    const startX = e.clientX
    const startWidth = drawerWidth

    const onMove = (ev: globalThis.PointerEvent) => {
      if (!isResizing.current) return
      const newWidth = Math.max(180, Math.min(400, startWidth + (ev.clientX - startX)))
      setDrawerWidth(newWidth)
    }

    const onUp = () => {
      isResizing.current = false
      document.removeEventListener('pointermove', onMove)
      document.removeEventListener('pointerup', onUp)
    }

    document.addEventListener('pointermove', onMove)
    document.addEventListener('pointerup', onUp)
  }

  /* Close flyout on Escape */
  useEffect(() => {
    const handleKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setFlyoutIndex(null)
    }
    document.addEventListener('keydown', handleKey)
    return () => document.removeEventListener('keydown', handleKey)
  }, [])

  /* ── Wheel forwarding (when sidebar can't scroll) ── */

  const handleWheel = (e: React.WheelEvent<HTMLElement>) => {
    const el = e.currentTarget
    const canScroll = el.scrollHeight > el.clientHeight
    const atTop = el.scrollTop <= 0
    const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1
    if (!canScroll || (e.deltaY < 0 && atTop) || (e.deltaY > 0 && atBottom)) {
      const main = document.querySelector('.main-content') as HTMLElement | null
      if (main) { main.scrollTop += e.deltaY; e.preventDefault() }
    }
  }

  /* ── Render helpers ───────────────────────────────── */

  const renderRailItem = (item: NavEntry, key: string) => {
    const active = isActive(item)
    const Icon = item.icon
    const hasChildren = item.children && item.children.length > 0

    return (
      <div
        key={key}
        className="relative w-full"
        onMouseEnter={() => hasChildren && !sidebarPinned ? openFlyout(key) : undefined}
      >
        <Link
          to={item.href}
          onMouseEnter={() => prefetchForRoute(item.href)}
          onFocus={() => hasChildren && !sidebarPinned ? openFlyout(key) : undefined}
          className={cn(
            'group relative flex flex-col items-center justify-center rounded-lg px-2 py-3 transition-all duration-150',
            active
              ? 'bg-accent-dim text-accent-text'
              : 'text-text-rail-label hover:text-foreground'
          )}
          title={item.label}
        >
          <span className="relative">
            <Icon size={24} strokeWidth={1.6} className={active ? 'opacity-100' : 'opacity-60 group-hover:opacity-85'} />
            {item.badge !== undefined && item.badge > 0 && (
              <span className="absolute -right-2 -top-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-primary px-1 text-[0.5rem] font-bold text-background">
                {item.badge > 99 ? '99+' : item.badge}
              </span>
            )}
          </span>
          <span className="mt-1.5 text-[0.625rem] font-sans font-medium leading-tight truncate max-w-[64px]">
            {item.shortLabel}
          </span>
        </Link>

        {/* Flyout rendered as drawer below */}
      </div>
    )
  }

  const renderPinnedItem = (item: NavEntry, key: string) => {
    const active = isActive(item)
    const Icon = item.icon
    const fullPath = location.pathname + location.search
    const activeChild = item.children?.find(c => fullPath === c.href || fullPath.startsWith(c.href + '&'))
    const isParentDimmed = !!activeChild && active

    return (
      <div key={key} className="group/nav">
        <Link
          to={item.href}
          onMouseEnter={() => prefetchForRoute(item.href)}
          className={cn(
            'group relative flex items-center gap-3 rounded-lg px-3 py-2 text-[0.8125rem] font-medium transition-all duration-150',
            active
              ? isParentDimmed
                ? 'bg-[rgba(96,165,250,0.05)] text-foreground/70'
                : 'bg-accent-dim text-foreground'
              : 'text-muted-foreground hover:bg-input hover:text-foreground'
          )}
        >
          {active && !isParentDimmed && (
            <div
              className="absolute left-0 top-1/2 h-6 w-[3px] -translate-y-1/2"
              style={{ background: 'var(--color-accent)', borderRadius: '0 3px 3px 0' }}
            />
          )}
          <Icon size={18} className={cn('shrink-0', active ? 'opacity-100' : 'opacity-70')} />
          <span className="truncate">{item.label}</span>
          {item.badge !== undefined && item.badge > 0 && (
            <span className="ml-auto shrink-0 rounded-full px-2 text-[0.6875rem] font-mono text-text-muted"
              style={{ background: 'var(--color-bg-card)', border: '1px solid var(--color-border-default)' }}>
              {item.badge}
            </span>
          )}
        </Link>

        {/* Sub-items for pinned mode */}
        {item.children && item.children.length > 0 && (
          <div className={cn(
            'mt-0.5 space-y-0.5 overflow-hidden transition-all duration-200',
            active || activeChild
              ? 'max-h-40 opacity-100'
              : 'max-h-0 opacity-0 group-hover/nav:max-h-40 group-hover/nav:opacity-100'
          )}>
            {item.children.map(child => {
              const childActive = isChildActive(child)
              return (
                <Link
                  key={child.href}
                  to={child.href}
                  className={cn(
                    'flex items-center gap-2 rounded-lg pl-9 pr-3 py-1.5 text-[0.8125rem] font-medium transition-colors',
                    childActive
                      ? 'bg-accent-dim text-foreground'
                      : 'text-muted-foreground hover:bg-input hover:text-foreground'
                  )}
                >
                  <span className="truncate">{child.label}</span>
                  {child.count !== undefined && (
                    <span className="ml-auto shrink-0 rounded-full px-2 text-[0.6875rem] font-mono text-text-muted"
                      style={{ background: 'var(--color-bg-card)', border: '1px solid var(--color-border-default)' }}>
                      {child.count}
                    </span>
                  )}
                </Link>
              )
            })}
          </div>
        )}
      </div>
    )
  }

  /* ── Find active flyout group for drawer ── */

  const activeFlyoutGroup = flyoutIndex && !sidebarPinned
    ? railGroups.find((_, i) => `rail-${i}` === flyoutIndex) ||
      footerItems.find((_, i) => `footer-${i}` === flyoutIndex)
    : null

  /* ── Main render ──────────────────────────────────── */

  if (sidebarPinned) {
    return (
      <nav
        ref={sidebarRef}
        className="sidebar flex flex-col h-full"
        style={{ background: 'var(--color-bg-sidebar)', borderRight: '1px solid var(--color-border-default)' }}
        onWheel={handleWheel}
      >
        {/* Pinned sidebar content */}
        <div className="px-3 py-2 space-y-0.5">
          {sections.map((section, si) => (
            <div key={section.title}>
              {si > 0 && (
                <div className="font-mono text-[0.5625rem] uppercase tracking-[0.12em] text-text-muted px-3 pt-3 pb-1">
                  {section.title}
                </div>
              )}
              {section.items.map((item, ii) => renderPinnedItem(item, `${si}-${ii}`))}
            </div>
          ))}
        </div>

        <div className="flex-1" />

        {/* Footer */}
        <div className="px-3 pt-2 pb-4 space-y-0.5" style={{ borderTop: '1px solid var(--color-border-default)' }}>
          {footerItems.map((item, i) => renderPinnedItem(item, `footer-${i}`))}
          <button
            type="button"
            onClick={toggleSidebarPinned}
            className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-[0.8125rem] font-medium text-muted-foreground hover:bg-input hover:text-foreground transition-colors"
            title="Unpin sidebar"
          >
            <PinOff size={18} className="shrink-0" />
            <span>Unpin</span>
          </button>
        </div>
      </nav>
    )
  }

  /* Icon Rail (default) — 5 grouped icons, Sentry-style */
  return (
    <div
      className="flex h-full"
      onMouseLeave={closeFlyout}
    >
      {/* Rail */}
      <nav
        ref={sidebarRef}
        className="sidebar flex flex-col items-center h-full shrink-0"
        style={{ background: 'var(--color-bg-sidebar)', borderRight: '1px solid var(--color-border-default)', width: '72px' }}
        onWheel={handleWheel}
      >
        {/* Nav items */}
        <div className="flex flex-col items-center w-full px-1 space-y-1.5">
          {railGroups.map((item, i) => renderRailItem(item, `rail-${i}`))}
        </div>

        <div className="flex-1" />

        {/* Footer: Account + Pin */}
        <div className="flex flex-col items-center w-full px-1 pb-5 pt-3 space-y-1.5" style={{ borderTop: '1px solid var(--color-border-default)' }}>
          {footerItems.map((item, i) => renderRailItem(item, `footer-${i}`))}
          <button
            type="button"
            onClick={toggleSidebarPinned}
            className="flex flex-col items-center justify-center rounded-lg px-2 py-3 text-text-rail-label hover:text-muted-foreground transition-colors"
            title="Pin sidebar"
          >
            <Pin size={22} strokeWidth={1.6} className="opacity-60 hover:opacity-85" />
            <span className="mt-1.5 text-[0.625rem] font-sans font-medium leading-tight">Pin</span>
          </button>
        </div>
      </nav>

      {/* Drawer panel — fixed position, full height, resizable, overlays main content */}
      {activeFlyoutGroup && activeFlyoutGroup.children && (
        <div
          className="fixed bottom-0 z-50 flex"
          style={{ top: 'var(--topbar-h)', left: '72px' }}
          onMouseEnter={keepFlyout}
          onMouseLeave={closeFlyout}
        >
          <div
            className="flex flex-col h-full overflow-y-auto py-4 px-2"
            style={{
              width: drawerWidth,
              background: 'var(--color-bg-sidebar)',
              borderRight: '1px solid var(--color-border-default)',
              boxShadow: '4px 0 12px rgba(0,0,0,0.2)',
            }}
          >
            {/* Drawer header */}
            <div className="px-3 mb-3">
              <h3 className="text-[0.6875rem] font-mono uppercase tracking-[0.12em] text-[#fbbf24]">
                {activeFlyoutGroup.label}
              </h3>
            </div>

            {/* Drawer items */}
            <div className="space-y-0.5 px-1">
              {activeFlyoutGroup.children.map(child => (
                <Link
                  key={child.href}
                  to={child.href}
                  className={cn(
                    'flex items-center justify-between rounded-md px-3 py-2 text-[0.8125rem] transition-colors',
                    isChildActive(child)
                      ? 'bg-accent-dim text-accent-text'
                      : 'text-muted-foreground hover:bg-input hover:text-foreground'
                  )}
                >
                  <span>{child.label}</span>
                  {child.count !== undefined && (
                    <span className="text-[0.6875rem] font-mono text-text-muted">{child.count}</span>
                  )}
                </Link>
              ))}
            </div>
          </div>

          {/* Resize handle */}
          <div
            className="w-1 cursor-col-resize hover:bg-primary/20 active:bg-primary/30 transition-colors shrink-0"
            onPointerDown={handleResizeStart}
            title="Drag to resize"
          />
        </div>
      )}
    </div>
  )
}
