import React, { useState, useMemo } from 'react';
import { 
  ChevronRight, 
  ChevronDown, 
  Folder, 
  FolderOpen, 
  Check, 
  Search
} from 'lucide-react';
import { Carnet } from '../types';
import { motion, AnimatePresence } from 'motion/react';

interface HierarchicalCarnetSelectorProps {
  carnets: Carnet[];
  selectedId: string | null;
  onSelect: (id: string) => void;
  className?: string;
  placeholder?: string;
}

export const HierarchicalCarnetSelector: React.FC<HierarchicalCarnetSelectorProps> = ({
  carnets,
  selectedId,
  onSelect,
  className = "",
  placeholder = "Sélectionner un carnet..."
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set(['1', '4'])); // Default expand some

  const selectedCarnet = carnets.find(c => c.id === selectedId);

  // Derive the path for display
  const path = useMemo(() => {
    if (!selectedCarnet) return [];
    const trail: Carnet[] = [];
    let current = selectedCarnet;
    while (current) {
      trail.unshift(current);
      if (!current.parentId) break;
      const parent = carnets.find(c => c.id === current.parentId);
      if (!parent) break;
      current = parent;
    }
    return trail;
  }, [selectedCarnet, carnets]);

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

  const filteredCarnets = useMemo(() => {
    if (!searchQuery) return carnets;
    return carnets.filter(c => c.name.toLowerCase().includes(searchQuery.toLowerCase()));
  }, [carnets, searchQuery]);

  const renderTree = (parentId?: string, level = 0) => {
    const children = carnets.filter(c => c.parentId === parentId);
    if (children.length === 0) return null;

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

          // If searching and this carnet doesn't match AND none of its children match, skip it
          if (searchQuery && !carnet.name.toLowerCase().includes(searchQuery.toLowerCase())) {
            const hasMatchingChild = (id: string): boolean => {
              const childrenOfId = carnets.filter(c => c.parentId === id);
              return childrenOfId.some(c => c.name.toLowerCase().includes(searchQuery.toLowerCase()) || hasMatchingChild(c.id));
            };
            if (!hasMatchingChild(carnet.id)) return null;
          }

          return (
            <div key={carnet.id} className="select-none">
              <div 
                onClick={() => {
                  onSelect(carnet.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' : 'hover:bg-slate-50 dark:hover:bg-white/5 text-ink'}`}
              >
                <div className="w-4 flex items-center justify-center">
                  {hasChildren ? (
                    <button 
                      onClick={(e) => toggleExpand(e, carnet.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' : 'bg-slate-100 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">{carnet.name}</span>
                
                {isSelected && <Check size={14} className="opacity-60" />}
              </div>
              
              <AnimatePresence>
                {isExpanded && (
                  <motion.div
                    initial={{ height: 0, opacity: 0 }}
                    animate={{ height: "auto", opacity: 1 }}
                    exit={{ height: 0, opacity: 0 }}
                    className="overflow-hidden"
                  >
                    {renderTree(carnet.id, level + 1)}
                  </motion.div>
                )}
              </AnimatePresence>
            </div>
          );
        })}
      </div>
    );
  };

  return (
    <div className={`relative ${className}`}>
      <div 
        onClick={() => setIsOpen(!isOpen)}
        className="w-full bg-slate-50 dark:bg-black/20 border border-border/80 rounded-xl px-4 py-4 text-sm outline-none focus:ring-4 ring-blueprint/5 focus:border-blueprint/40 transition-all cursor-pointer text-ink flex items-center gap-3"
      >
        <Folder size={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-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>

      <AnimatePresence>
        {isOpen && (
          <>
            <div 
              className="fixed inset-0 z-[60]" 
              onClick={() => setIsOpen(false)} 
            />
            <motion.div 
              initial={{ opacity: 0, y: 10, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              exit={{ opacity: 0, y: 10, scale: 0.98 }}
              className="absolute z-[70] mt-2 w-full bg-white dark:bg-dark-paper border border-border shadow-2xl rounded-2xl overflow-hidden flex flex-col min-w-[280px]"
            >
              <div className="p-3 border-b border-border/40 bg-slate-50/50">
                <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="Filtrer les carnets..."
                    className="w-full bg-white 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(undefined)}
              </div>
              
              <div className="p-2 border-t border-border/40 bg-slate-50/30 flex justify-between items-center px-4">
                <span className="text-[9px] font-bold text-concrete uppercase tracking-widest">
                  Structure des carnets
                </span>
                <button 
                  onClick={() => setIsOpen(false)}
                  className="text-[10px] font-bold text-blueprint hover:underline"
                >
                  Fermer
                </button>
              </div>
            </motion.div>
          </>
        )}
      </AnimatePresence>
    </div>
  );
};
