'use client'

import { useState, useRef, useEffect } from 'react'
import { Note, CheckItem, NOTE_COLORS, NoteColor, LinkMetadata } from '@/lib/types'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
  DropdownMenuSub,
  DropdownMenuSubTrigger,
  DropdownMenuSubContent,
} from '@/components/ui/dropdown-menu'
import { X, Plus, Palette, Image as ImageIcon, Bell, FileText, Eye, Link as LinkIcon, Sparkles, Maximize2, Copy, Wand2, LogOut } from 'lucide-react'
import { updateNote, createNote, cleanupOrphanedImages, leaveSharedNote } from '@/app/actions/notes'
import { fetchLinkMetadata } from '@/app/actions/scrape'
import { cn } from '@/lib/utils'
import { toast } from 'sonner'
import { MarkdownContent } from './markdown-content'
import { LabelManager } from './label-manager'
import { LabelBadge } from './label-badge'
import { ReminderDialog } from './reminder-dialog'
import { EditorImages } from './editor-images'
import { useAutoTagging } from '@/hooks/use-auto-tagging'
import { GhostTags } from './ghost-tags'
import { TitleSuggestions } from './title-suggestions'
import type { TitleSuggestion } from '@/hooks/use-title-suggestions'
import { EditorConnectionsSection } from './editor-connections-section'
import { ComparisonModal } from './comparison-modal'
import { FusionModal } from './fusion-modal'
import { AIAssistantActionBar } from './ai-assistant-action-bar'
import { useLabels } from '@/context/LabelContext'
import { useNoteRefresh } from '@/context/NoteRefreshContext'
import { NoteSize } from '@/lib/types'
import { Badge } from '@/components/ui/badge'
import { useLanguage } from '@/lib/i18n'

interface NoteEditorProps {
  note: Note
  readOnly?: boolean
  onClose: () => void
}

export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps) {
  const { labels: globalLabels, addLabel, refreshLabels, setNotebookId: setContextNotebookId } = useLabels()
  const { triggerRefresh } = useNoteRefresh()
  const { t } = useLanguage()
  const [title, setTitle] = useState(note.title || '')
  const [content, setContent] = useState(note.content)
  const [checkItems, setCheckItems] = useState<CheckItem[]>(note.checkItems || [])
  const [labels, setLabels] = useState<string[]>(note.labels || [])
  const [images, setImages] = useState<string[]>(note.images || [])
  const [links, setLinks] = useState<LinkMetadata[]>(note.links || [])
  const [newLabel, setNewLabel] = useState('')
  const [color, setColor] = useState(note.color)
  const [size, setSize] = useState<NoteSize>(note.size || 'small')
  const [isSaving, setIsSaving] = useState(false)
  const [removedImageUrls, setRemovedImageUrls] = useState<string[]>([])
  const [isMarkdown, setIsMarkdown] = useState(note.isMarkdown || false)
  const [showMarkdownPreview, setShowMarkdownPreview] = useState(note.isMarkdown || false)
  const fileInputRef = useRef<HTMLInputElement>(null)

  // Update context notebookId when note changes
  useEffect(() => {
    setContextNotebookId(note.notebookId || null)
  }, [note.notebookId, setContextNotebookId])

  // Auto-tagging hook - use local state for live suggestions as user types
  const { suggestions, isAnalyzing } = useAutoTagging({
    content: note.type === 'text' ? content : '',
    notebookId: note.notebookId,
    enabled: note.type === 'text'
  })

  // Reminder state
  const [showReminderDialog, setShowReminderDialog] = useState(false)
  const [currentReminder, setCurrentReminder] = useState<Date | null>(
    note.reminder ? new Date(note.reminder as unknown as string) : null
  )

  // Link state
  const [showLinkDialog, setShowLinkDialog] = useState(false)
  const [linkUrl, setLinkUrl] = useState('')

  // Title suggestions state
  const [titleSuggestions, setTitleSuggestions] = useState<TitleSuggestion[]>([])
  const [isGeneratingTitles, setIsGeneratingTitles] = useState(false)

  // Reformulation state
  const [isReformulating, setIsReformulating] = useState(false)
  const [reformulationModal, setReformulationModal] = useState<{
    originalText: string
    reformulatedText: string
    option: string
  } | null>(null)

  // AI processing state for ActionBar
  const [isProcessingAI, setIsProcessingAI] = useState(false)

  // Memory Echo Connections state
  const [comparisonNotes, setComparisonNotes] = useState<Array<Partial<Note>>>([])
  const [fusionNotes, setFusionNotes] = useState<Array<Partial<Note>>>([])

  // Tags dismissed by the user for this session
  const [dismissedTags, setDismissedTags] = useState<string[]>([])

  const colorClasses = NOTE_COLORS[color as NoteColor] || NOTE_COLORS.default

  const handleSelectGhostTag = async (tag: string) => {
    // Case-insensitive check
    const tagExists = labels.some(l => l.toLowerCase() === tag.toLowerCase())
    
    if (!tagExists) {
      setLabels(prev => [...prev, tag])
      
      // Create the label globally if it doesn't exist
      const globalExists = globalLabels.some(l => l.name.toLowerCase() === tag.toLowerCase())
      if (!globalExists) {
        try {
          await addLabel(tag)
        } catch (err) {
          console.error('Error creating auto-label:', err)
        }
      }
      toast.success(t('ai.tagAdded', { tag }))
    }
  }

  const handleDismissGhostTag = (tag: string) => {
    setDismissedTags(prev => [...prev, tag])
  }

  // Filter suggestions to exclude dismissed ones
  // and those already present on the note
  const existingLabelsLower = (note.labels || []).map((l) => l.toLowerCase())
  const filteredSuggestions = suggestions.filter(s => {
    if (!s || !s.tag) return false
    return !dismissedTags.includes(s.tag) && !existingLabelsLower.includes(s.tag.toLowerCase())
  })

  const handleImageUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    if (!files) return

    for (const file of Array.from(files)) {
      const formData = new FormData()
      formData.append('file', file)

      try {
        const response = await fetch('/api/upload', {
          method: 'POST',
          body: formData,
        })

        if (!response.ok) throw new Error('Upload failed')

        const data = await response.json()
        setImages(prev => [...prev, data.url])
      } catch (error) {
        console.error('Upload error:', error)
        toast.error(t('notes.uploadFailed', { filename: file.name }))
      }
    }
  }

  const handleRemoveImage = (index: number) => {
    const removedUrl = images[index]
    setImages(images.filter((_, i) => i !== index))
    // Track removed images for cleanup on save
    if (removedUrl) {
      setRemovedImageUrls(prev => [...prev, removedUrl])
    }
  }

  const handleAddLink = async () => {
    if (!linkUrl) return
    
    setShowLinkDialog(false)
    
    try {
      const metadata = await fetchLinkMetadata(linkUrl)
      if (metadata) {
        setLinks(prev => [...prev, metadata])
        toast.success(t('notes.linkAdded'))
      } else {
        toast.warning(t('notes.linkMetadataFailed'))
        setLinks(prev => [...prev, { url: linkUrl, title: linkUrl }])
      }
    } catch (error) {
      console.error('Failed to add link:', error)
      toast.error(t('notes.linkAddFailed'))
    } finally {
      setLinkUrl('')
    }
  }

  const handleRemoveLink = (index: number) => {
    setLinks(links.filter((_, i) => i !== index))
  }

  const handleGenerateTitles = async () => {
    // Combine content and link metadata for AI
    const fullContent = [
      content,
      ...links.map(l => `${l.title || ''} ${l.description || ''}`)
    ].join(' ').trim()

    const wordCount = fullContent.split(/\s+/).filter(word => word.length > 0).length

    if (wordCount < 10) {
      toast.error(t('ai.titleGenerationMinWords', { count: wordCount }))
      return
    }

    setIsGeneratingTitles(true)
    try {
      const response = await fetch('/api/ai/title-suggestions', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content: fullContent }),
      })

      if (!response.ok) {
        const errorData = await response.json()
        throw new Error(errorData.error || t('ai.titleGenerationError'))
      }

      const data = await response.json()
      setTitleSuggestions(data.suggestions || [])
      toast.success(t('ai.titlesGenerated', { count: data.suggestions.length }))
    } catch (error: any) {
      console.error('Error generating titles:', error)
      toast.error(error.message || t('ai.titleGenerationFailed'))
    } finally {
      setIsGeneratingTitles(false)
    }
  }

  const handleSelectTitle = (title: string) => {
    setTitle(title)
    setTitleSuggestions([])
    toast.success(t('ai.titleApplied'))
  }

  const handleReformulate = async (option: 'clarify' | 'shorten' | 'improve') => {
    // Get selected text or full content
    const selectedText = window.getSelection()?.toString()

    if (!selectedText && (!content || content.trim().length === 0)) {
      toast.error(t('ai.reformulationNoText'))
      return
    }

    // If selection is too short, use full content instead
    let textToReformulate: string
    if (selectedText && selectedText.trim().split(/\s+/).filter(word => word.length > 0).length >= 10) {
      textToReformulate = selectedText
    } else {
      textToReformulate = content
      if (selectedText) {
        toast.info(t('ai.reformulationSelectionTooShort'))
      }
    }

    const wordCount = textToReformulate.trim().split(/\s+/).filter(word => word.length > 0).length

    if (wordCount < 10) {
      toast.error(t('ai.reformulationMinWords', { count: wordCount }))
      return
    }

    if (wordCount > 500) {
      toast.error(t('ai.reformulationMaxWords'))
      return
    }

    setIsReformulating(true)
    try {
      const response = await fetch('/api/ai/reformulate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          text: textToReformulate,
          option: option
        }),
      })

      if (!response.ok) {
        const errorData = await response.json()
        throw new Error(errorData.error || t('ai.reformulationError'))
      }

      const data = await response.json()

      // Show reformulation modal
      setReformulationModal({
        originalText: data.originalText,
        reformulatedText: data.reformulatedText,
        option: data.option
      })
    } catch (error: any) {
      console.error('Error reformulating:', error)
      toast.error(error.message || t('ai.reformulationFailed'))
    } finally {
      setIsReformulating(false)
    }
  }

  // Simplified AI handlers for ActionBar (direct content update)
  const handleClarifyDirect = async () => {
    const wordCount = content.split(/\s+/).filter(w => w.length > 0).length
    if (!content || wordCount < 10) {
      toast.error(t('ai.reformulationMinWords', { count: wordCount }))
      return
    }

    setIsProcessingAI(true)
    try {
      const response = await fetch('/api/ai/reformulate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: content, option: 'clarify' })
      })
      const data = await response.json()
      if (!response.ok) throw new Error(data.error || t('notes.clarifyFailed'))
      setContent(data.reformulatedText || data.text)
      toast.success(t('ai.reformulationApplied'))
    } catch (error) {
      console.error('Clarify error:', error)
      toast.error(t('notes.clarifyFailed'))
    } finally {
      setIsProcessingAI(false)
    }
  }

  const handleShortenDirect = async () => {
    const wordCount = content.split(/\s+/).filter(w => w.length > 0).length
    if (!content || wordCount < 10) {
      toast.error(t('ai.reformulationMinWords', { count: wordCount }))
      return
    }

    setIsProcessingAI(true)
    try {
      const response = await fetch('/api/ai/reformulate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: content, option: 'shorten' })
      })
      const data = await response.json()
      if (!response.ok) throw new Error(data.error || t('notes.shortenFailed'))
      setContent(data.reformulatedText || data.text)
      toast.success(t('ai.reformulationApplied'))
    } catch (error) {
      console.error('Shorten error:', error)
      toast.error(t('notes.shortenFailed'))
    } finally {
      setIsProcessingAI(false)
    }
  }

  const handleImproveDirect = async () => {
    const wordCount = content.split(/\s+/).filter(w => w.length > 0).length
    if (!content || wordCount < 10) {
      toast.error(t('ai.reformulationMinWords', { count: wordCount }))
      return
    }

    setIsProcessingAI(true)
    try {
      const response = await fetch('/api/ai/reformulate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: content, option: 'improve' })
      })
      const data = await response.json()
      if (!response.ok) throw new Error(data.error || t('notes.improveFailed'))
      setContent(data.reformulatedText || data.text)
      toast.success(t('ai.reformulationApplied'))
    } catch (error) {
      console.error('Improve error:', error)
      toast.error(t('notes.improveFailed'))
    } finally {
      setIsProcessingAI(false)
    }
  }

  const handleTransformMarkdown = async () => {
    const wordCount = content.split(/\s+/).filter(w => w.length > 0).length
    if (!content || wordCount < 10) {
      toast.error(t('ai.reformulationMinWords', { count: wordCount }))
      return
    }

    if (wordCount > 500) {
      toast.error(t('ai.reformulationMaxWords'))
      return
    }

    setIsProcessingAI(true)
    try {
      const response = await fetch('/api/ai/transform-markdown', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: content })
      })
      const data = await response.json()
      if (!response.ok) throw new Error(data.error || t('notes.transformFailed'))

      // Set the transformed markdown content and enable markdown mode
      setContent(data.transformedText)
      setIsMarkdown(true)
      setShowMarkdownPreview(false)

      toast.success(t('ai.transformSuccess'))
    } catch (error) {
      console.error('Transform to markdown error:', error)
      toast.error(t('ai.transformError'))
    } finally {
      setIsProcessingAI(false)
    }
  }

  const handleApplyRefactor = () => {
    if (!reformulationModal) return

    // If selected text exists, replace it
    const selectedText = window.getSelection()?.toString()
    if (selectedText) {
      // For now, replace full content (TODO: improve to replace selection only)
      setContent(reformulationModal.reformulatedText)
    } else {
      setContent(reformulationModal.reformulatedText)
    }

    setReformulationModal(null)
    toast.success(t('ai.reformulationApplied'))
  }

  const handleReminderSave = async (date: Date) => {
    if (date < new Date()) {
      toast.error(t('notes.reminderPastError'))
      return
    }
    setCurrentReminder(date)
    try {
      await updateNote(note.id, { reminder: date })
      toast.success(t('notes.reminderSet', { datetime: date.toLocaleString() }))
    } catch {
      toast.error(t('notebook.savingReminder'))
    }
  }

  const handleRemoveReminder = async () => {
    setCurrentReminder(null)
    try {
      await updateNote(note.id, { reminder: null })
      toast.success(t('notes.reminderRemoved'))
    } catch {
      toast.error(t('notebook.removingReminder'))
    }
  }

  const handleSave = async () => {
    setIsSaving(true)
    try {
      await updateNote(note.id, {
        title: title.trim() || null,
        content: note.type === 'text' ? content : '',
        checkItems: note.type === 'checklist' ? checkItems : null,
        labels,
        images,
        links,
        color,
        reminder: currentReminder,
        isMarkdown,
        size,
      })

      // Clean up removed image files from disk (best-effort, don't block save)
      if (removedImageUrls.length > 0) {
        cleanupOrphanedImages(removedImageUrls, note.id).catch(() => {})
      }

      // Refresh global labels to reflect any deletions (orphans)
      await refreshLabels()

      // Refresh the notes list
      triggerRefresh()

      onClose()
    } catch (error) {
      console.error('Failed to save note:', error)
    } finally {
      setIsSaving(false)
    }
  }

  const handleCheckItem = (id: string) => {
    setCheckItems(items =>
      items.map(item =>
        item.id === id ? { ...item, checked: !item.checked } : item
      )
    )
  }

  const handleUpdateCheckItem = (id: string, text: string) => {
    setCheckItems(items =>
      items.map(item => (item.id === id ? { ...item, text } : item))
    )
  }

  const handleAddCheckItem = () => {
    setCheckItems([
      ...checkItems,
      { id: Date.now().toString(), text: '', checked: false },
    ])
  }

  const handleRemoveCheckItem = (id: string) => {
    setCheckItems(items => items.filter(item => item.id !== id))
  }

  const handleRemoveLabel = (label: string) => {
    setLabels(labels.filter(l => l !== label))
  }

  const handleMakeCopy = async () => {
    try {
      const newNote = await createNote({
        title: `${title || t('notes.untitled')} (${t('notes.copy')})`,
        content: content,
        color: color,
        type: note.type,
        checkItems: checkItems,
        labels: labels,
        images: images,
        links: links,
        isMarkdown: isMarkdown,
        size: size,
      })
      toast.success(t('notes.copySuccess'))
      triggerRefresh()
      onClose()
    } catch (error) {
      console.error('Failed to copy note:', error)
      toast.error(t('notes.copyFailed'))
    }
  }

  return (
    <Dialog open={true} onOpenChange={onClose}>
      <DialogContent
        className={cn(
          '!max-w-[min(95vw,1600px)] max-h-[90vh] overflow-y-auto',
          colorClasses.bg
        )}
      >
        <DialogHeader>
          <DialogTitle className="sr-only">{t('notes.edit')}</DialogTitle>
          <div className="flex items-center justify-between">
            <h2 className="text-lg font-semibold">{readOnly ? t('notes.view') : t('notes.edit')}</h2>
            {readOnly && (
              <Badge variant="secondary" className="bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-foreground">
                {t('notes.readOnly')}
              </Badge>
            )}
          </div>
        </DialogHeader>

        <div className="space-y-4">
          {/* Title */}
          <div className="relative">
            <Input
              placeholder={t('notes.titlePlaceholder')}
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              disabled={readOnly}
              className={cn(
                "text-lg font-semibold border-0 focus-visible:ring-0 px-0 bg-transparent pr-10",
                readOnly && "cursor-default"
              )}
            />
            <button
              onClick={handleGenerateTitles}
              disabled={isGeneratingTitles || readOnly}
              className="absolute right-0 top-1/2 -translate-y-1/2 p-1 hover:bg-purple-100 dark:hover:bg-purple-900 rounded transition-colors"
              title={isGeneratingTitles ? t('ai.titleGenerating') : t('ai.titleGenerateWithAI')}
            >
              {isGeneratingTitles ? (
                <div className="w-4 h-4 border-2 border-purple-500 border-t-transparent rounded-full animate-spin" />
              ) : (
                <Sparkles className="w-4 h-4 text-purple-600 hover:text-purple-700 dark:text-purple-400" />
              )}
            </button>
          </div>

          {/* Title Suggestions */}
          {!readOnly && titleSuggestions.length > 0 && (
            <TitleSuggestions
              suggestions={titleSuggestions}
              onSelect={handleSelectTitle}
              onDismiss={() => setTitleSuggestions([])}
            />
          )}

          {/* Images */}
          <EditorImages images={images} onRemove={handleRemoveImage} />

          {/* Link Previews */}
          {links.length > 0 && (
            <div className="flex flex-col gap-2">
              {links.map((link, idx) => (
                <div key={idx} className="relative group border rounded-lg overflow-hidden bg-white/50 dark:bg-black/20 flex">
                  {link.imageUrl && (
                    <div className="w-24 h-24 flex-shrink-0 bg-cover bg-center" style={{ backgroundImage: `url(${link.imageUrl})` }} />
                  )}
                  <div className="p-2 flex-1 min-w-0 flex flex-col justify-center">
                    <h4 className="font-medium text-sm truncate">{link.title || link.url}</h4>
                    {link.description && <p className="text-xs text-gray-500 truncate">{link.description}</p>}
                    <a href={link.url} target="_blank" rel="noopener noreferrer" className="text-xs text-primary truncate hover:underline block mt-1">
                      {new URL(link.url).hostname}
                    </a>
                  </div>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="absolute top-1 right-1 h-6 w-6 p-0 bg-white/50 hover:bg-white opacity-0 group-hover:opacity-100 transition-opacity rounded-full"
                    onClick={() => handleRemoveLink(idx)}
                  >
                    <X className="h-3 w-3" />
                  </Button>
                </div>
              ))}
            </div>
          )}

          {/* Content or Checklist */}
          {note.type === 'text' ? (
            <div className="space-y-2">
              {/* Markdown controls */}
              <div className="flex items-center justify-between gap-2 pb-2">
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    setIsMarkdown(!isMarkdown)
                    if (isMarkdown) setShowMarkdownPreview(false)
                  }}
                  className={cn("h-7 text-xs", isMarkdown && "text-primary")}
                >
                  <FileText className="h-3 w-3 mr-1" />
                  {isMarkdown ? t('notes.markdownOn') : t('notes.markdownOff')}
                </Button>

                {isMarkdown && (
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => setShowMarkdownPreview(!showMarkdownPreview)}
                    className="h-7 text-xs"
                  >
                    {showMarkdownPreview ? (
                      <>
                        <FileText className="h-3 w-3 mr-1" />
                        {t('general.edit')}
                      </>
                    ) : (
                      <>
                        <Eye className="h-3 w-3 mr-1" />
                        {t('notes.preview')}
                      </>
                    )}
                  </Button>
                )}
              </div>

              {showMarkdownPreview && isMarkdown ? (
                <MarkdownContent
                  content={content || t('notes.noContent')}
                  className="min-h-[200px] p-3 rounded-md border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50"
                />
              ) : (
                <Textarea
                  placeholder={isMarkdown ? t('notes.takeNoteMarkdown') : t('notes.takeNote')}
                  value={content}
                  onChange={(e) => setContent(e.target.value)}
                  disabled={readOnly}
                  className={cn(
                    "min-h-[200px] border-0 focus-visible:ring-0 px-0 bg-transparent resize-none",
                    readOnly && "cursor-default"
                  )}
                />
              )}
              
              {/* AI Auto-tagging Suggestions */}
              <GhostTags
                suggestions={filteredSuggestions}
                addedTags={labels}
                isAnalyzing={isAnalyzing}
                onSelectTag={handleSelectGhostTag}
                onDismissTag={handleDismissGhostTag}
              />

              {/* AI Assistant ActionBar */}
              {!readOnly && (
                <AIAssistantActionBar
                  onClarify={handleClarifyDirect}
                  onShorten={handleShortenDirect}
                  onImprove={handleImproveDirect}
                  onTransformMarkdown={handleTransformMarkdown}
                  isMarkdownMode={isMarkdown}
                  disabled={isProcessingAI || !content}
                  className="mt-3"
                />
              )}
            </div>
          ) : (
            <div className="space-y-2">
              {checkItems.map((item) => (
                <div key={item.id} className="flex items-start gap-2 group">
                  <Checkbox
                    checked={item.checked}
                    onCheckedChange={() => handleCheckItem(item.id)}
                    className="mt-2"
                  />
                  <Input
                    value={item.text}
                    onChange={(e) => handleUpdateCheckItem(item.id, e.target.value)}
                    placeholder={t('notes.listItem')}
                    className="flex-1 border-0 focus-visible:ring-0 px-0 bg-transparent"
                  />
                  <Button
                    variant="ghost"
                    size="sm"
                    className="opacity-0 group-hover:opacity-100 h-8 w-8 p-0"
                    onClick={() => handleRemoveCheckItem(item.id)}
                  >
                    <X className="h-4 w-4" />
                  </Button>
                </div>
              ))}
              <Button
                variant="ghost"
                size="sm"
                onClick={handleAddCheckItem}
                className="text-gray-600 dark:text-gray-400"
              >
                <Plus className="h-4 w-4 mr-1" />
                {t('notes.addItem')}
              </Button>
            </div>
          )}

          {/* Labels */}
          {labels.length > 0 && (
            <div className="flex flex-wrap gap-2">
              {labels.map((label) => (
                <LabelBadge
                  key={label}
                  label={label}
                  onRemove={() => handleRemoveLabel(label)}
                />
              ))}
            </div>
          )}

          {/* Memory Echo Connections Section */}
          {!readOnly && (
          <EditorConnectionsSection
            noteId={note.id}
            onOpenNote={(noteId) => {
              // Close current editor and reload page with the selected note
              onClose()
              window.location.href = `/?note=${noteId}`
            }}
            onCompareNotes={(noteIds) => {
              // Note: noteIds already includes current note
              // Fetch all notes for comparison
              Promise.all(noteIds.map(async (id) => {
                try {
                  const res = await fetch(`/api/notes/${id}`)
                  if (!res.ok) {
                    console.error(`Failed to fetch note ${id}`)
                    return null
                  }
                  const data = await res.json()
                  if (data.success && data.data) {
                    return data.data
                  }
                  return null
                } catch (error) {
                  console.error(`Error fetching note ${id}:`, error)
                  return null
                }
              }))
                .then(notes => notes.filter((n: any) => n !== null) as Array<Partial<Note>>)
                .then(fetchedNotes => {
                  setComparisonNotes(fetchedNotes)
                })
            }}
            onMergeNotes={async (noteIds) => {
              // Fetch notes for fusion (noteIds already includes current note)
              const fetchedNotes = await Promise.all(noteIds.map(async (id) => {
                try {
                  const res = await fetch(`/api/notes/${id}`)
                  if (!res.ok) {
                    console.error(`Failed to fetch note ${id}`)
                    return null
                  }
                  const data = await res.json()
                  if (data.success && data.data) {
                    return data.data
                  }
                  return null
                } catch (error) {
                  console.error(`Error fetching note ${id}:`, error)
                  return null
                }
              }))
              // Filter out nulls
              setFusionNotes(fetchedNotes.filter((n: any) => n !== null) as Array<Partial<Note>>)
            }}
          />
          )}

          {/* Toolbar */}
          <div className="flex items-center justify-between pt-4 border-t">
            <div className="flex items-center gap-2">
              {!readOnly && (
                <>
                  {/* Reminder Button */}
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => setShowReminderDialog(true)}
                    title={t('notes.setReminder')}
                    className={currentReminder ? "text-primary" : ""}
                  >
                    <Bell className="h-4 w-4" />
                  </Button>

                  {/* Add Image Button */}
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => fileInputRef.current?.click()}
                    title={t('notes.addImage')}
                  >
                    <ImageIcon className="h-4 w-4" />
                  </Button>

                  {/* Add Link Button */}
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => setShowLinkDialog(true)}
                    title={t('notes.addLink')}
                  >
                    <LinkIcon className="h-4 w-4" />
                  </Button>

                  {/* AI Assistant Button */}
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Button
                        variant="ghost"
                        size="sm"
                        title={t('ai.assistant')}
                        className="text-purple-600 hover:text-purple-700 dark:text-purple-400"
                      >
                        <Wand2 className="h-4 w-4" />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent align="end">
                      <DropdownMenuItem onClick={handleGenerateTitles} disabled={isGeneratingTitles}>
                        <Sparkles className="h-4 w-4 mr-2" />
                        {isGeneratingTitles ? t('ai.generating') : t('ai.generateTitles')}
                      </DropdownMenuItem>
                      <DropdownMenuSeparator />
                      <DropdownMenuSub>
                        <DropdownMenuSubTrigger>
                          <Wand2 className="h-4 w-4 mr-2" />
                          {t('ai.reformulateText')}
                        </DropdownMenuSubTrigger>
                        <DropdownMenuSubContent>
                          <DropdownMenuItem
                            onClick={() => handleReformulate('clarify')}
                            disabled={isReformulating}
                          >
                            <Sparkles className="h-4 w-4 mr-2" />
                            {isReformulating ? t('ai.reformulating') : t('ai.clarify')}
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            onClick={() => handleReformulate('shorten')}
                            disabled={isReformulating}
                          >
                            <Sparkles className="h-4 w-4 mr-2" />
                            {isReformulating ? t('ai.reformulating') : t('ai.shorten')}
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            onClick={() => handleReformulate('improve')}
                            disabled={isReformulating}
                          >
                            <Sparkles className="h-4 w-4 mr-2" />
                            {isReformulating ? t('ai.reformulating') : t('ai.improveStyle')}
                          </DropdownMenuItem>
                        </DropdownMenuSubContent>
                      </DropdownMenuSub>
                    </DropdownMenuContent>
                  </DropdownMenu>

                  {/* Size Selector */}
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Button variant="ghost" size="sm" title={t('notes.changeSize')}>
                        <Maximize2 className="h-4 w-4" />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent>
                      <div className="flex flex-col gap-1 p-1">
                        {['small', 'medium', 'large'].map((s) => (
                          <Button
                            key={s}
                            variant="ghost"
                            size="sm"
                            onClick={() => setSize(s as NoteSize)}
                            className={cn(
                              "justify-start capitalize",
                              size === s && "bg-accent"
                            )}
                          >
                            {s}
                          </Button>
                        ))}
                      </div>
                    </DropdownMenuContent>
                  </DropdownMenu>

                  {/* Color Picker */}
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Button variant="ghost" size="sm" title={t('notes.changeColor')}>
                        <Palette className="h-4 w-4" />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent>
                      <div className="grid grid-cols-5 gap-2 p-2">
                        {Object.entries(NOTE_COLORS).map(([colorName, classes]) => (
                          <button
                            key={colorName}
                            className={cn(
                              'h-8 w-8 rounded-full border-2 transition-transform hover:scale-110',
                              classes.bg,
                              color === colorName ? 'border-gray-900 dark:border-gray-100' : 'border-gray-300 dark:border-gray-700'
                            )}
                            onClick={() => setColor(colorName)}
                            title={colorName}
                          />
                        ))}
                      </div>
                    </DropdownMenuContent>
                  </DropdownMenu>

                  {/* Label Manager */}
                  <LabelManager
                    existingLabels={labels}
                    notebookId={note.notebookId}
                    onUpdate={setLabels}
                  />
                </>
              )}
              {readOnly && (
                <div className="flex items-center gap-2 text-sm text-muted-foreground">
                  <span className="text-xs">{t('notes.sharedReadOnly')}</span>
                </div>
              )}
            </div>

            <div className="flex gap-2">
              {readOnly ? (
                <>
                  <Button
                    variant="default"
                    onClick={handleMakeCopy}
                    className="flex items-center gap-2"
                  >
                    <Copy className="h-4 w-4" />
                    {t('notes.makeCopy')}
                  </Button>
                  <Button
                    variant="ghost"
                    className="flex items-center gap-2 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-950/30"
                    onClick={async () => {
                      try {
                        await leaveSharedNote(note.id)
                        toast.success(t('notes.leftShare') || 'Share removed')
                        triggerRefresh()
                        onClose()
                      } catch {
                        toast.error(t('general.error'))
                      }
                    }}
                  >
                    <LogOut className="h-4 w-4" />
                    {t('notes.leaveShare')}
                  </Button>
                  <Button variant="ghost" onClick={onClose}>
                    {t('general.close')}
                  </Button>
                </>
              ) : (
                <>
                  <Button variant="ghost" onClick={onClose}>
                    {t('general.cancel')}
                  </Button>
                  <Button onClick={handleSave} disabled={isSaving}>
                    {isSaving ? t('notes.saving') : t('general.save')}
                  </Button>
                </>
              )}
            </div>
          </div>
        </div>
        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          multiple
          className="hidden"
          onChange={handleImageUpload}
        />
      </DialogContent>

      <ReminderDialog 
        open={showReminderDialog}
        onOpenChange={setShowReminderDialog}
        currentReminder={currentReminder}
        onSave={handleReminderSave}
        onRemove={handleRemoveReminder}
      />

      <Dialog open={showLinkDialog} onOpenChange={setShowLinkDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t('notes.addLink')}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-4">
            <Input
              placeholder="https://example.com"
              value={linkUrl}
              onChange={(e) => setLinkUrl(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault()
                  handleAddLink()
                }
              }}
              autoFocus
            />
          </div>
          <DialogFooter>
            <Button variant="ghost" onClick={() => setShowLinkDialog(false)}>
              {t('general.cancel')}
            </Button>
            <Button onClick={handleAddLink}>
              {t('general.add')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Reformulation Modal */}
      {reformulationModal && (
        <Dialog open={!!reformulationModal} onOpenChange={() => setReformulationModal(null)}>
          <DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto">
            <DialogHeader>
              <DialogTitle>{t('ai.reformulationComparison')}</DialogTitle>
            </DialogHeader>
            <div className="grid grid-cols-2 gap-4 py-4">
              <div>
                <h3 className="font-semibold mb-2 text-sm text-gray-600 dark:text-gray-400">{t('ai.original')}</h3>
                <div className="p-4 bg-gray-50 dark:bg-gray-900 rounded-lg text-sm">
                  {reformulationModal.originalText}
                </div>
              </div>
              <div>
                <h3 className="font-semibold mb-2 text-sm text-purple-600 dark:text-purple-400">
                  {t('ai.reformulated')} ({reformulationModal.option})
                </h3>
                <div className="p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg text-sm">
                  {reformulationModal.reformulatedText}
                </div>
              </div>
            </div>
            <DialogFooter>
              <Button variant="ghost" onClick={() => setReformulationModal(null)}>
                {t('general.cancel')}
              </Button>
              <Button onClick={handleApplyRefactor}>
                {t('general.apply')}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )}

      {/* Comparison Modal */}
      {comparisonNotes && comparisonNotes.length > 0 && (
        <ComparisonModal
          isOpen={!!comparisonNotes}
          onClose={() => setComparisonNotes([])}
          notes={comparisonNotes}
          onOpenNote={(noteId) => {
            // Close current editor and open the selected note
            onClose()
            // Trigger navigation to the note
            window.location.href = `/?note=${noteId}`
          }}
        />
      )}

      {/* Fusion Modal */}
      {fusionNotes && fusionNotes.length > 0 && (
        <FusionModal
          isOpen={!!fusionNotes}
          onClose={() => setFusionNotes([])}
          notes={fusionNotes}
          onConfirmFusion={async ({ title, content }, options) => {
            // Create the fused note
            await createNote({
              title,
              content,
              labels: options.keepAllTags
                ? [...new Set(fusionNotes.flatMap(n => n.labels || []))]
                : fusionNotes[0].labels || [],
              color: fusionNotes[0].color,
              type: 'text',
              isMarkdown: true, // AI generates markdown content
              autoGenerated: true, // Mark as AI-generated fused note
              aiProvider: 'fusion',
              notebookId: fusionNotes[0].notebookId ?? undefined // Keep the notebook from the first note, convert null to undefined
            })

            // Archive original notes if option is selected
            if (options.archiveOriginals) {
              for (const note of fusionNotes) {
                if (note.id) {
                  await updateNote(note.id, { isArchived: true })
                }
              }
            }

            toast.success(t('toast.notesFusionSuccess'))
            triggerRefresh()
            onClose()
          }}
        />
      )}
    </Dialog>
  )
}