import React from 'react';
import { 
  Plus, 
  Search, 
  Share2, 
  Pin, 
  ChevronRight, 
  ChevronUp, 
  ChevronDown, 
  ArrowLeft, 
  MoreVertical, 
  Sparkles, 
  Tag as TagIcon, 
  X, 
  BookOpen, 
  Edit3, 
  Eye, 
  Trash2, 
  Wind, 
  FileText, 
  Paperclip, 
  Loader2, 
  MessageSquare, 
  Menu, 
  Globe, 
  Link2, 
  Folder, 
  LayoutGrid, 
  List, 
  Table, 
  CheckSquare,
  GraduationCap,
  PanelRight
} from 'lucide-react';
import { motion, AnimatePresence } from 'motion/react';
import { Note, Carnet, Tag, Attachment, Flashcard } from '../types';
import { SlashMenu } from './SlashMenu';
import { parseDocument } from '../services/geminiService';
import { v4 as uuidv4 } from 'uuid';
import { LivingBlock } from './LivingBlock';
import { BlockPicker } from './BlockPicker';
import { NotebookInfoSidebar } from './NotebookInfoSidebar';
import { ModernBlockNoteEditor } from './ModernBlockNoteEditor';

interface NotebooksViewProps {
  activeNoteId: string | null;
  activeCarnet: Carnet | undefined;
  filteredNotes: Note[];
  activeNote: Note | undefined;
  setActiveNoteId: (id: string | null) => void;
  togglePin: (id: string) => void;
  setShowNewNoteModal: (show: boolean) => void;
  isAISidebarOpen: boolean;
  setIsAISidebarOpen: (open: boolean) => void;
  selectedTagIds: string[];
  setSelectedTagIds: (ids: string[]) => void;
  allNotes: Note[];
  activeCarnetId: string;
  setShowNewCarnetModal: (show: boolean, parentId?: string, isRenaming?: boolean, carnetId?: string) => void;
  onDeleteNote: (id: string) => void;
  onBrainstormNote: (note: Note) => void;
  onUpdateNote?: (note: Note) => void;
  onOpenSidebar?: () => void;
  onSearchClick?: () => void;
  wsConnected?: boolean;
  broadcastLivingBlockUpdate?: (sourceNoteId: string, blockIndex: number, newText: string) => void;
  carnets?: Carnet[]; // Optional carnets list
  flashcards?: Flashcard[];
  onTriggerReviewDeck?: (noteId: string) => void;
  onGenerateFlashcards?: (noteId: string) => Promise<void>;
  isGeneratingFlashcards?: boolean;
}

export const NotebooksView: React.FC<NotebooksViewProps> = ({
  activeNoteId,
  activeCarnet,
  filteredNotes,
  activeNote,
  setActiveNoteId,
  togglePin,
  setShowNewNoteModal,
  isAISidebarOpen,
  setIsAISidebarOpen,
  selectedTagIds,
  setSelectedTagIds,
  allNotes,
  activeCarnetId,
  setShowNewCarnetModal,
  onDeleteNote,
  onBrainstormNote,
  onUpdateNote,
  onOpenSidebar,
  onSearchClick,
  wsConnected = true,
  broadcastLivingBlockUpdate,
  carnets = [],
  flashcards = [],
  onTriggerReviewDeck,
  onGenerateFlashcards,
  isGeneratingFlashcards = false
}) => {
  const [isTagsExpanded, setIsTagsExpanded] = React.useState(false);
  const [tagSearchQuery, setTagSearchQuery] = React.useState('');
  const [isEditing, setIsEditing] = React.useState(false);
  const [isNoteInfoOpen, setIsNoteInfoOpen] = React.useState(false);
  const [slashMenu, setSlashMenu] = React.useState<{ isOpen: boolean; top: number; left: number } | null>(null);
  const [isAnalyzing, setIsAnalyzing] = React.useState<string | null>(null);
  const [activeDocQnA, setActiveDocQnA] = React.useState<Attachment | null>(null);
  const [isPickerOpen, setIsPickerOpen] = React.useState(false);
  const [prefilledBlock, setPrefilledBlock] = React.useState<{ noteId: string; blockIndex: number } | null>(null);

  // Flashcards state computations
  const noteFlashcards = React.useMemo(() => {
    if (!activeNote || !flashcards) return [];
    return flashcards.filter(c => c.noteId === activeNote.id);
  }, [flashcards, activeNote]);

  const nextRecallText = React.useMemo(() => {
    if (noteFlashcards.length === 0) return '';
    let minDate = noteFlashcards[0].nextReviewDate;
    noteFlashcards.forEach(c => {
      if (c.nextReviewDate < minDate) {
        minDate = c.nextReviewDate;
      }
    });
    
    const diff = new Date(minDate).getTime() - Date.now();
    if (diff <= 0) return "Dû aujourd'hui";
    const days = Math.ceil(diff / (24 * 60 * 60 * 1000));
    return `dans ${days}j`;
  }, [noteFlashcards]);

  // Vue Structurée states
  const [viewType, setViewType] = React.useState<'notes' | 'tasks'>('notes');
  const [layoutMode, setLayoutMode] = React.useState<'grid' | 'list' | 'table'>('list');
  const [sortColumn, setSortColumn] = React.useState<'title' | 'carnet' | 'labels' | 'tasks' | 'modified' | null>(null);
  const [sortDirection, setSortDirection] = React.useState<'asc' | 'desc' | null>(null);

  // Helper mapping french relative dates for architecture aesthetics
  const getRelativeFrenchDate = (dateStr: string): string => {
    if (dateStr.includes('Oct 26')) return 'il y a 2h';
    if (dateStr.includes('Oct 27')) return 'il y a 1j';
    if (dateStr.includes('Oct 24')) return 'il y a 3j';
    if (dateStr.includes('Oct 25')) return 'il y a 2j';
    if (dateStr.includes('Oct 22')) return 'il y a 5j';
    if (dateStr.includes('Oct 23')) return 'il y a 4j';
    if (dateStr.includes('Oct 28')) return 'il y a 10 min';
    
    // Fallback calculation relative to May 24, 2026
    try {
      const d = new Date(dateStr);
      const now = new Date("2026-05-24T07:18:49Z");
      const diffTime = Math.abs(now.getTime() - d.getTime());
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
      
      if (diffDays <= 1) return "aujourd'hui";
      if (diffDays <= 2) return "hier";
      if (diffDays <= 7) return `il y a ${diffDays}j`;
      if (diffDays <= 30) return `il y a ${Math.floor(diffDays / 7)} sem.`;
      return `il y a ${Math.floor(diffDays / 30)} mois`;
    } catch (e) {
      return dateStr;
    }
  };

  // Aesthetic deterministic carnet colors
  const getCarnetColor = (c: Carnet) => {
    const colors = [
      { bg: 'bg-[#A47148]/5 dark:bg-[#A47148]/10', border: 'border-[#A47148]/20', text: 'text-[#A47148]' },
      { bg: 'bg-emerald-500/5 dark:bg-emerald-500/10', border: 'border-emerald-500/15', text: 'text-emerald-600 dark:text-emerald-400' },
      { bg: 'bg-indigo-500/5 dark:bg-indigo-500/10', border: 'border-indigo-500/15', text: 'text-indigo-600 dark:text-indigo-400' },
      { bg: 'bg-blue-500/5 dark:bg-blue-500/10', border: 'border-blue-500/15', text: 'text-blue-600 dark:text-blue-400' },
      { bg: 'bg-amber-500/5 dark:bg-amber-500/10', border: 'border-amber-500/15', text: 'text-amber-600 dark:text-amber-400' },
      { bg: 'bg-rose-500/5 dark:bg-rose-500/10', border: 'border-rose-500/15', text: 'text-rose-600 dark:text-rose-400' },
    ];
    
    if (c.type === 'Private') return colors[0];
    if (c.type === 'Shared') return colors[2];
    
    const idx = Math.abs(c.name.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)) % colors.length;
    return colors[idx];
  };

  // Extract tasks from markdown format: - [ ] Task name
  const getNoteTasksStats = (content: string) => {
    const lines = content.split('\n');
    let total = 0;
    let completed = 0;
    lines.forEach(line => {
      const match = line.match(/^\s*[-*]?\s*\[([ xX])\]\s*(.*)$/);
      if (match) {
        total++;
        if (match[1].toLowerCase() === 'x') {
          completed++;
        }
      }
    });
    return { completed, total };
  };

  interface TaskItem {
    id: string;
    noteId: string;
    noteTitle: string;
    text: string;
    completed: boolean;
    lineIndex: number;
  }

  const extractTasks = React.useMemo(() => {
    const tasksList: TaskItem[] = [];
    filteredNotes.forEach(note => {
      const lines = note.content.split('\n');
      lines.forEach((line, idx) => {
        const match = line.match(/^\s*[-*]?\s*\[([ xX])\]\s*(.*)$/);
        if (match) {
          tasksList.push({
            id: `${note.id}-${idx}`,
            noteId: note.id,
            noteTitle: note.title,
            text: match[2].trim(),
            completed: match[1].toLowerCase() === 'x',
            lineIndex: idx
          });
        }
      });
    });
    return tasksList;
  }, [filteredNotes]);

  const completedTasksCount = React.useMemo(() => {
    return extractTasks.filter(t => t.completed).length;
  }, [extractTasks]);

  const handleToggleTask = (task: TaskItem) => {
    const note = allNotes.find(n => n.id === task.noteId);
    if (!note) return;
    const lines = note.content.split('\n');
    const line = lines[task.lineIndex];
    if (line) {
      const isNowCompleted = !task.completed;
      const nextChar = isNowCompleted ? 'x' : ' ';
      const updatedLine = line.replace(/\[([ xX])\]/, `[${nextChar}]`);
      lines[task.lineIndex] = updatedLine;
      const updatedNote = { ...note, content: lines.join('\n') };
      if (onUpdateNote) {
        onUpdateNote(updatedNote);
      }
    }
  };

  // Click handler to toggle sorting order
  const handleSort = (field: 'title' | 'carnet' | 'labels' | 'tasks' | 'modified') => {
    if (sortColumn !== field) {
      setSortColumn(field);
      setSortDirection('asc');
    } else if (sortDirection === 'asc') {
      setSortDirection('desc');
    } else {
      setSortColumn(null);
      setSortDirection(null);
    }
  };

  // Computes the sorted copy of filteredNotes
  const sortedNotes = React.useMemo(() => {
    if (!sortColumn || !sortDirection) return filteredNotes;
    
    const notesCopy = [...filteredNotes];
    return notesCopy.sort((a, b) => {
      let valA: any = '';
      let valB: any = '';
      
      if (sortColumn === 'title') {
        valA = (a.title || '').toLowerCase();
        valB = (b.title || '').toLowerCase();
      } else if (sortColumn === 'carnet') {
        const parentA = carnets?.find(c => c.id === a.carnetId)?.name || '';
        const parentB = carnets?.find(c => c.id === b.carnetId)?.name || '';
        valA = parentA.toLowerCase();
        valB = parentB.toLowerCase();
      } else if (sortColumn === 'labels') {
        valA = a.tags?.length || 0;
        valB = b.tags?.length || 0;
      } else if (sortColumn === 'tasks') {
        const statsA = getNoteTasksStats(a.content);
        const statsB = getNoteTasksStats(b.content);
        valA = statsA.total > 0 ? (statsA.completed / statsA.total) : -1;
        valB = statsB.total > 0 ? (statsB.completed / statsB.total) : -1;
      } else if (sortColumn === 'modified') {
        valA = new Date(a.date).getTime() || 0;
        valB = new Date(b.date).getTime() || 0;
      }
      
      if (valA < valB) return sortDirection === 'asc' ? -1 : 1;
      if (valA > valB) return sortDirection === 'asc' ? 1 : -1;
      return 0;
    });
  }, [filteredNotes, sortColumn, sortDirection, carnets]);

  const renderSortIndicator = (field: 'title' | 'carnet' | 'labels' | 'tasks' | 'modified') => {
    if (sortColumn !== field) return null;
    return sortDirection === 'asc' ? (
      <ChevronUp size={10} className="text-accent ml-1 inline-block transition-transform duration-200" />
    ) : (
      <ChevronDown size={10} className="text-accent ml-1 inline-block transition-transform duration-200" />
    );
  };

  const fileInputRef = React.useRef<HTMLInputElement>(null);
  const titleInputRef = React.useRef<HTMLInputElement>(null);
  const contentTextareaRef = React.useRef<HTMLTextAreaElement>(null);

  const backlinks = React.useMemo(() => {
    if (!activeNote) return [];
    const list: Array<{ note: Note; accessedAt: string }> = [];
    allNotes.forEach(note => {
      if (note.id === activeNote.id) return;
      if (note.content.includes(`[[living-block:${activeNote.id}:`)) {
        list.push({ note, accessedAt: "Récemment" });
      }
    });
    return list;
  }, [allNotes, activeNote]);

  const memoryEchoBlock = React.useMemo(() => {
    if (!activeNote) return null;
    const otherNotes = allNotes.filter(n => n.id !== activeNote.id);
    if (otherNotes.length === 0) return null;
    let bestNote = otherNotes[0];
    let maxOverlap = -1;
    const currentTags = new Set(activeNote.tags?.map(t => t.id) || []);
    otherNotes.forEach(note => {
      const overlap = note.tags?.filter(t => currentTags.has(t.id)).length || 0;
      if (overlap > maxOverlap) {
        maxOverlap = overlap;
        bestNote = note;
      }
    });
    const lines = bestNote.content.split('\n').filter(line => line.trim().length > 30 && !line.startsWith('#') && !line.startsWith('[[living-block'));
    if (lines.length === 0) return null;
    const blockText = lines[0];
    const blockIndex = bestNote.content.split('\n').indexOf(blockText);
    return {
      noteId: bestNote.id,
      noteTitle: bestNote.title || "Note reliée",
      text: blockText,
      blockIndex
    };
  }, [activeNote, allNotes]);

  const handleSelectBlock = (sourceNoteId: string, blockIndex: number) => {
    setIsPickerOpen(false);
    setPrefilledBlock(null);
    if (!activeNote) return;

    const blockCode = `\n[[living-block:${sourceNoteId}:${blockIndex}]]\n`;
    
    // Insert blockCode into textarea at cursor or end of text
    const textarea = contentTextareaRef.current;
    if (textarea) {
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const originalText = textarea.value;
      const newText = originalText.substring(0, start) + blockCode + originalText.substring(end);
      
      const updatedNote = { ...activeNote, content: newText };
      onUpdateNote?.(updatedNote);
      
      // Update defaultValue/value of textarea
      textarea.value = newText;
    } else {
      // Fallback: append to end of content
      const updatedNote = { 
        ...activeNote, 
        content: activeNote.content + blockCode
      };
      onUpdateNote?.(updatedNote);
    }
  };

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file || !activeNote) return;

    const newAttachment: Attachment = {
      id: uuidv4(),
      name: file.name,
      type: file.name.endsWith('.pdf') ? 'pdf' : (file.name.endsWith('.docx') ? 'docx' : 'other'),
      url: URL.createObjectURL(file), // Local preview url
      isProcessed: false
    };

    const updatedNote = {
      ...activeNote,
      attachments: [...(activeNote.attachments || []), newAttachment]
    };

    onUpdateNote?.(updatedNote);
    
    // Auto-analyze
    setIsAnalyzing(newAttachment.id);
    const content = await parseDocument(newAttachment.url, newAttachment.name);
    
    const processedAttachment = { ...newAttachment, content, isProcessed: true };
    const finalNote = {
      ...activeNote,
      attachments: [...(activeNote.attachments || []), processedAttachment]
    };
    onUpdateNote?.(finalNote);
    setIsAnalyzing(null);
  };

  const handleEditorKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === '/') {
      const selection = window.getSelection();
      if (selection && selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        const rect = range.getBoundingClientRect();
        setSlashMenu({
          isOpen: true,
          top: rect.bottom + window.scrollY,
          left: rect.left + window.scrollX
        });
      }
    }
  };

  const insertCommand = (type: string) => {
    console.log(`Command selected: ${type}`);
    setSlashMenu(null);
    if (type === 'embed') {
      setPrefilledBlock(null);
      setIsPickerOpen(true);
    }
  };

  const availableTags = React.useMemo(() => {
    const carnetNotes = allNotes.filter(n => n.carnetId === activeCarnetId);
    const tagsMap = new Map<string, Tag>();
    carnetNotes.forEach(note => {
      note.tags?.forEach(tag => {
        tagsMap.set(tag.id, tag);
      });
    });
    return Array.from(tagsMap.values()).sort((a, b) => {
      // AI tags first, then alphabetical
      if (a.type === 'ai' && b.type !== 'ai') return -1;
      if (a.type !== 'ai' && b.type === 'ai') return 1;
      return a.label.localeCompare(b.label);
    });
  }, [allNotes, activeCarnetId]);

  const visibleTags = React.useMemo(() => {
    let filtered = availableTags;
    if (tagSearchQuery) {
      filtered = availableTags.filter(t => 
        t.label.toLowerCase().includes(tagSearchQuery.toLowerCase())
      );
    } else if (!isTagsExpanded) {
      filtered = availableTags.slice(0, 10);
      // Ensure selected tags are always visible even if not in the first 10
      selectedTagIds.forEach(id => {
        if (!filtered.find(t => t.id === id)) {
          const tag = availableTags.find(t => t.id === id);
          if (tag) filtered.push(tag);
        }
      });
    }
    return filtered;
  }, [availableTags, isTagsExpanded, tagSearchQuery, selectedTagIds]);

  const toggleTag = (tagId: string) => {
    if (selectedTagIds.includes(tagId)) {
      setSelectedTagIds(selectedTagIds.filter(id => id !== tagId));
    } else {
      setSelectedTagIds([...selectedTagIds, tagId]);
    }
  };

  if (!activeNoteId) {
    return (
      <div className="h-full flex flex-col overflow-y-auto">
        <header className="px-6 sm:px-12 pt-12 pb-8 flex flex-col gap-6 sticky top-0 bg-paper/80 backdrop-blur-md z-30">
          <div className="flex justify-between items-start gap-4">
            <button 
              onClick={onOpenSidebar}
              className="lg:hidden p-2 -ml-2 text-ink hover:bg-black/5 rounded-lg transition-colors"
            >
              <Menu size={20} />
            </button>
            <h1 className="text-3xl sm:text-4xl font-serif font-medium tracking-tight text-ink leading-tight flex-1 pr-6">
              {activeCarnet?.name} — {filteredNotes[0]?.date || 'Oct 26'}
            </h1>
          </div>
          
          <div className="flex items-center justify-between border-b border-ink/5 pb-4 flex-wrap gap-4 select-none">
            <div className="flex items-center gap-6">
              <button 
                onClick={() => setShowNewNoteModal(true)}
                className="flex items-center gap-2 text-[13px] text-ink font-medium hover:opacity-70 transition-opacity cursor-pointer"
              >
                <Plus size={16} />
                <span>Add Note</span>
              </button>
              <button 
                onClick={() => setShowNewCarnetModal(true, activeCarnetId)}
                className="flex items-center gap-2 text-[13px] text-concrete font-medium hover:text-ink transition-all cursor-pointer"
              >
                <BookOpen size={16} />
                <span>New Sub-Carnet</span>
              </button>
              <button 
                onClick={onSearchClick}
                className="flex items-center gap-2 text-[13px] text-ink font-medium hover:opacity-70 transition-opacity cursor-pointer"
              >
                <Search size={16} />
                <span>Search</span>
              </button>
            </div>
            
            <div className="flex items-center gap-4 flex-wrap">
              {/* Onglet Notes / Tâches */}
              <div className="bg-black/[0.03] dark:bg-white/[0.04] p-0.5 rounded-full flex border border-border/30">
                <button
                  onClick={() => setViewType('notes')}
                  className={`px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider transition-all cursor-pointer
                    ${viewType === 'notes' 
                      ? 'bg-ink text-paper dark:bg-white dark:text-black shadow-sm' 
                      : 'text-concrete hover:text-ink'}`}
                >
                  Notes
                </button>
                <button
                  onClick={() => setViewType('tasks')}
                  className={`px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider transition-all cursor-pointer
                    ${viewType === 'tasks' 
                      ? 'bg-ink text-paper dark:bg-white dark:text-black shadow-sm' 
                      : 'text-concrete hover:text-ink'}`}
                >
                  Tâches
                </button>
              </div>

              {/* Toggle 3 états pour Notes */}
              {viewType === 'notes' && (
                <div className="bg-black/[0.03] dark:bg-white/[0.04] p-0.5 rounded-full flex border border-border/30 items-center">
                  <button
                    onClick={() => setLayoutMode('grid')}
                    className={`p-1.5 rounded-full transition-all cursor-pointer ${layoutMode === 'grid' ? 'bg-ink text-paper dark:bg-white dark:text-black shadow-sm' : 'text-concrete hover:text-ink'}`}
                    title="Vue cartes / grille"
                  >
                    <LayoutGrid size={13} />
                  </button>
                  <button
                    onClick={() => setLayoutMode('list')}
                    className={`p-1.5 rounded-full transition-all cursor-pointer ${layoutMode === 'list' ? 'bg-ink text-paper dark:bg-white dark:text-black shadow-sm' : 'text-concrete hover:text-ink'}`}
                    title="Vue liste éditoriale"
                  >
                    <List size={13} />
                  </button>
                  <button
                    onClick={() => setLayoutMode('table')}
                    className={`p-1.5 rounded-full transition-all cursor-pointer ${layoutMode === 'table' ? 'bg-ink text-paper dark:bg-white dark:text-black shadow-sm' : 'text-concrete hover:text-ink'}`}
                    title="Vue tableau structuré"
                  >
                    <Table size={13} />
                  </button>
                </div>
              )}

              <button className="flex items-center gap-2 text-[13px] text-ink font-medium hover:opacity-70 transition-opacity cursor-pointer">
                <Share2 size={16} />
                <span>Share</span>
              </button>
            </div>
          </div>

          <div className="flex flex-col gap-4">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-3 text-[10px] font-bold uppercase tracking-[0.2em] text-concrete">
                <TagIcon size={12} />
                <span>Filter by Tags</span>
                {selectedTagIds.length > 0 && (
                  <span className="bg-accent/10 text-accent px-2 py-0.5 rounded-full text-[9px] lowercase tracking-normal">
                    {selectedTagIds.length} active
                  </span>
                )}
              </div>
              
              {availableTags.length > 10 && (
                <div className="relative group">
                  <input 
                    type="text"
                    placeholder="Search tags..."
                    className="bg-transparent border-b border-border/40 text-[10px] outline-none focus:border-accent/40 py-1 px-2 w-32 transition-all focus:w-48 placeholder:text-concrete/40"
                    onChange={(e) => setTagSearchQuery(e.target.value)}
                  />
                </div>
              )}
            </div>

            <div className="flex flex-wrap gap-2 items-center min-h-[32px]">
              <AnimatePresence mode="popLayout">
                {visibleTags.map(tag => {
                  const isActive = selectedTagIds.includes(tag.id);
                  return (
                    <motion.button
                      layout
                      initial={{ opacity: 0, scale: 0.9 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0.9 }}
                      key={tag.id}
                      onClick={() => toggleTag(tag.id)}
                      className={`px-3 py-1.5 rounded-full text-[10px] font-bold uppercase tracking-wider transition-all border flex items-center gap-2
                        ${isActive 
                          ? 'bg-ink text-paper border-ink shadow-lg shadow-ink/10' 
                          : 'bg-white/40 border-border text-concrete hover:border-concrete/40 hover:bg-white/60'}`}
                    >
                      {tag.type === 'ai' && (
                        <Sparkles 
                          size={10} 
                          className={isActive ? 'text-accent' : 'text-accent/60'} 
                        />
                      )}
                      {tag.label}
                      {isActive && <X size={10} />}
                    </motion.button>
                  );
                })}
              </AnimatePresence>

              {availableTags.length > 10 && !tagSearchQuery && (
                <button 
                  onClick={() => setIsTagsExpanded(!isTagsExpanded)}
                  className="px-3 py-1.5 text-[10px] font-bold uppercase tracking-wider text-concrete/60 hover:text-ink transition-colors border border-dashed border-border rounded-full"
                >
                  {isTagsExpanded ? 'Show less' : `+ ${availableTags.length - 10} more`}
                </button>
              )}

              {selectedTagIds.length > 0 && (
                <button 
                  onClick={() => setSelectedTagIds([])}
                  className="px-3 py-1.5 text-[10px] font-bold uppercase tracking-wider text-rust hover:underline ml-auto"
                >
                  Clear all
                </button>
              )}
            </div>
          </div>
        </header>

        <div className="px-6 md:px-12 flex-1 pb-20 pt-6">
          {viewType === 'tasks' ? (
            // ================== FLAT TASKS LIST VIEW ==================
            <div className="max-w-4xl mx-auto space-y-6">
              <div className="flex items-center justify-between pb-3 border-b border-black/[0.05] dark:border-white/[0.05]">
                <div className="flex items-center gap-2">
                  <div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
                  <span className="text-[10px] uppercase font-bold tracking-[0.2em] text-concrete">
                    Ravi de vous revoir — Tâches d'Architecture
                  </span>
                </div>
                <div className="text-[11px] font-mono font-bold text-ink bg-black/[0.03] dark:bg-white/5 py-1 px-3 rounded-full">
                  {extractTasks.length} tâches · {completedTasksCount} complétées
                </div>
              </div>

              {extractTasks.length > 0 ? (
                <div className="overflow-hidden border border-[#D5D2CD]/40 dark:border-neutral-800/40 rounded-2xl bg-paper dark:bg-[#1C1C1E]/20 shadow-sm">
                  <div className="divide-y divide-black/[0.04] dark:divide-white/[0.04]">
                    {extractTasks.map((task, idx) => (
                      <div 
                        key={task.id} 
                        className="p-4 flex items-center justify-between gap-4 hover:bg-black/[0.01] dark:hover:bg-white/[0.01] transition-all group"
                      >
                        <div className="flex items-center gap-3.5 flex-grow min-w-0">
                          <button
                            onClick={() => handleToggleTask(task)}
                            className={`w-5 h-5 rounded-md border flex items-center justify-center transition-all cursor-pointer shrink-0
                              ${task.completed 
                                ? 'bg-[#A47148] border-[#A47148] text-white' 
                                : 'border-[#D5D2CD] dark:border-neutral-700 hover:border-accent bg-transparent'}`}
                          >
                            {task.completed && <span className="text-xs font-bold font-sans">✓</span>}
                          </button>
                          
                          <span className={`text-[13px] font-light leading-relaxed truncate text-ink/80
                            ${task.completed ? 'line-through text-concrete decoration-concrete' : 'dark:text-white/95'}`}
                          >
                            {task.text}
                          </span>
                        </div>

                        <div className="flex items-center gap-2 shrink-0">
                          <span className="text-[9.5px] uppercase font-mono tracking-wider text-concrete dark:text-neutral-500 max-w-[140px] truncate">
                            Note : {task.noteTitle}
                          </span>
                          <button
                            onClick={() => setActiveNoteId(task.noteId)}
                            className="p-1.5 rounded-full hover:bg-black/5 dark:hover:bg-white/5 text-concrete hover:text-ink transition-all cursor-pointer"
                            title="Ouvrir la note source"
                          >
                            <Link2 size={13} />
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              ) : (
                // ================== EMPTY STATE TASKS ==================
                <div className="h-64 flex flex-col items-center justify-center text-center space-y-4">
                  <div className="w-12 h-12 rounded-full bg-neutral-100 dark:bg-zinc-800/50 flex items-center justify-center border border-border/40 text-concrete animate-pulse">
                    <CheckSquare size={18} className="text-concrete/60" />
                  </div>
                  <p className="font-serif text-lg italic text-muted-ink">Aucune tâche dans ce carnet</p>
                  <p className="text-xs text-concrete/70 max-w-sm leading-relaxed font-light">
                    Ajoutez des lignes de tâches au format <code className="font-mono text-[10.5px] bg-black/[0.04] dark:bg-white/5 p-1 px-1.5 rounded text-ink dark:text-amber-200">- [ ] Ma tâche</code> dans vos notes pour commencer.
                  </p>
                </div>
              )}
            </div>
          ) : layoutMode === 'grid' ? (
            // ================== CARDS/GRID VIEW ==================
            <div className="max-w-6xl mx-auto space-y-8">
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                {sortedNotes.map((note, index) => {
                  const stats = getNoteTasksStats(note.content);
                  return (
                    <motion.div
                      initial={{ opacity: 0, y: 15 }}
                      animate={{ opacity: 1, y: 0 }}
                      transition={{ delay: 0.04 * index, duration: 0.5 }}
                      key={note.id}
                      onClick={() => setActiveNoteId(note.id)}
                      className="bg-white dark:bg-[#1C1C1E]/40 border border-[#D5D2CD]/40 dark:border-neutral-800/40 rounded-2xl overflow-hidden hover:shadow-md hover:border-accent/30 transition-all duration-300 group/card cursor-pointer flex flex-col"
                    >
                      {/* Thumbnail with black white architectural look */}
                      <div className="aspect-[16/10] bg-neutral-100 dark:bg-neutral-900 border-b border-[#D5D2CD]/20 dark:border-neutral-800/20 overflow-hidden relative">
                        <img
                          src={note.imageUrl}
                          alt={note.title}
                          className="w-full h-full object-cover mix-blend-multiply dark:mix-blend-normal opacity-85 grayscale contrast-115 group-hover/card:scale-105 group-hover/card:grayscale-0 group-hover/card:opacity-100 transition-all duration-500"
                          referrerPolicy="no-referrer"
                        />
                        {note.isPinned && (
                          <div className="absolute top-3 left-3 bg-paper/90 dark:bg-dark-paper/90 backdrop-blur-sm p-1.5 rounded-full shadow-sm border border-border/40 text-amber-500">
                            <Pin size={11} className="fill-amber-500" />
                          </div>
                        )}
                        {stats.total > 0 && (
                          <div className="absolute top-3 right-3 bg-paper/90 dark:bg-dark-paper/90 backdrop-blur-sm py-1 px-2.5 rounded-full shadow-sm border border-border/40 text-[9.5px] font-mono font-bold text-concrete">
                            {stats.completed}/{stats.total} ✓
                          </div>
                        )}
                      </div>

                      <div className="p-5 flex-1 flex flex-col justify-between space-y-4">
                        <div className="space-y-2.5">
                          <div className="flex flex-wrap gap-1.5">
                            {note.tags?.slice(0, 2).map(tag => (
                              <span
                                key={tag.id}
                                className={`px-1.5 py-0.5 rounded text-[8px] font-bold uppercase tracking-wider border flex items-center gap-1
                                  ${tag.type === 'ai' 
                                    ? 'bg-accent/5 border-accent/15 text-accent' 
                                    : 'bg-concrete/5 border-border text-concrete'}`}
                              >
                                {tag.type === 'ai' && <Sparkles size={6} />}
                                {tag.label}
                              </span>
                            ))}
                          </div>

                          <h3 className="font-serif text-base font-semibold text-ink leading-snug group-hover/card:text-accent transition-colors flex items-center justify-between gap-2">
                            <span className="truncate">{note.title}</span>
                          </h3>

                          <p className="text-xs text-concrete dark:text-neutral-400 leading-relaxed line-clamp-3 font-light text-justify">
                            {note.content.replace(/[-*]?\s*\[([ xX])\]\s*(.*)/g, '').trim().substring(0, 110)}...
                          </p>
                        </div>

                        <div className="flex items-center justify-between pt-3 border-t border-black/[0.03] dark:border-white/[0.03] text-[9.5px] text-concrete font-medium uppercase tracking-wider">
                          <span>{note.date}</span>
                          <div className="flex items-center gap-1 opacity-0 group-hover/card:opacity-100 transition-opacity">
                            <button
                              onClick={(e) => {
                                e.stopPropagation();
                                onBrainstormNote(note);
                              }}
                              className="p-1 px-2 rounded-full hover:bg-ochre/10 text-ochre transition-all flex items-center gap-1 cursor-pointer"
                              title="Brainstorm this concept"
                            >
                              <Wind size={11} />
                            </button>
                            <button
                              onClick={(e) => {
                                e.stopPropagation();
                                togglePin(note.id);
                              }}
                              className="p-1 px-2 rounded-full hover:bg-slate-100 dark:hover:bg-white/10 text-ink transition-all cursor-pointer"
                            >
                              <Pin size={11} className={note.isPinned ? "fill-amber-500 text-amber-500" : ""} />
                            </button>
                            <button
                              onClick={(e) => {
                                e.stopPropagation();
                                onDeleteNote(note.id);
                              }}
                              className="p-1 px-2 rounded-full hover:bg-rose-50 text-rose-500 transition-all cursor-pointer"
                            >
                              <Trash2 size={11} />
                            </button>
                          </div>
                        </div>
                      </div>
                    </motion.div>
                  );
                })}
              </div>

              {sortedNotes.length === 0 && (
                <div className="h-64 flex flex-col items-center justify-center text-center space-y-4">
                  <p className="font-serif text-xl italic text-muted-ink">This notebook is waiting for its first vision.</p>
                  <button 
                    onClick={() => setShowNewNoteModal(true)}
                    className="px-6 py-2 border border-ink text-[13px] uppercase tracking-[0.2em] hover:bg-ink hover:text-paper transition-all cursor-pointer"
                  >
                    Begin Drawing
                  </button>
                </div>
              )}
            </div>
          ) : layoutMode === 'table' ? (
            // ================== STRUCTURING TABLE VIEW ==================
            <div className="max-w-6xl mx-auto space-y-4 select-none">
              <div className="w-full overflow-x-auto border border-[#D5D2CD]/40 dark:border-neutral-800/40 rounded-2xl bg-white dark:bg-[#1C1C1E]/20 shadow-sm [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar-thumb]:bg-black/10 [&::-webkit-scrollbar-track]:bg-transparent">
                <table className="w-full text-left border-collapse table-fixed min-w-[700px]">
                  <thead>
                    <tr className="border-b border-black/[0.04] dark:border-white/[0.04] bg-black/[0.01] dark:bg-white/[0.01]">
                      {/* Titre */}
                      <th 
                        onClick={() => handleSort('title')}
                        className="w-[40%] px-4 py-3 text-[10px] uppercase tracking-widest font-black text-concrete cursor-pointer hover:text-ink transition-colors"
                      >
                        <div className="flex items-center gap-1">
                          <span>Titre</span>
                          {renderSortIndicator('title')}
                        </div>
                      </th>
                      {/* Carnet */}
                      <th 
                        onClick={() => handleSort('carnet')}
                        className="w-[15%] px-4 py-3 text-[10px] uppercase tracking-widest font-black text-concrete cursor-pointer hover:text-ink transition-colors"
                      >
                        <div className="flex items-center gap-1">
                          <span>Carnet</span>
                          {renderSortIndicator('carnet')}
                        </div>
                      </th>
                      {/* Labels */}
                      <th 
                        onClick={() => handleSort('labels')}
                        className="w-[20%] px-4 py-3 text-[10px] uppercase tracking-widest font-black text-concrete cursor-pointer hover:text-ink transition-colors"
                      >
                        <div className="flex items-center gap-1">
                          <span>Labels</span>
                          {renderSortIndicator('labels')}
                        </div>
                      </th>
                      {/* Tâches */}
                      <th 
                        onClick={() => handleSort('tasks')}
                        className="w-[12%] px-4 py-3 text-[10px] uppercase tracking-widest font-black text-concrete cursor-pointer hover:text-ink transition-colors"
                      >
                        <div className="flex items-center gap-1">
                          <span>Tâches</span>
                          {renderSortIndicator('tasks')}
                        </div>
                      </th>
                      {/* Modifié */}
                      <th 
                        onClick={() => handleSort('modified')}
                        className="w-[13%] px-4 py-3 text-[10px] uppercase tracking-widest font-black text-concrete cursor-pointer hover:text-ink transition-colors"
                      >
                        <div className="flex items-center gap-1">
                          <span>Modifié</span>
                          {renderSortIndicator('modified')}
                        </div>
                      </th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-black/[0.03] dark:divide-white/[0.03]">
                    {sortedNotes.map((note) => {
                      const carnet = carnets?.find(c => c.id === note.carnetId);
                      const noteColor = carnet ? getCarnetColor(carnet) : { bg: 'bg-zinc-500/5', border: 'border-zinc-500/10', text: 'text-zinc-500' };
                      const stats = getNoteTasksStats(note.content);
                      
                      return (
                        <tr 
                          key={note.id}
                          onClick={() => setActiveNoteId(note.id)}
                          className="h-10 hover:bg-neutral-50 dark:hover:bg-white/[0.02] cursor-pointer transition-all duration-150 relative group"
                        >
                          {/* Titre */}
                          <td className="px-4 py-2 font-serif text-[13px] font-medium text-ink truncate">
                            <div className="flex items-center gap-2 truncate">
                              {note.isPinned && <Pin size={11} className="text-amber-500 fill-amber-500 shrink-0" />}
                              <span className="truncate group-hover:text-accent transition-colors">{note.title || "Note sans titre"}</span>
                            </div>
                          </td>
                          {/* Carnet */}
                          <td className="px-4 py-2">
                            {carnet ? (
                              <span className={`inline-block px-2 py-0.5 rounded-full text-[9px] font-bold tracking-wide border truncate max-w-[125px] ${noteColor.bg} ${noteColor.border} ${noteColor.text}`}>
                                {carnet.name}
                              </span>
                            ) : (
                              <span className="text-zinc-500 text-[10px]">—</span>
                            )}
                          </td>
                          {/* Labels */}
                          <td className="px-4 py-2">
                            <div className="flex items-center gap-1 flex-wrap">
                              {note.tags?.slice(0, 3).map(tag => (
                                <span 
                                  key={tag.id}
                                  className={`px-1.5 py-0.5 rounded text-[8px] font-extrabold uppercase tracking-wider border shrink-0
                                    ${tag.type === 'ai' 
                                      ? 'bg-accent/5 border-accent/15 text-accent' 
                                      : 'bg-concrete/5 border-border text-concrete'}`}
                                >
                                  {tag.label}
                                </span>
                              ))}
                              {note.tags && note.tags.length > 3 && (
                                <span className="text-[8.5px] font-mono text-concrete font-bold shrink-0 bg-neutral-100 dark:bg-neutral-800 px-1 py-0.5 rounded">
                                  +{note.tags.length - 3}
                                </span>
                              )}
                            </div>
                          </td>
                          {/* Tâches */}
                          <td className="px-4 py-2 font-mono text-[10.5px] font-bold text-ink">
                            {stats.total > 0 ? (
                              <span className={`inline-flex items-center gap-1 ${stats.completed === stats.total ? 'text-emerald-600 dark:text-emerald-400 font-extrabold' : 'text-concrete'}`}>
                                {stats.completed}/{stats.total} <span className="text-[9px] font-sans">✓</span>
                              </span>
                            ) : (
                              <span className="text-concrete/40">—</span>
                            )}
                          </td>
                          {/* Modifié */}
                          <td className="px-4 py-2 text-[10.5px] font-mono text-concrete shrink-0 truncate">
                            {getRelativeFrenchDate(note.date)}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>

              {sortedNotes.length === 0 && (
                <div className="h-64 flex flex-col items-center justify-center text-center space-y-4">
                  <p className="font-serif text-xl italic text-muted-ink">This notebook is waiting for its first vision.</p>
                  <button 
                    onClick={() => setShowNewNoteModal(true)}
                    className="px-6 py-2 border border-ink text-[13px] uppercase tracking-[0.2em] hover:bg-ink hover:text-paper transition-all cursor-pointer"
                  >
                    Begin Drawing
                  </button>
                </div>
              )}
            </div>
          ) : (
            // ================== ORIGINAL DETAILED EDITORIAL LIST VIEW ==================
            <div className="max-w-3xl space-y-16">
              {filteredNotes.map((note, index) => (
                <motion.div 
                   initial={{ opacity: 0, y: 20 }}
                   animate={{ opacity: 1, y: 0 }}
                   transition={{ delay: 0.1 * index, duration: 0.8 }}
                   key={note.id} 
                   className="space-y-4 group cursor-pointer relative"
                   onClick={() => setActiveNoteId(note.id)}
                >
                  <h2 className="text-2xl font-serif font-medium text-ink flex items-center justify-between">
                    <span className="flex items-center gap-3">
                      {note.isPinned && <Pin size={18} className="text-amber-500 fill-amber-500" />}
                      {note.title}
                    </span>
                    <div className="flex items-center gap-2">
                      <button 
                        onClick={(e) => {
                          e.stopPropagation();
                          onBrainstormNote(note);
                        }}
                        className="p-2 rounded-full opacity-0 group-hover:opacity-60 hover:opacity-100 hover:bg-ochre/10 text-ochre transition-all cursor-pointer"
                        title="Brainstorm this concept"
                      >
                        <Wind size={16} />
                      </button>
                      <button 
                        onClick={(e) => {
                          e.stopPropagation();
                          togglePin(note.id);
                        }}
                        className={`p-2 rounded-full transition-all cursor-pointer ${note.isPinned ? 'text-amber-600 bg-amber-50' : 'opacity-0 group-hover:opacity-60 hover:bg-slate-100 dark:hover:bg-white/10 text-ink'}`}
                      >
                        <Pin size={16} />
                      </button>
                      <button 
                        onClick={(e) => {
                          e.stopPropagation();
                          onDeleteNote(note.id);
                        }}
                        className="p-2 rounded-full opacity-0 group-hover:opacity-60 hover:opacity-100 hover:bg-rose-50 text-rose-500 transition-all cursor-pointer"
                      >
                        <Trash2 size={16} />
                      </button>
                      <button className="opacity-0 group-hover:opacity-40 transition-opacity">
                        <ChevronRight size={20} />
                      </button>
                    </div>
                  </h2>
                  <div className="flex flex-col md:flex-row gap-8 items-start">
                    <div className="w-full md:w-56 aspect-[4/3] bg-white/50 dark:bg-white/5 border border-border overflow-hidden rounded shadow-sm flex-shrink-0">
                      <img 
                        src={note.imageUrl || "https://images.unsplash.com/photo-1503387762-592dea58ef23"} 
                        alt={note.title} 
                        className="w-full h-full object-cover mix-blend-multiply dark:mix-blend-normal opacity-80 grayscale contrast-125 group-hover:grayscale-0 group-hover:opacity-100 transition-all duration-500"
                        referrerPolicy="no-referrer"
                      />
                    </div>
                    <div className="space-y-3">
                      <div className="flex flex-wrap gap-2 mb-2">
                        {note.tags?.map(tag => (
                          <div 
                            key={tag.id}
                            className={`px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider border flex items-center gap-1.5
                              ${tag.type === 'ai' 
                                ? 'bg-accent/5 border-accent/20 text-accent' 
                                : 'bg-concrete/5 border-border text-concrete'}`}
                          >
                            {tag.type === 'ai' && <Sparkles size={8} />}
                            {tag.label}
                          </div>
                        ))}
                      </div>
                      <p className="text-[14px] leading-relaxed text-ink/80 font-light max-w-lg text-justify line-clamp-4">
                        {note.content}
                      </p>
                      <span className="text-[11px] text-muted-ink uppercase tracking-widest font-medium">Read more</span>
                    </div>
                  </div>
                </motion.div>
              ))}
              {filteredNotes.length === 0 && (
                <div className="h-64 flex flex-col items-center justify-center text-center space-y-4">
                  <p className="font-serif text-xl italic text-muted-ink">This notebook is waiting for its first vision.</p>
                  <button 
                    onClick={() => setShowNewNoteModal(true)}
                    className="px-6 py-2 border border-ink text-[13px] uppercase tracking-[0.2em] hover:bg-ink hover:text-paper transition-all cursor-pointer"
                  >
                    Begin Drawing
                  </button>
                </div>
              )}
            </div>
          )}
        </div>

        <footer className="px-12 py-6 border-t border-ink/5 text-center mt-auto">
          <p className="text-[11px] text-muted-ink uppercase tracking-[0.2em] font-medium">
            &copy; 2024 Architectural Grid. All rights reserved.
          </p>
        </footer>
      </div>
    );
  }

  return (
    <div className="h-full flex overflow-hidden transition-all duration-500">
      <div className="flex-1 flex flex-col overflow-y-auto bg-white dark:bg-paper">
        <div className="px-6 sm:px-12 py-8 flex items-center justify-between sticky top-0 bg-white/90 dark:bg-paper/90 backdrop-blur-sm z-40 border-b border-border gap-4">
          <div className="flex items-center gap-2 sm:gap-4">
            <button 
              onClick={onOpenSidebar}
              className="lg:hidden p-2 -ml-2 text-ink hover:bg-black/5 rounded-lg transition-colors"
            >
              <Menu size={20} />
            </button>
            <button 
              onClick={() => setActiveNoteId(null)}
              className="flex items-center gap-2 text-ink hover:opacity-60 transition-opacity"
              title="Retour aux documents"
            >
              <ArrowLeft size={18} />
            </button>
          </div>
          <div className="flex items-center gap-2 sm:gap-4 overflow-x-auto no-scrollbar">
            <button 
              onClick={() => fileInputRef.current?.click()}
              className="flex items-center gap-2 px-3 py-1.5 rounded-full border border-border text-muted-ink hover:text-ink transition-all"
              title="Add attachment"
            >
              <Paperclip size={16} />
              <input 
                type="file" 
                ref={fileInputRef} 
                onChange={handleFileUpload} 
                className="hidden" 
                accept=".pdf,.docx,.txt"
              />
            </button>
            <button 
              onClick={() => onBrainstormNote(activeNote!)}
              className="p-2 rounded-full border border-ochre/30 text-ochre hover:bg-ochre/5 transition-all cursor-pointer"
              title="Brainstorm IA"
            >
              <Wind size={16} />
            </button>
            <button 
              onClick={() => onGenerateFlashcards?.(activeNote!.id)}
              disabled={isGeneratingFlashcards}
              className="p-2 rounded-full border border-accent/30 text-accent hover:bg-accent/5 transition-all disabled:opacity-50 cursor-pointer"
              title={isGeneratingFlashcards ? 'Génération...' : 'Révisions & Flashcards'}
            >
              {isGeneratingFlashcards ? (
                <div className="w-4 h-4 rounded-full border-2 border-accent border-t-transparent animate-spin" />
              ) : (
                <GraduationCap size={16} />
              )}
            </button>
            <button 
              onClick={() => {
                if (isEditing && activeNote) {
                  // Save edits
                  const updatedNote = {
                    ...activeNote,
                    title: titleInputRef.current?.value || activeNote.title,
                    content: contentTextareaRef.current?.value || activeNote.content
                  };
                  onUpdateNote?.(updatedNote);
                }
                setIsEditing(!isEditing);
              }}
              className={`p-2 rounded-full border transition-all duration-300
                ${isEditing ? 'bg-accent text-white border-accent shadow-lg shadow-accent/20' : 'border-border text-ink hover:bg-slate-50'}`}
              title={isEditing ? 'Visualiser' : 'Modifier'}
            >
              {isEditing ? <Eye size={16} /> : <Edit3 size={16} />}
            </button>
            <button 
              onClick={() => togglePin(activeNoteId!)}
              className={`p-2 rounded-full transition-all ${activeNote?.isPinned ? 'text-amber-600 bg-amber-50 dark:bg-ochre/10' : 'text-muted-ink hover:text-ink'}`}
              title={activeNote?.isPinned ? "Unpin note" : "Pin note"}
            >
              <Pin size={18} className={activeNote?.isPinned ? 'fill-amber-600' : ''} />
            </button>
            {/* Native simulated connection status indicator toggle */}
            <button 
              onClick={() => {
                window.dispatchEvent(new CustomEvent('toggle-websocket-simulate'));
              }}
              className={`p-2 rounded-full transition-all shrink-0 border cursor-pointer
                ${wsConnected 
                  ? 'bg-blue-500/5 text-blue-600 border-blue-500/10 hover:bg-rose-500/10 hover:text-rose-600 hover:border-rose-500/15' 
                  : 'bg-amber-500/5 text-amber-600 border-amber-500/10 hover:bg-blue-500/10 hover:text-blue-600 hover:border-blue-500/15'}`}
              title={wsConnected ? "WebSocket : En ligne (Cliquez pour déconnecter)" : "WebSocket : Hors ligne (Cliquez pour reconnecter)"}
            >
              <span className={`w-1.5 h-1.5 rounded-full ${wsConnected ? 'bg-blue-500 animate-pulse' : 'bg-amber-500'}`} />
            </button>
            <button 
              onClick={() => setIsAISidebarOpen(!isAISidebarOpen)}
              className={`p-2 rounded-full border transition-all duration-300
                ${isAISidebarOpen ? 'bg-ink text-paper border-ink' : 'border-border text-ink hover:bg-white/50 dark:hover:bg-white/5'}`}
              title="Assistant IA"
            >
              <Sparkles size={16} />
            </button>
            <button className="p-2 text-muted-ink hover:text-red-500 transition-colors">
              <Trash2 size={18} />
            </button>
            <button className="p-2 text-muted-ink hover:text-ink transition-colors">
              <MoreVertical size={18} />
            </button>
            <button 
              onClick={() => setIsNoteInfoOpen(!isNoteInfoOpen)}
              className={`p-2 rounded-full border transition-all duration-300 cursor-pointer shrink-0
                ${isNoteInfoOpen ? 'bg-ink text-paper border-ink dark:bg-white dark:text-ink' : 'border-border text-ink hover:bg-white/50 dark:hover:bg-white/5'}`}
              title="Informations & Versions de la note"
            >
              <PanelRight size={16} />
            </button>
          </div>
        </div>

        <div className="max-w-4xl mx-auto w-full px-12 py-16 space-y-12 relative">
          <AnimatePresence>
            {slashMenu?.isOpen && (
              <SlashMenu 
                position={{ top: slashMenu.top, left: slashMenu.left }}
                onSelect={(type) => insertCommand(type)}
                onClose={() => setSlashMenu(null)}
              />
            )}
          </AnimatePresence>

          {activeNote?.isClipped && (
            <div className="w-full relative overflow-hidden bg-cyan-500/10 dark:bg-cyan-500/5 rounded-xl border border-cyan-500/20 p-4 space-y-2">
              <div className="absolute top-0 left-0 right-0 h-[8px] bg-cyan-600/30" />
              
              <div className="flex flex-wrap items-center justify-between gap-4 text-xs pt-1.5 select-all">
                <div className="flex items-center gap-2.5 min-w-0">
                  {activeNote.clipFavicon ? (
                    <img 
                      src={activeNote.clipFavicon} 
                      alt="favicon" 
                      className="w-4.5 h-4.5 object-contain rounded bg-white p-0.5 border border-cyan-500/10"
                      onError={(e) => { (e.target as any).src = 'https://www.google.com/s2/favicons?domain=google.com'; }}
                    />
                  ) : (
                    <span className="p-1 bg-cyan-500/5 rounded"><Globe size={13} className="text-cyan-600 dark:text-cyan-400" /></span>
                  )}
                  <span className="text-[11px] font-mono text-cyan-800 dark:text-cyan-300 truncate max-w-[400px]" title={activeNote.clipSourceUrl}>
                    {activeNote.clipSourceUrl}
                  </span>
                </div>
                
                <div className="flex items-center gap-2 text-[10px] text-cyan-700/80 dark:text-cyan-400/80 font-medium">
                  <span className="bg-cyan-500/10 dark:bg-cyan-500/20 px-2 py-0.5 rounded text-[9.5px] tracking-wide uppercase font-bold text-cyan-700 dark:text-cyan-300">
                    Source web
                  </span>
                  <span>Capturé : {activeNote.clipDate || activeNote.date}</span>
                </div>
              </div>
            </div>
          )}

          <div className="space-y-4">
            <div className="flex items-center gap-3 text-[12px] text-muted-ink uppercase tracking-[.25em] font-bold flex-wrap">
              <span className="text-accent">{activeCarnet?.name}</span>
              <ChevronRight size={10} className="text-concrete" />
              <span className="text-concrete">{activeNote?.date}</span>
              {activeNote?.isClipped && (
                <>
                  <ChevronRight size={10} className="text-concrete" />
                  <span className="text-cyan-600 dark:text-cyan-400 bg-cyan-500/10 px-1.5 py-0.5 rounded text-[9.5px] tracking-widest">Source web</span>
                </>
              )}
            </div>
            
            {isEditing ? (
              <input 
                type="text"
                ref={titleInputRef}
                defaultValue={activeNote?.title}
                className="w-full text-5xl md:text-6xl font-serif font-bold text-ink leading-tight bg-transparent border-none outline-none focus:ring-0 placeholder:text-concrete/20"
                placeholder="Titre de la note..."
              />
            ) : (
              <h1 className="text-5xl md:text-6xl font-serif font-bold text-ink leading-tight">
                {activeNote?.title}
              </h1>
            )}

            <div className="flex flex-wrap gap-2 pt-2">
              {activeNote?.tags?.map(tag => (
                <div 
                  key={tag.id}
                  className={`px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-widest border flex items-center gap-2
                    ${tag.type === 'ai' 
                      ? 'bg-accent/5 border-accent/20 text-accent' 
                      : 'bg-paper border-border text-concrete'}`}
                >
                  {tag.type === 'ai' && <Sparkles size={12} />}
                  {tag.label}
                  {tag.type === 'ai' && (
                    <div className="w-1.5 h-1.5 rounded-full bg-accent animate-pulse" />
                  )}
                </div>
              ))}
            </div>

            {/* Flashcards alert state indicator (E) */}
            {activeNote && noteFlashcards.length > 0 && (
              <div id="note-flashcard-alert" className="flex flex-wrap items-center gap-4 text-xs font-semibold bg-sage/10 text-sage dark:bg-sage/5 border border-sage/25 rounded-2xl px-4 py-2.5 w-fit mt-3 select-none">
                <div className="flex items-center gap-1.5">
                  <GraduationCap size={15} className="text-sage" />
                  <span>{noteFlashcards.length} flashcards générées · Prochain rappel : {nextRecallText}</span>
                </div>
                <button 
                  onClick={() => onTriggerReviewDeck?.(activeNote.id)}
                  className="text-accent hover:underline font-bold text-xs shrink-0 cursor-pointer"
                >
                  Réviser maintenant
                </button>
              </div>
            )}
          </div>

          <div className="aspect-[16/9] w-full bg-slate-100 dark:bg-white/5 rounded-xl overflow-hidden shadow-2xl relative group/img">
            <img 
              src={activeNote?.imageUrl} 
              alt={activeNote?.title} 
              className="w-full h-full object-cover transition-transform duration-700 group-hover/img:scale-105"
              referrerPolicy="no-referrer"
            />
            <div className="absolute inset-0 bg-gradient-to-t from-ink/20 to-transparent pointer-events-none" />
          </div>

          <div className="max-w-2xl mx-auto w-full space-y-8 pb-40">
            {activeNote?.attachments && activeNote.attachments.length > 0 && (
              <div className="space-y-4">
                <h4 className="text-[10px] uppercase font-bold tracking-widest text-concrete border-b border-border pb-2">Pièces jointes ({activeNote.attachments.length})</h4>
                <div className="grid grid-cols-2 gap-4">
                  {activeNote.attachments.map(att => (
                    <div key={att.id} className="p-3 border border-border rounded-xl bg-white/40 flex items-center justify-between group">
                      <div className="flex items-center gap-3">
                        <div className="p-2 bg-accent/10 text-accent rounded-lg">
                          <FileText size={16} />
                        </div>
                        <div className="overflow-hidden">
                          <p className="text-xs font-bold text-ink truncate w-32">{att.name}</p>
                          <p className="text-[9px] uppercase font-medium text-concrete">{att.type}</p>
                        </div>
                      </div>
                      <div className="flex items-center gap-1">
                        {isAnalyzing === att.id ? (
                          <Loader2 size={14} className="animate-spin text-accent" />
                        ) : (
                          <button 
                            onClick={() => setActiveDocQnA(att)}
                            className="p-2 hover:bg-accent/10 text-accent rounded-lg transition-colors opacity-0 group-hover:opacity-100"
                            title="Converser avec ce document"
                          >
                            <MessageSquare size={14} />
                          </button>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {activeNote && (
              <ModernBlockNoteEditor 
                note={activeNote} 
                onUpdateNote={onUpdateNote || (() => {})} 
                allNotes={allNotes}
              />
            )}

            <div className="space-y-12 mt-12">
              {/* Memory Echo Section */}
              {memoryEchoBlock && (
                <div className="p-6 rounded-2xl bg-gradient-to-br from-indigo-500/[0.03] via-transparent to-transparent border border-indigo-500/10 shadow-sm space-y-4">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <Sparkles size={14} className="text-indigo-500 animate-pulse" />
                      <span className="text-[10px] uppercase font-bold tracking-widest text-indigo-500">Memory Echo (Affinité Sémantique)</span>
                    </div>
                    <span className="text-[10px] font-mono font-bold text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-950/40 px-2 py-0.5 rounded">
                      92% affinité sémétrique
                    </span>
                  </div>
                  
                  <p className="text-sm font-serif italic text-ink/80 leading-relaxed pl-3 border-l pb-1 border-indigo-500/20">
                    « {memoryEchoBlock.text.substring(0, 150)}... »
                  </p>
                  
                  <div className="flex items-center justify-between text-[11px] pt-1 border-t border-black/[0.03] dark:border-white/[0.02] flex-wrap gap-2">
                    <span className="text-concrete">Passage détecté dans : <strong className="text-ink/60 font-semibold">{memoryEchoBlock.noteTitle}</strong></span>
                    <div className="flex items-center gap-3">
                      <button
                        onClick={() => setActiveNoteId(memoryEchoBlock.noteId)}
                        className="text-concrete hover:text-ink font-bold transition-all hover:underline"
                      >
                        Voir la connexion
                      </button>
                      <button
                        onClick={() => {
                          setPrefilledBlock({ noteId: memoryEchoBlock.noteId, blockIndex: memoryEchoBlock.blockIndex });
                          setIsPickerOpen(true);
                        }}
                        className="flex items-center gap-1.5 text-blue-600 dark:text-blue-400 font-extrabold hover:underline"
                      >
                        <Link2 size={12} />
                        Embedder ce passage
                      </button>
                    </div>
                  </div>
                </div>
              )}

              {/* Backlinks panel */}
              {backlinks.length > 0 && (
                <div className="p-6 rounded-2xl bg-[#FCFBFA] dark:bg-zinc-900/[0.15] border border-[#D5D2CD]/40 dark:border-neutral-800/40 space-y-4 shadow-[0_1px_2px_rgba(0,0,0,0.01)]">
                  <div className="flex items-center gap-2 pb-2 border-b border-black/[0.03] dark:border-white/[0.02]">
                    <div className="w-1.5 h-3 bg-accent rounded-full animate-pulse" />
                    <span className="text-[10px] uppercase font-bold tracking-widest text-concrete">Rétroliens &amp; Intégrations Sémantiques</span>
                  </div>
                  
                  <div className="space-y-3">
                    <span className="text-xs font-semibold text-ink/80 block">Embeddé comme Living Block dans {backlinks.length} note{backlinks.length > 1 ? 's' : ''} :</span>
                    <div className="grid grid-cols-1 gap-2.5">
                      {backlinks.map(({ note, accessedAt }) => (
                        <div 
                          key={note.id}
                          onClick={() => setActiveNoteId(note.id)}
                          className="p-3.5 bg-white dark:bg-zinc-800/20 border border-black/[0.04] dark:border-white/[0.04] rounded-xl hover:bg-black/[0.02] dark:hover:bg-white/[0.02] hover:border-accent/20 transition-all cursor-pointer flex items-center justify-between pr-4 group"
                        >
                          <div className="flex items-center gap-3">
                            <Link2 size={13} className="text-blue-500 shrink-0" />
                            <div className="min-w-0">
                              <span className="text-xs font-bold text-ink dark:text-dark-ink truncate block group-hover:text-accent transition-colors">
                                {note.title || "Note sans titre"}
                              </span>
                              <span className="text-[9.5px] font-mono uppercase tracking-wider text-concrete">
                                Carnet : {carnets?.find(c => c.id === note.carnetId)?.name || "Général"}
                              </span>
                            </div>
                          </div>
                          <span className="text-[10px] text-concrete font-medium bg-black/[0.03] dark:bg-white/5 py-0.5 px-3 rounded-full">
                            Accès : {accessedAt}
                          </span>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              )}
            </div>

          </div>
        </div>
      </div>
      
      {/* Document Q&A Overlay */}
      <AnimatePresence>
        {activeDocQnA && (
          <div className="fixed inset-0 z-[100] flex items-center justify-center p-8 bg-ink/30 backdrop-blur-md">
            <motion.div 
              initial={{ scale: 0.95, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              exit={{ scale: 0.95, opacity: 0 }}
              className="w-full max-w-4xl h-full bg-paper dark:bg-dark-paper border border-border rounded-[32px] shadow-2xl flex overflow-hidden"
            >
              {/* Document Preview (Mock) */}
              <div className="flex-1 bg-slate-50 dark:bg-black/20 border-r border-border p-12 overflow-y-auto custom-scrollbar">
                <div className="flex items-center gap-4 mb-8">
                  <div className="p-3 bg-accent text-white rounded-xl">
                    <FileText size={24} />
                  </div>
                  <div>
                    <h3 className="text-xl font-serif font-bold text-ink">{activeDocQnA.name}</h3>
                    <p className="text-[10px] uppercase font-bold tracking-widest text-concrete">DOCUMENT SOURCE ANALYSÉ</p>
                  </div>
                </div>
                <div className="prose prose-sm prose-slate dark:prose-invert max-w-none">
                  <div className="whitespace-pre-wrap font-serif text-lg leading-relaxed text-ink/80 italic">
                    {activeDocQnA.content || "Analyse du contenu en cours..."}
                  </div>
                </div>
              </div>

              {/* Chat Side */}
              <div className="w-[400px] flex flex-col bg-white dark:bg-paper">
                <div className="p-6 border-b border-border flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <Sparkles size={18} className="text-accent" />
                    <h4 className="text-xs font-bold uppercase tracking-widest text-ink">Expert Document</h4>
                  </div>
                  <button onClick={() => setActiveDocQnA(null)} className="p-2 hover:bg-slate-50 dark:hover:bg-white/5 rounded-full text-concrete">
                    <X size={20} />
                  </button>
                </div>
                
                <div className="flex-1 p-6 overflow-y-auto space-y-6">
                  <div className="p-4 bg-accent/5 border border-accent/10 rounded-2xl">
                    <p className="text-xs text-accent font-medium leading-relaxed">
                      Bonjour ! J'ai analysé ce document. Posez-moi n'importe quelle question sur son contenu, les chiffres clés ou les concepts abordés.
                    </p>
                  </div>
                </div>

                <div className="p-6 border-t border-border">
                  <div className="relative">
                    <textarea 
                      placeholder="Poser une question au document..."
                      className="w-full bg-slate-50 dark:bg-black/20 border border-border rounded-xl p-4 pr-12 text-xs outline-none focus:border-accent transition-all resize-none"
                      rows={3}
                    />
                    <button className="absolute right-3 bottom-3 p-2 bg-accent text-white rounded-lg shadow-lg shadow-accent/10">
                      <Sparkles size={16} />
                    </button>
                  </div>
                </div>
              </div>
            </motion.div>
          </div>
        )}
      </AnimatePresence>

      <BlockPicker
        isOpen={isPickerOpen}
        onClose={() => setIsPickerOpen(false)}
        currentNote={activeNote}
        allNotes={allNotes}
        carnets={carnets}
        onSelectBlock={handleSelectBlock}
        prefilledBlock={prefilledBlock}
      />

      <NotebookInfoSidebar 
        isOpen={isNoteInfoOpen}
        onClose={() => setIsNoteInfoOpen(false)}
        activeNote={activeNote}
        notes={allNotes}
        carnets={carnets}
        onOpenNote={setActiveNoteId}
        onUpdateNote={onUpdateNote}
      />
    </div>
  );
};
