import { useState, useEffect, useRef, useCallback, useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import {
  Search, Loader2, ArrowRight, FileText, Clock,
  Sparkles, LayoutDashboard, Tag, Plus, BookOpen, Terminal,
} from 'lucide-react'
import { treesApi } from '@/api/trees'
import { sessionsApi } from '@/api/sessions'
import type { TreeListItem } from '@/types'
import type { Session } from '@/types/session'
import { getTreeNavigatePath } from '@/lib/routing'
import { cn } from '@/lib/utils'
import { detectIntent } from '@/lib/paletteIntent'
import { getRecentFlows } from '@/lib/recentFlows'
import { useAuthStore } from '@/store/authStore'

interface CommandPaletteProps {
  open: boolean
  onClose: () => void
}

type GroupType = 'flowpilot' | 'pages' | 'flows' | 'sessions' | 'tags' | 'quick-actions' | 'recent-flows'

interface PaletteItem {
  id: string
  group: GroupType
  title: string
  subtitle?: string
  path: string
  icon: 'sparkles' | 'tree' | 'session' | 'page' | 'tag' | 'action' | 'recent'
}

interface Group {
  type: GroupType
  label: string
  items: PaletteItem[]
}

const PAGES: PaletteItem[] = [
  { id: 'page-dashboard', group: 'pages', title: 'Dashboard', path: '/', icon: 'page' },
  { id: 'page-flows', group: 'pages', title: 'All Flows', subtitle: 'Browse your flow library', path: '/trees', icon: 'page' },
  { id: 'page-sessions', group: 'pages', title: 'Sessions', subtitle: 'View session history', path: '/sessions', icon: 'page' },
  { id: 'page-assistant', group: 'pages', title: 'AI Assistant', subtitle: 'FlowPilot chat', path: '/assistant', icon: 'page' },
  { id: 'page-scripts', group: 'pages', title: 'Script Generator', subtitle: 'Generate PowerShell scripts', path: '/scripts', icon: 'page' },
  { id: 'page-analytics', group: 'pages', title: 'Analytics', subtitle: 'Team usage & metrics', path: '/analytics', icon: 'page' },
  { id: 'page-settings', group: 'pages', title: 'Settings', subtitle: 'Account & preferences', path: '/account', icon: 'page' },
  { id: 'page-library', group: 'pages', title: 'Step Library', subtitle: 'Reusable steps', path: '/library', icon: 'page' },
]

const ADMIN_PAGES: PaletteItem[] = [
  { id: 'page-admin', group: 'pages', title: 'Admin', subtitle: 'Platform administration', path: '/admin', icon: 'page' },
]

const QUICK_ACTIONS: PaletteItem[] = [
  { id: 'action-new-flow', group: 'quick-actions', title: 'Create New Flow', subtitle: 'Start from scratch or use AI', path: '/trees', icon: 'action' },
  { id: 'action-kb', group: 'quick-actions', title: 'Import from KB', subtitle: 'KB Accelerator', path: '/kb-accelerator', icon: 'action' },
  { id: 'action-scripts', group: 'quick-actions', title: 'Open Script Generator', subtitle: 'Generate automation scripts', path: '/scripts', icon: 'action' },
]

function ItemIcon({ icon, className }: { icon: PaletteItem['icon'], className?: string }) {
  const cls = cn('shrink-0', className)
  switch (icon) {
    case 'sparkles': return <Sparkles size={16} className={cls} />
    case 'tree': return <FileText size={16} className={cls} />
    case 'session': return <Clock size={16} className={cls} />
    case 'page': return <LayoutDashboard size={16} className={cls} />
    case 'tag': return <Tag size={16} className={cls} />
    case 'action': return <Plus size={16} className={cls} />
    case 'recent': return <BookOpen size={16} className={cls} />
    default: return <Terminal size={16} className={cls} />
  }
}

export function CommandPalette({ open, onClose }: CommandPaletteProps) {
  const navigate = useNavigate()
  const user = useAuthStore(s => s.user)
  const inputRef = useRef<HTMLInputElement>(null)
  const [query, setQuery] = useState('')
  const [isSearching, setIsSearching] = useState(false)
  const [selectedIndex, setSelectedIndex] = useState(0)
  const [searchFlows, setSearchFlows] = useState<TreeListItem[]>([])
  const [searchSessions, setSearchSessions] = useState<Session[]>([])
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // Focus input when opened
  useEffect(() => {
    if (open) {
      setQuery('')
      setSearchFlows([])
      setSearchSessions([])
      setSelectedIndex(0)
      setTimeout(() => inputRef.current?.focus(), 50)
    }
  }, [open])

  // Close on Escape
  useEffect(() => {
    if (!open) return
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    document.addEventListener('keydown', handler)
    return () => document.removeEventListener('keydown', handler)
  }, [open, onClose])

  // Debounced search
  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current)
    if (query.trim().length < 2) {
      setSearchFlows([])
      setSearchSessions([])
      setIsSearching(false)
      return
    }
    setIsSearching(true)
    debounceRef.current = setTimeout(async () => {
      try {
        const [flows, sessions] = await Promise.all([
          treesApi.search(query, 6),
          sessionsApi.list({ size: 5 }).catch(() => [] as Session[]),
        ])
        setSearchFlows(flows)
        // Filter sessions by tree name
        const filtered = sessions.filter((s: Session) =>
          s.tree_snapshot?.name?.toLowerCase().includes(query.toLowerCase())
        ).slice(0, 3)
        setSearchSessions(filtered)
      } catch {
        setSearchFlows([])
        setSearchSessions([])
      } finally {
        setIsSearching(false)
      }
    }, 250)
    return () => { if (debounceRef.current) clearTimeout(debounceRef.current) }
  }, [query])

  // Build groups based on intent and search results
  const builtGroups = useMemo((): Group[] => {
    const trimmed = query.trim()
    const intent = detectIntent(trimmed)
    const lower = trimmed.toLowerCase()

    if (intent === 'empty') {
      // Empty state: recent flows + quick actions
      const recentFlows = getRecentFlows(5)
      const recentItems: PaletteItem[] = recentFlows.map(f => ({
        id: `recent-${f.id}`,
        group: 'recent-flows' as GroupType,
        title: f.name,
        subtitle: f.tree_type,
        path: getTreeNavigatePath(f.id, f.tree_type),
        icon: 'recent' as const,
      }))

      const result: Group[] = []
      if (recentItems.length > 0) {
        result.push({ type: 'recent-flows', label: 'Recent Flows', items: recentItems })
      }
      result.push({ type: 'quick-actions', label: 'Quick Actions', items: QUICK_ACTIONS })
      return result
    }

    // Build FlowPilot item
    const flowPilotItem: PaletteItem = {
      id: 'flowpilot-ai',
      group: 'flowpilot',
      title: 'Ask FlowPilot AI',
      subtitle: trimmed,
      path: '/assistant',
      icon: 'sparkles',
    }

    // Filter pages
    const allPages = user?.is_super_admin ? [...PAGES, ...ADMIN_PAGES] : PAGES
    const filteredPages = allPages.filter(p =>
      p.title.toLowerCase().includes(lower) ||
      (p.subtitle?.toLowerCase().includes(lower) ?? false)
    )

    // Build flow items
    const flowItems: PaletteItem[] = searchFlows.map(f => ({
      id: `flow-${f.id}`,
      group: 'flows' as GroupType,
      title: f.name,
      subtitle: f.description || undefined,
      path: getTreeNavigatePath(f.id, f.tree_type),
      icon: 'tree' as const,
    }))

    // Extract unique tags from search results
    const tagSet = new Set<string>()
    for (const f of searchFlows) {
      if (Array.isArray(f.tags)) {
        for (const t of f.tags) {
          if (t.toLowerCase().includes(lower)) tagSet.add(t)
        }
      }
    }
    const tagItems: PaletteItem[] = Array.from(tagSet).slice(0, 4).map(tag => ({
      id: `tag-${tag}`,
      group: 'tags' as GroupType,
      title: tag,
      subtitle: 'Browse flows with this tag',
      path: `/trees?tag=${encodeURIComponent(tag)}`,
      icon: 'tag' as const,
    }))

    // Build session items
    const sessionItems: PaletteItem[] = searchSessions.map(s => ({
      id: `session-${s.id}`,
      group: 'sessions' as GroupType,
      title: s.tree_snapshot?.name || 'Session',
      subtitle: s.completed_at ? 'Completed' : 'In progress',
      path: `/sessions/${s.id}`,
      icon: 'session' as const,
    }))

    const result: Group[] = []

    if (intent === 'question') {
      // FlowPilot prominent at top
      result.push({ type: 'flowpilot', label: 'AI Assistant', items: [flowPilotItem] })
      if (flowItems.length > 0) result.push({ type: 'flows', label: 'Flows', items: flowItems })
      if (sessionItems.length > 0) result.push({ type: 'sessions', label: 'Sessions', items: sessionItems })
      if (tagItems.length > 0) result.push({ type: 'tags', label: 'Tags', items: tagItems })
    } else if (intent === 'page') {
      // Pages first, FlowPilot at bottom
      if (filteredPages.length > 0) result.push({ type: 'pages', label: 'Pages', items: filteredPages })
      if (flowItems.length > 0) result.push({ type: 'flows', label: 'Flows', items: flowItems })
      if (sessionItems.length > 0) result.push({ type: 'sessions', label: 'Sessions', items: sessionItems })
      if (tagItems.length > 0) result.push({ type: 'tags', label: 'Tags', items: tagItems })
      result.push({ type: 'flowpilot', label: 'AI Assistant', items: [flowPilotItem] })
    } else {
      // keyword: FlowPilot at top, flows/sessions/tags below
      result.push({ type: 'flowpilot', label: 'AI Assistant', items: [flowPilotItem] })
      if (flowItems.length > 0) result.push({ type: 'flows', label: 'Flows', items: flowItems })
      if (sessionItems.length > 0) result.push({ type: 'sessions', label: 'Sessions', items: sessionItems })
      if (tagItems.length > 0) result.push({ type: 'tags', label: 'Tags', items: tagItems })
      if (filteredPages.length > 0) result.push({ type: 'pages', label: 'Pages', items: filteredPages })
    }

    return result
  }, [query, searchFlows, searchSessions, user])

  // Flatten all items for keyboard navigation
  const flatItems: PaletteItem[] = builtGroups.flatMap(g => g.items)

  const handleSelect = useCallback((item: PaletteItem) => {
    onClose()
    if (item.group === 'flowpilot') {
      navigate(item.path, { state: { prefill: query.trim() } })
    } else {
      navigate(item.path)
    }
  }, [navigate, onClose, query])

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'ArrowDown') {
      e.preventDefault()
      setSelectedIndex(i => Math.min(i + 1, flatItems.length - 1))
    } else if (e.key === 'ArrowUp') {
      e.preventDefault()
      setSelectedIndex(i => Math.max(i - 1, 0))
    } else if (e.key === 'Enter' && flatItems[selectedIndex]) {
      e.preventDefault()
      handleSelect(flatItems[selectedIndex])
    }
  }

  // Track global flat index for selection highlight
  let globalIdx = 0

  const intent = detectIntent(query.trim())
  const hasQuery = query.trim().length >= 2
  const isEmpty = intent === 'empty'
  const isQuestion = intent === 'question'

  if (!open) return null

  return (
    <div className="fixed inset-0 z-[100] flex items-start justify-center pt-[20vh]">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/60 backdrop-blur-xs animate-fade-in"
        onClick={onClose}
      />

      {/* Palette */}
      <div className="relative w-full max-w-lg rounded-xl border border-border bg-card shadow-2xl animate-scale-in">
        {/* Search input */}
        <div className="flex items-center gap-3 border-b border-border px-4 py-3">
          <Search size={18} className="shrink-0 text-muted-foreground" />
          <input
            ref={inputRef}
            type="text"
            value={query}
            onChange={e => { setQuery(e.target.value); setSelectedIndex(0) }}
            onKeyDown={handleKeyDown}
            placeholder="Search flows, ask a question, navigate…"
            className="flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground outline-hidden"
          />
          <kbd className="rounded border border-border bg-background px-1.5 py-0.5 font-label text-[0.625rem] text-muted-foreground">
            ESC
          </kbd>
        </div>

        {/* Results */}
        <div className="max-h-[28rem] overflow-y-auto">
          {isSearching ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
            </div>
          ) : hasQuery && flatItems.length === 0 ? (
            <div className="px-4 py-8 text-center text-sm text-muted-foreground">
              No results for &ldquo;{query}&rdquo;
            </div>
          ) : builtGroups.length > 0 ? (
            <div className="p-1">
              {builtGroups.map(group => {
                const groupStart = globalIdx
                globalIdx += group.items.length

                return (
                  <div key={group.type}>
                    {/* Section label */}
                    <div className="px-3 pt-2 pb-1">
                      <span className="font-label text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                        {group.label}
                      </span>
                    </div>

                    {group.items.map((item, i) => {
                      const itemGlobalIdx = groupStart + i
                      const isSelected = itemGlobalIdx === selectedIndex
                      const isFlowPilot = item.group === 'flowpilot'

                      if (isFlowPilot) {
                        // Special prominent styling for question intent at top
                        return (
                          <button
                            key={item.id}
                            onClick={() => handleSelect(item)}
                            onMouseEnter={() => setSelectedIndex(itemGlobalIdx)}
                            className={cn(
                              'flex w-full items-center gap-3 rounded-[10px] px-3 py-2.5 text-left transition-colors',
                              'bg-primary/5 border border-primary/10',
                              isQuestion ? 'mb-1' : '',
                              isSelected
                                ? 'bg-primary/10 border-primary/20'
                                : 'hover:bg-primary/10 hover:border-primary/20'
                            )}
                          >
                            <div className={cn(
                              'flex h-7 w-7 shrink-0 items-center justify-center rounded-lg',
                              isQuestion ? 'bg-primary/15' : 'bg-primary/10'
                            )}>
                              <Sparkles size={14} className="text-primary" />
                            </div>
                            <div className="min-w-0 flex-1">
                              <p className={cn(
                                'text-sm font-medium truncate',
                                isQuestion ? 'text-primary' : 'text-foreground'
                              )}>
                                {item.title}
                              </p>
                              {item.subtitle && (
                                <p className="text-[0.6875rem] text-muted-foreground truncate italic">
                                  &ldquo;{item.subtitle}&rdquo;
                                </p>
                              )}
                            </div>
                            {isSelected && (
                              <ArrowRight size={14} className="shrink-0 text-primary opacity-60" />
                            )}
                          </button>
                        )
                      }

                      return (
                        <button
                          key={item.id}
                          onClick={() => handleSelect(item)}
                          onMouseEnter={() => setSelectedIndex(itemGlobalIdx)}
                          className={cn(
                            'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors',
                            isSelected
                              ? 'bg-accent text-foreground'
                              : 'text-muted-foreground hover:bg-accent/50'
                          )}
                        >
                          <ItemIcon
                            icon={item.icon}
                            className={isSelected ? 'opacity-80' : 'opacity-50'}
                          />
                          <div className="min-w-0 flex-1">
                            <p className="text-sm font-medium truncate">{item.title}</p>
                            {item.subtitle && (
                              <p className="text-[0.6875rem] text-muted-foreground truncate">{item.subtitle}</p>
                            )}
                          </div>
                          {isSelected && (
                            <ArrowRight size={14} className="shrink-0 opacity-40" />
                          )}
                        </button>
                      )
                    })}
                  </div>
                )
              })}
            </div>
          ) : (
            <div className="px-4 py-6 text-center text-sm text-muted-foreground">
              {isEmpty
                ? 'Type to search flows, pages, or ask FlowPilot a question'
                : 'Type to search flows and sessions'}
            </div>
          )}
        </div>

        {/* Footer hints */}
        {flatItems.length > 0 && (
          <div className="flex items-center gap-4 border-t border-border px-4 py-2">
            <span className="flex items-center gap-1 text-[0.625rem] text-muted-foreground">
              <kbd className="rounded border border-border bg-background px-1 py-px font-label">↑↓</kbd>
              Navigate
            </span>
            <span className="flex items-center gap-1 text-[0.625rem] text-muted-foreground">
              <kbd className="rounded border border-border bg-background px-1 py-px font-label">↵</kbd>
              Open
            </span>
          </div>
        )}
      </div>
    </div>
  )
}
