'use client'

import React, { useState, useMemo, useRef, useCallback } from 'react'
import {
  ChevronRight,
  ChevronDown,
  Folder,
  FolderOpen,
  Check,
  Search,
} from 'lucide-react'
import { Notebook } from '@/lib/types'
import { motion, AnimatePresence } from 'motion/react'
import { createPortal } from 'react-dom'

interface HierarchicalNotebookSelectorProps {
  notebooks: { id: string; name: string; icon?: string | null; parentId?: string | null; trashedAt?: Date | string | null }[]
  selectedId: string | null
  onSelect: (id: string) => void
  className?: string
  placeholder?: string
  dropUp?: boolean
  size?: 'default' | 'sm'
}

export function HierarchicalNotebookSelector({
  notebooks,
  selectedId,
  onSelect,
  className = '',
  placeholder = 'Select a notebook...',
  dropUp = false,
  size = 'default',
}: HierarchicalNotebookSelectorProps) {
  const [isOpen, setIsOpen] = useState(false)
  const [searchQuery, setSearchQuery] = useState('')
  const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
  const triggerRef = useRef<HTMLDivElement>(null)

  const getDropdownStyle = useCallback((): React.CSSProperties => {
    if (!triggerRef.current) return { position: 'fixed', top: 0, left: 0, width: 280, zIndex: 9999 }
    const rect = triggerRef.current.getBoundingClientRect()
    if (dropUp) {
      return {
        position: 'fixed',
        bottom: window.innerHeight - rect.top + 8,
        left: rect.left,
        width: Math.max(rect.width, 280),
        zIndex: 9999,
      }
    }
    return {
      position: 'fixed',
      top: rect.bottom + 8,
      left: rect.left,
      width: Math.max(rect.width, 280),
      zIndex: 9999,
    }
  }, [dropUp])

  const selectedNotebook = notebooks.find(nb => nb.id === selectedId)

  const path = useMemo(() => {
    if (!selectedNotebook) return []
    const trail: typeof notebooks = []
    let current: typeof notebooks[0] | undefined = selectedNotebook
    while (current) {
      trail.unshift(current)
      if (!current.parentId) break
      const parent = notebooks.find(nb => nb.id === current!.parentId)
      if (!parent) break
      current = parent
    }
    return trail
  }, [selectedNotebook, notebooks])

  const toggleExpand = (e: React.MouseEvent, id: string) => {
    e.stopPropagation()
    const next = new Set(expandedIds)
    if (next.has(id)) next.delete(id)
    else next.add(id)
    setExpandedIds(next)
  }

  const renderTree = (parentId: string | null | undefined, level = 0): React.ReactNode => {
    const children = notebooks.filter(
      nb => (nb.parentId ?? null) === (parentId ?? null)
    )
    if (children.length === 0) return null

    return (
      <div className={level > 0 ? 'ml-4 border-l border-border/40 pl-2' : ''}>
        {children.map(notebook => {
          const isExpanded = expandedIds.has(notebook.id) || searchQuery.length > 0
          const hasChildren = notebooks.some(nb => nb.parentId === notebook.id)
          const isSelected = selectedId === notebook.id

          if (searchQuery && !notebook.name.toLowerCase().includes(searchQuery.toLowerCase())) {
            const hasMatchingChild = (id: string): boolean => {
              const kids = notebooks.filter(nb => nb.parentId === id)
              return kids.some(nb => nb.name.toLowerCase().includes(searchQuery.toLowerCase()) || hasMatchingChild(nb.id))
            }
            if (!hasMatchingChild(notebook.id)) return null
          }

          return (
            <div key={notebook.id} className="select-none">
              <div
                onClick={() => {
                  onSelect(notebook.id)
                  if (!searchQuery) setIsOpen(false)
                }}
                className={`flex items-center gap-2.5 px-2 py-1.5 rounded-lg cursor-pointer transition-all group
                  ${isSelected ? 'bg-blueprint/10 text-blueprint font-bold dark:bg-blueprint/10' : 'hover:bg-muted dark:hover:bg-white/5 text-ink'}`}
              >
                <div className="w-4 flex items-center justify-center">
                  {hasChildren ? (
                    <button
                      onClick={(e) => toggleExpand(e, notebook.id)}
                      className="p-1 hover:bg-black/5 dark:hover:bg-white/5 rounded transition-colors"
                    >
                      {isExpanded ? <ChevronDown size={12} /> : <ChevronRight size={12} />}
                    </button>
                  ) : null}
                </div>

                <div className={`p-1 rounded ${isSelected ? 'bg-blueprint/20 dark:bg-blueprint/20' : 'bg-muted/50 dark:bg-white/5 group-hover:bg-white/40'}`}>
                  {isExpanded && hasChildren ? <FolderOpen size={13} /> : <Folder size={13} />}
                </div>

                <span className="text-[13px] truncate flex-1">{notebook.name}</span>

                {isSelected && <Check size={14} className="opacity-60 shrink-0" />}
              </div>

              <AnimatePresence>
                {isExpanded && (
                  <motion.div
                    initial={{ height: 0, opacity: 0 }}
                    animate={{ height: 'auto', opacity: 1 }}
                    exit={{ height: 0, opacity: 0 }}
                    className="overflow-hidden"
                  >
                    {renderTree(notebook.id, level + 1)}
                  </motion.div>
                )}
              </AnimatePresence>
            </div>
          )
        })}
      </div>
    )
  }

  return (
    <div className={`relative ${className}`}>
      <div
        ref={triggerRef}
        onClick={() => setIsOpen(prev => !prev)}
        className={`w-full bg-card dark:bg-white/5 border border-border/80 rounded-xl outline-none focus:ring-4 ring-blueprint/5 focus:border-blueprint/40 transition-all cursor-pointer text-ink flex items-center gap-3 ${size === 'sm' ? 'px-3 py-2 text-xs' : 'px-4 py-3 text-sm'}`}
      >
        <Folder size={size === 'sm' ? 14 : 16} className="text-blueprint/60 shrink-0" />
        <div className="flex-1 flex items-center gap-1 min-w-0">
          {path.length > 0 ? (
            <div className="flex items-center gap-1.5 truncate">
              {path.map((item, i) => (
                <React.Fragment key={item.id}>
                  {i > 0 && <span className="text-concrete/40 text-[10px]">/</span>}
                  <span className={`truncate ${i === path.length - 1 ? 'font-bold text-ink' : 'text-concrete'}`}>
                    {item.name}
                  </span>
                </React.Fragment>
              ))}
            </div>
          ) : (
            <span className="text-concrete italic">{placeholder}</span>
          )}
        </div>
        <ChevronDown size={14} className={`transition-transform duration-300 text-concrete shrink-0 ${isOpen ? 'rotate-180' : ''}`} />
      </div>

      {isOpen && typeof window !== 'undefined' && createPortal(
        <>
          <div className="fixed inset-0 z-[9998]" onClick={() => setIsOpen(false)} />
          <AnimatePresence>
            <motion.div
              key="notebook-dropdown"
              initial={{ opacity: 0, y: dropUp ? -8 : 8, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              exit={{ opacity: 0, y: dropUp ? -8 : 8, scale: 0.98 }}
              transition={{ duration: 0.15 }}
              style={getDropdownStyle()}
              className="bg-card border border-border shadow-2xl rounded-2xl overflow-hidden flex flex-col"
            >
              <div className="p-3 border-b border-border/40 bg-card/50 dark:bg-white/5">
                <div className="relative">
                  <Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-concrete" />
                  <input
                    autoFocus
                    type="text"
                    value={searchQuery}
                    onChange={(e) => setSearchQuery(e.target.value)}
                    placeholder={placeholder}
                    className="w-full bg-card border border-border rounded-lg pl-9 pr-4 py-2 text-xs outline-none focus:border-blueprint transition-colors"
                  />
                </div>
              </div>

              <div className="max-h-72 overflow-y-auto custom-scrollbar p-2">
                {renderTree(null)}
              </div>

              <div className="p-2 border-t border-border/40 bg-card/30 dark:bg-white/5 flex justify-between items-center px-4">
                <span className="text-[9px] font-bold text-muted-foreground uppercase tracking-widest">
                  {notebooks.length} notebooks
                </span>
                <button
                  onClick={() => setIsOpen(false)}
                  className="text-[10px] font-bold text-blueprint hover:underline"
                >
                  Close
                </button>
              </div>
            </motion.div>
          </AnimatePresence>
        </>,
        document.body
      )}
    </div>
  )
}
