import React, { useState, useEffect, useMemo, useRef } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { 
  Search, 
  ChevronLeft, 
  ChevronRight, 
  Plus, 
  Bookmark, 
  Layers, 
  FileText, 
  CheckCircle,
  HelpCircle,
  X,
  CornerDownRight,
  Folder,
  Sliders,
  Sparkles,
  Command,
  Settings
} from 'lucide-react';
import { Note, Carnet } from '../types';

interface SearchModalProps {
  isOpen: boolean;
  onClose: () => void;
  notes: Note[];
  carnets: Carnet[];
  onSelectNote: (noteId: string) => void;
}

interface SearchMatch {
  id: string; // Unique match identifier
  noteId: string;
  noteTitle: string;
  path: string;
  type: 'document' | 'heading' | 'paragraph' | 'list';
  headingLevel?: number;
  text: string;
  matchedText: string;
  lineIndex: number;
}

export const SearchModal: React.FC<SearchModalProps> = ({
  isOpen,
  onClose,
  notes,
  carnets,
  onSelectNote
}) => {
  const [query, setQuery] = useState('');
  const [useRegex, setUseRegex] = useState(false);
  const [caseSensitive, setCaseSensitive] = useState(false);
  const [includeChildDocs, setIncludeChildDocs] = useState(true);
  const [searchInTrash, setSearchInTrash] = useState(false);
  const [savedQueries, setSavedQueries] = useState<string[]>(['block', 'siyuan', 'guide']);
  
  const [selectedIndex, setSelectedIndex] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);
  const listRef = useRef<HTMLDivElement>(null);

  // Focus input on launch
  useEffect(() => {
    if (isOpen) {
      setTimeout(() => inputRef.current?.focus(), 50);
    }
  }, [isOpen]);

  // Handle global keybindings in modal
  useEffect(() => {
    if (!isOpen) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        onClose();
      } else if (e.key === 'ArrowDown') {
        e.preventDefault();
        setSelectedIndex(prev => Math.min(prev + 1, filteredMatches.length - 1));
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        setSelectedIndex(prev => Math.max(prev - 1, 0));
      } else if (e.key === 'Enter') {
        e.preventDefault();
        if (filteredMatches[selectedIndex]) {
          const m = filteredMatches[selectedIndex];
          onSelectNote(m.noteId);
          onClose();
        }
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, selectedIndex]);

  // Helper: reconstruct carnet path
  const getCarnetPath = (carnetId: string): string => {
    const segments: string[] = [];
    let current = carnets.find(c => c.id === carnetId);
    while (current) {
      segments.unshift(current.name);
      current = current.parentId ? carnets.find(c => c.id === current.parentId) : undefined;
    }
    return segments.join('/');
  };

  // Safe term escape for RegExp
  const escapeRegExp = (string: string) => {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  };

  // Perform multi-match search logic across document titles and contents
  const filteredMatches = useMemo(() => {
    if (!query.trim()) return [];

    const matches: SearchMatch[] = [];
    const searchRegex = (() => {
      try {
        const flag = caseSensitive ? '' : 'i';
        const pattern = useRegex ? query : escapeRegExp(query);
        return new RegExp(pattern, flag);
      } catch (e) {
        return null; // Handle partial regex input gracefully
      }
    })();

    if (!searchRegex) return [];

    // Filter notes depending on trash status
    const targetNotes = notes.filter(n => searchInTrash ? n.isDeleted : !n.isDeleted);

    targetNotes.forEach(note => {
      const notePath = getCarnetPath(note.carnetId);
      const fullPath = notePath ? `${notePath}/${note.title}` : note.title;

      // 1. Check Title match
      if (searchRegex.test(note.title)) {
        matches.push({
          id: `${note.id}-title`,
          noteId: note.id,
          noteTitle: note.title,
          path: fullPath,
          type: 'document',
          text: note.title,
          matchedText: note.title,
          lineIndex: -1
        });
      }

      // 2. Parse Content blocks / lines
      if (note.content) {
        const lines = note.content.split('\n');
        lines.forEach((line, index) => {
          const trimmed = line.trim();
          if (!trimmed) return;

          if (searchRegex.test(trimmed)) {
            let type: 'heading' | 'paragraph' | 'list' = 'paragraph';
            let headingLevel = undefined;
            let displayVal = trimmed;

            // Classify content structure elements
            if (trimmed.startsWith('#')) {
              type = 'heading';
              const headingMatch = trimmed.match(/^(#{1,6})\s+(.+)$/);
              if (headingMatch) {
                headingLevel = headingMatch[1].length;
                displayVal = headingMatch[2];
              }
            } else if (/^[-*+]\s+/.test(trimmed) || /^\d+\.\s+/.test(trimmed)) {
              type = 'list';
              displayVal = trimmed.replace(/^[-*+\d.]+\s+/, '');
            }

            matches.push({
              id: `${note.id}-line-${index}`,
              noteId: note.id,
              noteTitle: note.title,
              path: fullPath,
              type,
              headingLevel,
              text: trimmed,
              matchedText: displayVal,
              lineIndex: index
            });
          }
        });
      }
    });

    return matches;
  }, [notes, query, useRegex, caseSensitive, searchInTrash, carnets]);

  // Ensure index remains in bounds when matches array updates
  useEffect(() => {
    setSelectedIndex(0);
  }, [query]);

  // Toggle saving criteria
  const handleSaveCriteria = () => {
    if (query.trim() && !savedQueries.includes(query.trim())) {
      setSavedQueries(prev => [...prev, query.trim()]);
    }
  };

  const handleRemoveCriteria = () => {
    setSavedQueries(prev => prev.filter(q => q !== query.trim()));
  };

  // Count distinct notes involved in match list
  const docMatchesCount = useMemo(() => {
    const uniqueNoteIds = new Set(filteredMatches.map(m => m.noteId));
    return uniqueNoteIds.size;
  }, [filteredMatches]);

  const activeMatch = filteredMatches[selectedIndex];

  // Dynamically load document content with visual query highlights
  const highlightedNotePreviewContent = useMemo(() => {
    if (!activeMatch) return null;
    const currentNote = notes.find(n => n.id === activeMatch.noteId);
    if (!currentNote) return null;

    if (!query.trim()) return currentNote.content;

    try {
      const flag = caseSensitive ? 'g' : 'gi';
      const searchPattern = useRegex ? query : escapeRegExp(query);
      const highlightRegex = new RegExp(`(${searchPattern})`, flag);

      // Return content split by line to let us format block matches neatly
      const lines = (currentNote.content || '').split('\n');
      
      // Let's frame the match around the matched line for contextual proximity
      const targetIndex = activeMatch.lineIndex >= 0 ? activeMatch.lineIndex : 0;
      const startLine = Math.max(0, targetIndex - 3);
      const endLine = Math.min(lines.length - 1, targetIndex + 5);

      return (
        <div className="space-y-1 my-2">
          {startLine > 0 && (
            <div className="text-[10px] text-concrete/40 italic pl-4">...</div>
          )}
          {lines.slice(startLine, endLine + 1).map((line, idx) => {
            const absoluteIdx = startLine + idx;
            const isMatchLine = absoluteIdx === targetIndex;
            const hasMatches = highlightRegex.test(line);

            // Reconstruct highlighted segments
            const segments = line.split(highlightRegex);
            
            return (
              <div 
                key={absoluteIdx} 
                className={`py-1 px-3 rounded-lg text-xs leading-relaxed flex items-start gap-4 transition-colors
                  ${isMatchLine ? 'bg-amber-100/15 border-l-2 border-amber-500 pl-2.5 dark:bg-amber-500/5' : 'opacity-85'}`}
              >
                <span className="font-mono text-[9px] text-concrete/40 text-right w-6 select-none mt-1">
                  {absoluteIdx + 1}
                </span>
                
                <span className="font-sans text-ink dark:text-dark-ink break-all">
                  {hasMatches ? (
                    segments.map((seg, sIdx) => {
                      const matchesPattern = highlightRegex.test(seg);
                      return matchesPattern ? (
                        <mark 
                          key={sIdx} 
                          className="bg-amber-500/30 text-ink dark:text-white dark:bg-amber-400/40 rounded px-0.5 border-b border-amber-600 font-semibold"
                        >
                          {seg}
                        </mark>
                      ) : (
                        seg
                      );
                    })
                  ) : (
                    line
                  )}
                </span>
              </div>
            );
          })}
          {endLine < lines.length - 1 && (
            <div className="text-[10px] text-concrete/40 italic pl-4">...</div>
          )}
        </div>
      );
    } catch (e) {
      return <div className="text-xs text-concrete pr-4">{currentNote.content}</div>;
    }
  }, [activeMatch, notes, query, useRegex, caseSensitive]);

  // Render text segment highlight in results row items
  const renderHighlightedRowText = (text: string) => {
    if (!query.trim()) return text;
    try {
      const flag = caseSensitive ? 'gi' : 'gi';
      const searchPattern = useRegex ? query : escapeRegExp(query);
      const highlightRegex = new RegExp(`(${searchPattern})`, flag);
      const segments = text.split(highlightRegex);

      return (
        <span className="truncate">
          {segments.map((seg, sIdx) => {
            const isMatch = highlightRegex.test(seg);
            return isMatch ? (
              <mark key={sIdx} className="bg-amber-400/35 text-ink dark:text-white dark:bg-amber-500/45 px-0.5 rounded font-black">
                {seg}
              </mark>
            ) : (
              seg
            );
          })}
        </span>
      );
    } catch (e) {
      return text;
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 bg-black/40 dark:bg-black/60 backdrop-blur-xs flex items-center justify-center z-[100] p-4 sm:p-6 select-none font-sans">
      <motion.div 
        initial={{ opacity: 0, scale: 0.98, y: 10 }}
        animate={{ opacity: 1, scale: 1, y: 0 }}
        exit={{ opacity: 0, scale: 0.98, y: 10 }}
        className="w-full max-w-[840px] h-[580px] sm:h-[640px] rounded-2xl bg-white dark:bg-[#121212] border border-border dark:border-zinc-800 shadow-2xl flex flex-col overflow-hidden"
      >
        {/* TOP Advanced Search Bar Row */}
        <div className="p-4 border-b border-border/60 dark:border-zinc-800/80 bg-paper/50 dark:bg-[#161616] flex flex-col gap-3 shrink-0">
          <div className="flex items-center gap-2.5 relative">
            <Search size={18} className="text-concrete absolute left-3 top-1/2 -translate-y-1/2 shrink-0" />
            
            <input 
              ref={inputRef}
              type="text"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Rechercher des documents ou des blocs de texte..."
              className="w-full text-sm pl-10 pr-24 py-2.5 rounded-xl border border-border/70 dark:border-zinc-800/80 bg-white/85 dark:bg-[#1C1C1C] text-ink dark:text-dark-ink placeholder-concrete/50 outline-none focus:border-accent"
            />

            {/* Config Quick Badges */}
            <div className="absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1.5 bg-paper dark:bg-transparent rounded-lg p-0.5">
               <button 
                 onClick={() => setCaseSensitive(!caseSensitive)}
                 className={`px-1.5 py-1 text-[9.5px] font-bold rounded-md hover:bg-black/5 dark:hover:bg-white/5 uppercase select-none transition-colors
                   ${caseSensitive ? 'text-accent bg-accent/5' : 'text-concrete'}`}
                 title="Respecter la casse (Aa)"
               >
                 Aa
               </button>
               <button 
                 onClick={() => setUseRegex(!useRegex)}
                 className={`px-1.5 py-1 text-[9.5px] font-bold rounded-md hover:bg-black/5 dark:hover:bg-white/5 uppercase select-none transition-colors
                   ${useRegex ? 'text-accent bg-accent/5' : 'text-concrete'}`}
                 title="Activer Regex (.*)"
               >
                 .*
               </button>
               <button 
                 onClick={onClose}
                 className="p-1 hover:bg-black/5 dark:hover:bg-white/10 rounded-md text-concrete transition-all"
               >
                 <X size={14} />
               </button>
            </div>
          </div>

          {/* Quick saved criteria filter tags */}
          {savedQueries.length > 0 && (
             <div className="flex items-center gap-2 text-[10px] text-concrete font-bold tracking-tight">
                <span className="uppercase text-[9px]">Favoris:</span>
                <div className="flex flex-wrap gap-1.5">
                    {savedQueries.map(sq => (
                      <button 
                         key={sq}
                         onClick={() => setQuery(sq)}
                         className={`px-2 py-0.5 rounded-md border text-[9.5px] font-medium transition-all hover:border-accent
                           ${query === sq 
                             ? 'bg-accent/10 border-accent text-accent' 
                             : 'bg-white dark:bg-zinc-800 border-border/40 text-muted-ink'}`}
                      >
                        {sq}
                      </button>
                    ))}
                </div>
             </div>
          )}
        </div>

        {/* UTILITY BAR Row -> Match statistics with action links */}
        <div className="px-4 py-2 bg-[#F8F7F4] dark:bg-[#141414] border-b border-border/40 dark:border-zinc-850 flex items-center justify-between shrink-0">
           <div className="flex items-center gap-3">
               {/* Arrow Switchers */}
               <div className="flex items-center gap-1 border border-border/40 dark:border-zinc-800 bg-white dark:bg-zinc-900 rounded-lg p-0.5">
                  <button 
                    disabled={filteredMatches.length === 0}
                    onClick={() => setSelectedIndex(prev => Math.max(0, prev - 1))}
                    className="p-1 hover:bg-black/5 dark:hover:bg-white/5 rounded text-concrete disabled:opacity-40"
                  >
                    <ChevronLeft size={12} />
                  </button>
                  <span className="text-[9.5px] font-bold font-mono px-1.5 text-concrete">
                     {filteredMatches.length > 0 ? `${selectedIndex + 1}/${filteredMatches.length}` : '0/0'}
                  </span>
                  <button 
                    disabled={filteredMatches.length === 0}
                    onClick={() => setSelectedIndex(prev => Math.min(filteredMatches.length - 1, prev + 1))}
                    className="p-1 hover:bg-black/5 dark:hover:bg-white/5 rounded text-concrete disabled:opacity-40"
                  >
                    <ChevronRight size={12} />
                  </button>
               </div>

               <span className="text-[11px] font-medium text-concrete">
                  {filteredMatches.length > 0 
                    ? `Trouvé ${filteredMatches.length} occurrences dans ${docMatchesCount} documents` 
                    : query.trim() ? "Aucun élément ne correspond" : "Saisissez votre requête"}
               </span>
           </div>

           {/* Toolbar Action Links */}
           <div className="flex items-center gap-4">
               {query.trim() && (
                 <button 
                    onClick={savedQueries.includes(query.trim()) ? handleRemoveCriteria : handleSaveCriteria}
                    className="text-[10px] font-bold uppercase tracking-wider text-accent border-b border-dashed border-accent hover:border-solid select-none"
                 >
                    {savedQueries.includes(query.trim()) ? 'Supprimer favori' : 'Sauvegarder recherche'}
                 </button>
               )}

               <label className="flex items-center gap-1.5 cursor-pointer text-[10.5px] font-medium text-concrete">
                  <input 
                     type="checkbox"
                     checked={includeChildDocs}
                     onChange={(e) => setIncludeChildDocs(e.target.checked)}
                     className="rounded border-border/60 text-accent focus:ring-accent w-3 h-3"
                  />
                  <span>Sous-docs inclus</span>
               </label>

               <label className="flex items-center gap-1.5 cursor-pointer text-[10.5px] font-medium text-concrete">
                  <input 
                     type="checkbox"
                     checked={searchInTrash}
                     onChange={(e) => setSearchInTrash(e.target.checked)}
                     className="rounded border-border/60 text-accent focus:ring-accent w-3 h-3"
                  />
                  <span>Corbeille incluse</span>
               </label>
           </div>
        </div>

        {/* DUAL SECTION LAYOUT */}
        <div className="flex-1 flex overflow-hidden">
           
           {/* Left Section: Scrollable matches list */}
           <div className="w-[45%] h-full border-r border-border/40 dark:border-zinc-800 flex flex-col bg-[#FAF9F5]/30 dark:bg-[#121212]/30 overflow-hidden">
                <div ref={listRef} className="flex-1 overflow-y-auto custom-scrollbar p-2 space-y-1">
                   {filteredMatches.map((m, idx) => {
                       const isSelected = idx === selectedIndex;
                       return (
                          <div
                             key={m.id}
                             onClick={() => setSelectedIndex(idx)}
                             onDoubleClick={() => {
                                onSelectNote(m.noteId);
                                onClose();
                             }}
                             className={`p-2.5 rounded-xl cursor-pointer text-left select-none relative group/item transition-all flex flex-col gap-1 border
                               ${isSelected 
                                 ? 'bg-white dark:bg-zinc-800 shadow-md border-amber-500/30' 
                                 : 'border-transparent hover:bg-black/[0.02] dark:hover:bg-white/[0.02]/30'}`}
                          >
                              {/* Selection overlay accent */}
                              {isSelected && (
                                <div className="absolute left-0 top-1/2 -translate-y-1/2 w-1 h-3.5 bg-amber-500 rounded-r-full" />
                              )}

                              <div className="flex items-center justify-between text-[11px] gap-2">
                                  <div className="flex items-center gap-1.5 min-w-0 flex-1">
                                       {/* Element classifier badges */}
                                       {m.type === 'document' && (
                                         <FileText size={12} className="text-sky-500 shrink-0" />
                                       )}
                                       {m.type === 'heading' && (
                                         <span className="text-[8.5px] font-extrabold uppercase bg-indigo-50 dark:bg-indigo-950/40 text-indigo-500 border border-indigo-500/10 px-1 rounded-sm shrink-0 font-mono">
                                             H{m.headingLevel || ''}
                                         </span>
                                       )}
                                       {m.type === 'list' && (
                                         <span className="text-[8.5px] font-extrabold uppercase bg-emerald-50 dark:bg-emerald-950/40 text-emerald-500 border border-emerald-500/10 px-1 rounded-sm shrink-0 font-mono">
                                             LIST
                                         </span>
                                       )}
                                       {m.type === 'paragraph' && (
                                         <span className="text-[8px] font-extrabold uppercase bg-zinc-100 dark:bg-zinc-800 text-concrete border border-border/20 px-1 rounded-sm shrink-0 font-mono">
                                             TXT
                                         </span>
                                       )}
                                       
                                       <span className={`font-semibold truncate leading-none text-xs ${isSelected ? 'text-ink dark:text-dark-ink' : 'text-muted-ink'}`}>
                                            {m.noteTitle}
                                       </span>
                                  </div>
                              </div>

                              {/* Highlighted snippet row content */}
                              <div className="text-[11px] text-concrete truncate pl-4.5 font-sans leading-tight">
                                  {renderHighlightedRowText(m.matchedText)}
                              </div>

                              {/* Breadcrumb row path */}
                              <div className="text-[8.5px] font-mono tracking-widest uppercase text-concrete/45 truncate pl-4.5 mt-0.5 max-w-full">
                                  {m.path}
                              </div>
                          </div>
                       );
                   })}

                   {filteredMatches.length === 0 && (
                      <div className="h-full flex flex-col items-center justify-center text-center p-6 text-concrete pt-32 space-y-2">
                          <Search size={22} className="opacity-35 text-concrete animate-pulse" />
                          <p className="text-[11px] font-medium italic opacity-70">
                              {query.trim() ? "Aucun bloc ou doc ne correspond à cette recherche." : "Taper pour obtenir des résultats instantanés."}
                          </p>
                      </div>
                   )}
                </div>
           </div>

           {/* Right Section: Scrollable content preview card with visual highlighted markers */}
           <div className="flex-1 h-full bg-[#FCFCFA]/80 dark:bg-[#151515] flex flex-col overflow-hidden">
                {activeMatch ? (
                    <div className="flex-1 flex flex-col p-5 overflow-hidden justify-between">
                         <div className="space-y-4 overflow-hidden flex flex-col flex-1">
                             {/* Breadcrumb locator line */}
                             <div className="flex items-center gap-1.5 p-2 bg-black/[0.02] dark:bg-white/[0.02] border border-border/40 rounded-xl">
                                 <Folder size={11} className="text-concrete" />
                                 <span className="text-[9.5px] font-mono tracking-widest text-concrete font-medium uppercase truncate flex-1">
                                    {activeMatch.path}
                                 </span>
                             </div>

                             {/* Document focus heading title */}
                             <div className="border-b border-border/40 dark:border-zinc-800 pb-2">
                                 <h4 className="text-[13px] font-serif font-black text-ink dark:text-dark-ink">
                                     {activeMatch.noteTitle}
                                 </h4>
                                 <p className="text-[8px] uppercase tracking-wider text-concrete font-bold mt-1">APERÇU CONTEXTUEL DU BLOC</p>
                             </div>

                             {/* Dynamic document contents highlighted and framed */}
                             <div className="flex-1 overflow-y-auto custom-scrollbar pr-1 bg-white dark:bg-[#121212] border border-border/30 rounded-xl p-3.5 shadow-inner">
                                  {highlightedNotePreviewContent}
                             </div>
                         </div>

                         {/* Quick Actions trigger buttons */}
                         <div className="pt-4 border-t border-border/40 dark:border-zinc-800 flex items-center justify-between shrink-0">
                             <button
                                onClick={() => {
                                  onSelectNote(activeMatch.noteId);
                                  onClose();
                                }}
                                className="px-5 py-2.5 bg-ink text-white dark:bg-white dark:text-black hover:scale-102 active:scale-98 text-xs font-semibold rounded-xl flex items-center gap-2 transition-all shadow-sm"
                             >
                                 <CornerDownRight size={13} />
                                 <span>Ouvrir dans l'éditeur</span>
                             </button>
                             <span className="text-[10px] text-concrete font-bold font-mono bg-paper dark:bg-white/5 border border-border/30 px-2 py-1 rounded">
                                 ID: {activeMatch.noteId.slice(0, 6)}...
                             </span>
                         </div>
                    </div>
                ) : (
                    <div className="flex-1 flex flex-col items-center justify-center text-center p-6 text-concrete space-y-3">
                         <HelpCircle size={24} className="opacity-25" />
                         <div className="space-y-1">
                              <p className="text-[11.5px] font-bold">Aperçu du document</p>
                              <p className="text-[10px] italic opacity-60">Sélectionnez un résultat de recherche de la colonne et explorez immédiatement son contenu sémantique.</p>
                         </div>
                    </div>
                )}
           </div>

        </div>

        {/* BOTTOM Status Keyboard shortcuts hint footer bar */}
        <div className="p-3.5 bg-[#FAF9F5] dark:bg-[#0E0E0E] border-t border-border/50 dark:border-zinc-800/60 flex items-center justify-between shrink-0 font-sans">
             <div className="flex items-center gap-5 text-[9.5px] font-bold text-concrete/75 antialiased">
                 <span className="flex items-center gap-1.5"><strong className="bg-slate-200 dark:bg-zinc-800 px-1 py-0.5 rounded text-ink dark:text-light">↑↓</strong> naviguer</span>
                 <span className="flex items-center gap-1.5"><strong className="bg-slate-200 dark:bg-zinc-800 px-1 py-0.5 rounded text-ink dark:text-light">Entrée</strong> ouvrir</span>
                 <span className="flex items-center gap-1.5"><strong className="bg-slate-200 dark:bg-zinc-800 px-1 py-0.5 rounded text-ink dark:text-light">Double clic</strong> ouvrir</span>
                 <span className="flex items-center gap-1.5"><strong className="bg-slate-200 dark:bg-zinc-800 px-1 py-0.5 rounded text-ink dark:text-light">Échap</strong> fermer</span>
             </div>

             <div className="flex items-center gap-1.5 text-[9px] font-bold uppercase tracking-wider text-concrete/60">
                 <Command size={10} />
                 <span>Memento Search OS v2.3</span>
             </div>
        </div>
      </motion.div>
    </div>
  );
};
