'use client'

import { Note, NOTE_COLORS, NoteColor, NoteType } from '@/lib/types'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuSeparator,
} from '@/components/ui/dropdown-menu'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { Pin, Bell, GripVertical, X, Link2, FolderOpen, StickyNote, LucideIcon, Folder, Briefcase, FileText, Zap, BarChart3, Globe, Sparkles, Book, Heart, Crown, Music, Building2, LogOut, Trash2, AlignLeft, FileCode2, PenLine, ListChecks, ChevronRight, Plus } from 'lucide-react'
import { useState, useEffect, useTransition, useOptimistic, memo, useMemo } from 'react'
import dynamic from 'next/dynamic'
import { useSession } from 'next-auth/react'
import { useRouter, useSearchParams } from 'next/navigation'
import { deleteNote, toggleArchive, togglePin, updateColor, updateNote, updateSize, getNoteAllUsers, leaveSharedNote, removeFusedBadge, createNote, restoreNote, permanentDeleteNote } from '@/app/actions/notes'
import { cn } from '@/lib/utils'
import { formatDistanceToNow, Locale } from 'date-fns'
import { enUS } from 'date-fns/locale/en-US'
import { fr } from 'date-fns/locale/fr'
import { es } from 'date-fns/locale/es'
import { de } from 'date-fns/locale/de'
import { faIR } from 'date-fns/locale/fa-IR'
import { it } from 'date-fns/locale/it'
import { pt } from 'date-fns/locale/pt'
import { ru } from 'date-fns/locale/ru'
import { zhCN } from 'date-fns/locale/zh-CN'
import { ja } from 'date-fns/locale/ja'
import { ko } from 'date-fns/locale/ko'
import { ar } from 'date-fns/locale/ar'
import { hi } from 'date-fns/locale/hi'
import { nl } from 'date-fns/locale/nl'
import { pl } from 'date-fns/locale/pl'
import { LabelBadge } from './label-badge'
import { NoteImages } from './note-images'
import { NoteChecklist } from './note-checklist'
import { NoteActions } from './note-actions'
import { CollaboratorAvatars } from './collaborator-avatars'
import { ConnectionsBadge } from './connections-badge'

const MarkdownContent = dynamic(() => import('./markdown-content').then(m => ({ default: m.MarkdownContent })), {
  loading: () => <div className="text-sm text-muted-foreground animate-pulse">…</div>,
})
const CollaboratorDialog = dynamic(() => import('./collaborator-dialog').then(m => ({ default: m.CollaboratorDialog })), { ssr: false })
const ConnectionsOverlay = dynamic(() => import('./connections-overlay').then(m => ({ default: m.ConnectionsOverlay })), { ssr: false })
const ComparisonModal = dynamic(() => import('./comparison-modal').then(m => ({ default: m.ComparisonModal })), { ssr: false })
const FusionModal = dynamic(() => import('./fusion-modal').then(m => ({ default: m.FusionModal })), { ssr: false })
import { useConnectionsCompare } from '@/hooks/use-connections-compare'
import { useNotebooks } from '@/context/notebooks-context'
import { useRefresh } from '@/lib/use-refresh'
import { useLanguage } from '@/lib/i18n'
import { toast } from 'sonner'

// Mapping of supported languages to date-fns locales
const localeMap: Record<string, Locale> = {
  en: enUS,
  fr: fr,
  es: es,
  de: de,
  fa: faIR,
  it: it,
  pt: pt,
  ru: ru,
  zh: zhCN,
  ja: ja,
  ko: ko,
  ar: ar,
  hi: hi,
  nl: nl,
  pl: pl,
}

function getDateLocale(language: string): Locale {
  return localeMap[language] || enUS
}

const NOTE_TYPE_ICONS: Record<NoteType, LucideIcon> = {
  text: AlignLeft,
  markdown: FileCode2,
  richtext: PenLine,
  checklist: ListChecks,
}

// Map icon names to lucide-react components
const ICON_MAP: Record<string, LucideIcon> = {
  'folder': Folder,
  'briefcase': Briefcase,
  'document': FileText,
  'lightning': Zap,
  'chart': BarChart3,
  'globe': Globe,
  'sparkle': Sparkles,
  'book': Book,
  'heart': Heart,
  'crown': Crown,
  'music': Music,
  'building': Building2,
}

// Function to get icon component by name
function getNotebookIcon(iconName: string): LucideIcon {
  const IconComponent = ICON_MAP[iconName] || Folder
  return IconComponent
}

 interface NoteCardProps {
  note: Note
  onEdit?: (note: Note, readOnly?: boolean) => void
  isDragging?: boolean
  isDragOver?: boolean
  onDragStart?: (noteId: string) => void
  onDragEnd?: () => void
  onResize?: () => void
  onSizeChange?: (newSize: 'small' | 'medium' | 'large') => void
  isTrashView?: boolean
  noteHistoryEnabled?: boolean
  onOpenHistory?: (note: Note) => void
  onCreateSubNotebook?: () => void
}

// Helper function to get initials from name
function getInitials(name: string): string {
  if (!name) return '??'
  const trimmedName = name.trim()
  const parts = trimmedName.split(' ')
  if (parts.length === 1) {
    return trimmedName.substring(0, 2).toUpperCase()
  }
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()
}

// Helper function to get avatar color based on name hash
function getAvatarColor(name: string): string {
  const colors = [
    'bg-primary',
    'bg-purple-600',
    'bg-emerald-600',
    'bg-amber-600',
    'bg-pink-600',
    'bg-teal-600',
    'bg-stone-600',
    'bg-indigo-600',
  ]

  const hash = name.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
  return colors[hash % colors.length]
}

export const NoteCard = memo(function NoteCard({
  note,
  onEdit,
  onDragStart,
  onDragEnd,
  isDragging,
  onResize,
  onSizeChange,
  isTrashView,
  noteHistoryEnabled = false,
  onOpenHistory,
  onCreateSubNotebook,
}: NoteCardProps) {
  const router = useRouter()
  const searchParams = useSearchParams()
  const { refreshNotes } = useRefresh()
  const { data: session } = useSession()
  const { t, language } = useLanguage()
  const { notebooks, moveNoteToNotebookOptimistic, refreshLabels } = useNotebooks()
  const [, startTransition] = useTransition()
  const [isDeleting, setIsDeleting] = useState(false)
  const [isHidden, setIsHidden] = useState(false)
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [showCollaboratorDialog, setShowCollaboratorDialog] = useState(false)
  const [collaborators, setCollaborators] = useState<any[]>([])
  const [owner, setOwner] = useState<any>(null)
  const [showConnectionsOverlay, setShowConnectionsOverlay] = useState(false)
  const [comparisonNotes, setComparisonNotes] = useState<string[] | null>(null)
  const [fusionNotes, setFusionNotes] = useState<Array<Partial<Note>>>([])
  const [showNotebookMenu, setShowNotebookMenu] = useState(false)
  const [reminderDate, setReminderDate] = useState<Date | null>(note.reminder ? new Date(note.reminder) : null)

  const sanitizedHtml = useMemo(() => {
    if (note.type !== 'richtext' || !note.content) return ''
    if (typeof window !== 'undefined') {
      // eslint-disable-next-line @typescript-eslint/no-require-imports
      return require('isomorphic-dompurify').sanitize(note.content)
    }
    return note.content
  }, [note.type, note.content])

  const handleUpdateReminder = async (noteId: string, reminder: Date | null) => {
    startTransition(async () => {
      try {
        await updateNote(noteId, { reminder })
        setReminderDate(reminder)
        refreshNotes(note?.notebookId)
        if (reminder) {
          toast.success(t('notes.reminderSet', { datetime: reminder.toLocaleString() }))
        } else {
          toast.info(t('reminder.removeReminder'))
        }
      } catch {
        toast.error(t('general.error'))
      }
    })
  }

  // Move note to a notebook
  const handleMoveToNotebook = async (notebookId: string | null) => {
    await moveNoteToNotebookOptimistic(note.id, notebookId)
    setShowNotebookMenu(false)
    // No need for router.refresh() - refreshNotes(note?.notebookId) is already called in moveNoteToNotebookOptimistic
  }

  // Optimistic UI state for instant feedback
  const [optimisticNote, addOptimisticNote] = useOptimistic(
    note,
    (state, newProps: Partial<Note>) => ({ ...state, ...newProps })
  )

  // Local color state so color persists after transition ends
  const [localColor, setLocalColor] = useState(note.color)
  // Local checkItems state so checklist toggles persist after transition ends
  const [localCheckItems, setLocalCheckItems] = useState(note.checkItems)

  // Sync local state when parent data refreshes
  useEffect(() => {
    setLocalCheckItems(note.checkItems)
  }, [note.checkItems])

  const colorClasses = NOTE_COLORS[(localColor || optimisticNote.color) as NoteColor] || NOTE_COLORS.default

  // Check if this note is currently open in the editor
  const isNoteOpenInEditor = searchParams.get('note') === note.id

  // Only fetch comparison notes when we have IDs to compare
  const { notes: comparisonNotesData, isLoading: isLoadingComparison } = useConnectionsCompare(
    comparisonNotes && comparisonNotes.length > 0 ? comparisonNotes : null
  )

  const currentUserId = session?.user?.id
  const canManageCollaborators = currentUserId && note.userId && currentUserId === note.userId
  const isSharedNote = currentUserId && note.userId && currentUserId !== note.userId
  const isOwner = currentUserId && note.userId && currentUserId === note.userId

  // Load collaborators only for shared notes (not owned by current user)
  useEffect(() => {
    // Skip API call for notes owned by current user — no need to fetch collaborators
    if (!isSharedNote) {
      // For own notes, set owner to current user
      if (currentUserId && session?.user) {
        setOwner({
          id: currentUserId,
          name: session.user.name,
          email: session.user.email,
          image: session.user.image,
        })
      }
      return
    }

    if (!isSharedNote) return

    let isMounted = true

    const loadCollaborators = async () => {
      if (note.userId && isMounted) {
        try {
          const users = await getNoteAllUsers(note.id)
          if (isMounted) {
            setCollaborators(users)
            if (users.length > 0) {
              setOwner(users[0])
            }
          }
        } catch (error) {
          if (isMounted) {
            setCollaborators([])
          }
        }
      }
    }

    loadCollaborators()

    return () => {
      isMounted = false
    }
  }, [note.id, note.userId, isSharedNote, currentUserId, session?.user])

  const handleDelete = async () => {
    setIsDeleting(true)
    setIsHidden(true) // masquage immédiat
    try {
      await deleteNote(note.id)
      await refreshLabels()
      refreshNotes(note?.notebookId) // met à jour la liste et le compteur du carnet
    } catch (error) {
      console.error('Failed to delete note:', error)
      setIsHidden(false)
      setIsDeleting(false)
    }
  }

  const handleRestore = async () => {
    setIsDeleting(true)
    setIsHidden(true)
    try {
      await restoreNote(note.id)
      refreshNotes(note?.notebookId)
      toast.success(t('trash.noteRestored'))
    } catch (error) {
      console.error('Failed to restore note:', error)
      setIsHidden(false)
      setIsDeleting(false)
    }
  }

  const handlePermanentDelete = async () => {
    setIsDeleting(true)
    setIsHidden(true)
    try {
      await permanentDeleteNote(note.id)
      refreshNotes(note?.notebookId)
      toast.success(t('trash.notePermanentlyDeleted'))
    } catch (error) {
      console.error('Failed to permanently delete note:', error)
      setIsHidden(false)
      setIsDeleting(false)
    }
  }

  const handleTogglePin = async () => {
    startTransition(async () => {
      addOptimisticNote({ isPinned: !note.isPinned })
      await togglePin(note.id, !note.isPinned)
      refreshNotes(note?.notebookId)

      if (!note.isPinned) {
        toast.success(t('notes.pinned'))
      } else {
        toast.info(t('notes.unpinned'))
      }
    })
  }

  const handleToggleArchive = async () => {
    startTransition(async () => {
      addOptimisticNote({ isArchived: !note.isArchived })
      await toggleArchive(note.id, !note.isArchived)
      refreshNotes(note?.notebookId)
    })
  }

  const handleColorChange = async (color: string) => {
    setLocalColor(color) // instant visual update, survives transition
    startTransition(async () => {
      addOptimisticNote({ color })
      await updateNote(note.id, { color }, { skipRevalidation: false })
    })
  }

  const handleSizeChange = async (size: 'small' | 'medium' | 'large') => {
    startTransition(async () => {
      // Instant visual feedback for the card itself
      addOptimisticNote({ size })

      // Notify parent so it can update its local state
      onSizeChange?.(size)

      // Trigger layout refresh
      onResize?.()
      setTimeout(() => onResize?.(), 300)

      // Update server in background

      try {
        await updateSize(note.id, size);
      } catch (error) {
        console.error('Failed to update note size:', error);
      }
    })
  }

  const handleCheckItem = async (checkItemId: string) => {
    if (note.type === 'checklist') {
      const currentItems = localCheckItems || note.checkItems || []
      const updatedItems = currentItems.map(item =>
        item.id === checkItemId ? { ...item, checked: !item.checked } : item
      )
      setLocalCheckItems(updatedItems) // instant visual update, survives transition
      startTransition(async () => {
        addOptimisticNote({ checkItems: updatedItems })
        await updateNote(note.id, { checkItems: updatedItems })
      })
    }
  }

  const handleLeaveShare = async () => {
    if (confirm(t('notes.confirmLeaveShare'))) {
      try {
        await leaveSharedNote(note.id)
        setIsDeleting(true) // Hide the note from view
      } catch (error) {
        console.error('Failed to leave share:', error)
      }
    }
  }

  const handleRemoveFusedBadge = async (e: React.MouseEvent) => {
    e.stopPropagation() // Prevent opening the note editor
    startTransition(async () => {
      addOptimisticNote({ autoGenerated: null })
      await removeFusedBadge(note.id)
      // No router.refresh() — optimistic update is sufficient and avoids grid rebuild
    })
  }

  if (isDeleting) return null

  const getMinHeight = (size?: string) => {
    switch (size) {
      case 'medium': return '350px'
      case 'large': return '500px'
      default: return '150px' // small
    }
  }



  if (isHidden) return null

  return (
    <Card
      data-testid="note-card"
      data-draggable="true"
      data-note-id={note.id}
      data-size={optimisticNote.size}
      style={{ minHeight: getMinHeight(optimisticNote.size) }}
      draggable={true}
      onDragStart={(e) => {
        e.dataTransfer.setData('text/plain', note.id)
        e.dataTransfer.effectAllowed = 'move'
        e.dataTransfer.setData('text/html', '') // Prevent ghost image in some browsers
        onDragStart?.(note.id)
      }}
      onDragEnd={() => onDragEnd?.()}
      className={cn(
        'note-card group relative rounded-lg overflow-hidden p-6 border border-transparent shadow-[0_2px_4px_rgba(0,0,0,0.04),0_4px_12px_rgba(0,0,0,0.04)]',
        'transition-all duration-200 ease-out',
        !isTrashView && 'hover:shadow-[0_4px_8px_rgba(0,0,0,0.06),0_8px_24px_rgba(0,0,0,0.08)] hover:border-border/40 hover:-translate-y-0.5',
        isTrashView && 'cursor-default',
        colorClasses.bg,
        colorClasses.card,
        colorClasses.hover,
        isDragging && 'shadow-lg'
      )}
      onClick={(e) => {
        // Trashed notes are not editable
        if (isTrashView) return
        // Only trigger edit if not clicking on buttons
        const target = e.target as HTMLElement
        if (!target.closest('button') && !target.closest('[role="checkbox"]') && !target.closest('.muuri-drag-handle') && !target.closest('.drag-handle')) {
          // For shared notes, pass readOnly flag
          onEdit?.(note, !!isSharedNote) // Pass second parameter as readOnly flag (convert to boolean)
        }
      }}
    >
      {/* Drag Handle - Only visible on mobile/touch devices */}
      <div
        className="muuri-drag-handle absolute top-2 start-2 z-20 cursor-grab active:cursor-grabbing p-2 md:hidden"
        aria-label={t('notes.dragToReorder')}
        title={t('notes.dragToReorder')}
      >
        <GripVertical className="h-5 w-5 text-muted-foreground" />
      </div>

      {/* Move to Notebook Dropdown Menu — hidden in trash */}
      {!isTrashView && <div onClick={(e) => e.stopPropagation()} className="absolute top-2 end-2 z-20">
        <DropdownMenu open={showNotebookMenu} onOpenChange={setShowNotebookMenu}>
          <DropdownMenuTrigger asChild>
            <Button
              variant="ghost"
              size="sm"
              className="h-8 w-8 p-0 bg-primary/10 dark:bg-primary/20 hover:bg-primary/20 dark:hover:bg-primary/30 text-primary dark:text-primary-foreground"
              title={t('notebookSuggestion.moveToNotebook')}
            >
              <FolderOpen className="h-4 w-4" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" className="w-56">
            <div className="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
              {t('notebookSuggestion.moveToNotebook')}
            </div>
            <DropdownMenuItem onClick={() => handleMoveToNotebook(null)}>
              <StickyNote className="h-4 w-4 me-2" />
              {t('notebookSuggestion.generalNotes')}
            </DropdownMenuItem>
            {notebooks.filter(nb => !nb.parentId && !nb.trashedAt).map((notebook: any) => {
                const NotebookIcon = getNotebookIcon(notebook.icon || 'folder')
                const allDescendants = (parentId: string): any[] => {
                  const kids = notebooks.filter((c: any) => c.parentId === parentId && !c.trashedAt)
                  return kids.flatMap((k: any) => [k, ...allDescendants(k.id)])
                }
                const descendants = allDescendants(notebook.id)
                if (descendants.length > 0) {
                  return (
                    <DropdownMenuSub key={notebook.id}>
                      <DropdownMenuSubTrigger className="gap-2">
                        <NotebookIcon className="h-4 w-4" />
                        {notebook.name}
                        <ChevronRight className="h-3 w-3 ms-auto opacity-50 rtl:rotate-180" />
                      </DropdownMenuSubTrigger>
                      <DropdownMenuSubContent>
                        <DropdownMenuItem onClick={() => handleMoveToNotebook(notebook.id)}>
                          <NotebookIcon className="h-4 w-4 me-2" />
                          {notebook.name}
                        </DropdownMenuItem>
                        {descendants.map((child: any) => {
                          const ChildIcon = getNotebookIcon(child.icon || 'folder')
                          const depth = (() => {
                            let d = 0
                            let current = child
                            while (current.parentId && current.parentId !== notebook.id) {
                              d++
                              current = notebooks.find((nb: any) => nb.id === current.parentId)
                              if (!current) break
                            }
                            return d
                          })()
                          return (
                            <DropdownMenuItem key={child.id} onClick={() => handleMoveToNotebook(child.id)}>
                              <NotebookIcon className="h-4 w-4 me-2" />
                              <span style={{ marginInlineStart: `${depth * 0.5}rem` }}>{child.name}</span>
                            </DropdownMenuItem>
                          )
                        })}
                      </DropdownMenuSubContent>
                    </DropdownMenuSub>
                  )
                }
               return (
                 <DropdownMenuItem key={notebook.id} onClick={() => handleMoveToNotebook(notebook.id)}>
                   <NotebookIcon className="h-4 w-4 me-2" />
                   {notebook.name}
                 </DropdownMenuItem>
               )
             })}
             <DropdownMenuSeparator />
             <DropdownMenuItem className="text-muted-foreground" onSelect={() => onCreateSubNotebook?.()}>
               <Plus className="h-4 w-4 me-2" />
               {t('notebook.createSubNotebook')}
             </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>}

      {/* Pin Button - hidden in trash */}
      {!isTrashView && <Button
        variant="ghost"
        size="sm"
        data-testid="pin-button"
        className={cn(
          "absolute top-2 end-12 z-20 h-8 w-8 p-0 rounded-md transition-opacity",
          optimisticNote.isPinned ? "opacity-100" : "opacity-0 group-hover:opacity-100"
        )}
        onClick={(e) => {
          e.stopPropagation()
          handleTogglePin()
        }}
      >
        <Pin
          className={cn("h-4 w-4", optimisticNote.isPinned ? "fill-current text-primary" : "text-muted-foreground")}
        />
      </Button>}



      {/* Reminder Icon - Move slightly if pin button is there */}
      {note.reminder && new Date(note.reminder) > new Date() && (
        <Bell
          className="absolute top-3 end-10 h-4 w-4 text-primary"
        />
      )}

      {/* Fusion Badge */}
      {note.aiProvider === 'fusion' && optimisticNote.autoGenerated !== null && (
        <div className="px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-400 border border-purple-200 dark:border-purple-800 flex items-center gap-1 group/badge relative mb-2 w-fit">
          <Link2 className="h-2.5 w-2.5" />
          {t('memoryEcho.fused')}
          <button
            onClick={handleRemoveFusedBadge}
            className="ms-1 opacity-0 group-hover/badge:opacity-100 hover:opacity-100 transition-opacity"
            title={t('notes.remove')}
          >
            <Trash2 className="h-2.5 w-2.5" />
          </button>
        </div>
      )}

      {/* Title */}
      {note.title && (
        <h3 dir="auto" className="text-lg font-heading font-semibold mb-2 pe-20 text-foreground leading-tight tracking-tight flex items-center gap-2">
          {(() => {
            const TypeIcon = NOTE_TYPE_ICONS[note.type] || AlignLeft
            return <TypeIcon className="h-4 w-4 shrink-0 text-muted-foreground/50" />
          })()}
          <span className="min-w-0 truncate">{note.title}</span>
        </h3>
      )}

      {/* Search Match Type Badge */}
      {note.matchType && (
        <Badge
          variant={note.matchType === 'exact' ? 'default' : 'secondary'}
          className={cn(
            'mb-2 text-xs',
            note.matchType === 'exact'
              ? 'bg-green-100 text-green-800 border-green-200 dark:bg-green-900/30 dark:text-green-300 dark:border-green-800'
              : 'bg-primary/10 text-primary border-primary/20 dark:bg-primary/20 dark:text-primary-foreground'
          )}
        >
          {t(`semanticSearch.${note.matchType === 'exact' ? 'exactMatch' : 'related'}`)}
        </Badge>
      )}

      {/* Shared badge */}
      {isSharedNote && owner && (
        <div className="flex items-center justify-between mb-2">
          <span className="text-xs text-primary dark:text-primary-foreground font-medium">
            {t('notes.sharedBy')} {owner.name || owner.email}
          </span>
          <Button
            variant="ghost"
            size="sm"
            className="h-6 px-2 text-xs text-gray-500 hover:text-red-600 dark:hover:text-red-400"
            onClick={(e) => {
              e.stopPropagation()
              handleLeaveShare()
            }}
          >
            <LogOut className="h-3 w-3 me-1" />
            {t('notes.leaveShare')}
          </Button>
        </div>
      )}

      {/* Images Component */}
      <NoteImages images={note.images || []} title={note.title} />

      {/* Link Previews */}
      {Array.isArray(note.links) && note.links.length > 0 && (
        <div className="flex flex-col gap-2 mb-2">
          {note.links.map((link: any, idx: number) => (
            <a
              key={idx}
              href={link.url}
              target="_blank"
              rel="noopener noreferrer"
              className="block border rounded-md overflow-hidden bg-white/50 dark:bg-black/20 hover:bg-white/80 dark:hover:bg-black/40 transition-colors"
              onClick={(e) => e.stopPropagation()}
            >
              {link.imageUrl && (
                <div className="h-24 bg-cover bg-center" style={{ backgroundImage: `url(${link.imageUrl})` }} />
              )}
              <div className="p-2">
                <h4 className="font-medium text-xs truncate text-gray-900 dark:text-gray-100">{link.title || link.url}</h4>
                {link.description && <p className="text-xs text-gray-500 dark:text-gray-400 line-clamp-2 mt-0.5">{link.description}</p>}
                <span className="text-[10px] text-primary mt-1 block">
                  {new URL(link.url).hostname}
                </span>
              </div>
            </a>
          ))}
        </div>
      )}

      {/* Content */}
      {note.type === 'checklist' ? (
        <NoteChecklist
          items={localCheckItems || optimisticNote.checkItems || note.checkItems || []}
          onToggleItem={handleCheckItem}
        />
      ) : note.type === 'richtext' ? (
        <div className="text-sm text-foreground line-clamp-10 rt-preview" dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />
      ) : (
        <div className="text-sm text-foreground line-clamp-10">
          <MarkdownContent 
            content={note.content} 
            className="prose-h1:text-xl prose-h1:font-semibold prose-h1:leading-snug prose-h1:mt-1 prose-h1:mb-2 prose-h2:text-lg prose-h2:font-medium prose-h3:text-base prose-p:text-sm prose-p:leading-relaxed"
          />
        </div>
      )}

      {/* Labels - using shared LabelBadge component */}
      {note.notebookId && Array.isArray(note.labels) && note.labels.length > 0 && (
        <div className="flex flex-wrap gap-1 mt-3">
          {note.labels.map((label: string) => (
            <LabelBadge key={label} label={label} />
          ))}
        </div>
      )}

      {/* Footer with Date only */}
      <div className="mt-3 flex items-center justify-end">
        {/* Creation Date */}
        <div className="text-xs text-muted-foreground" suppressHydrationWarning>
          {formatDistanceToNow(new Date(note.createdAt), { addSuffix: true, locale: getDateLocale(language) })}
        </div>
      </div>

      {/* Owner Avatar - Aligned with action buttons at bottom */}
      {owner && (
        <div
          className={cn(
            "absolute bottom-2 start-2 z-20",
            "w-6 h-6 rounded-full text-white text-[10px] font-semibold flex items-center justify-center",
            getAvatarColor(owner.name || owner.email || 'Unknown')
          )}
          title={owner.name || owner.email || 'Unknown'}
        >
          {getInitials(owner.name || owner.email || '??')}
        </div>
      )}

      {/* Action Bar Component - Always show for now to fix regression */}
      {true && (
        <NoteActions
          isPinned={optimisticNote.isPinned}
          isArchived={optimisticNote.isArchived}
          currentColor={optimisticNote.color}
          currentSize={optimisticNote.size as 'small' | 'medium' | 'large'}
          onTogglePin={handleTogglePin}
          onToggleArchive={handleToggleArchive}
          onColorChange={handleColorChange}
          onSizeChange={handleSizeChange}
          onDelete={() => setShowDeleteDialog(true)}
          onShareCollaborators={() => setShowCollaboratorDialog(true)}
          isTrashView={isTrashView}
          onRestore={handleRestore}
          onPermanentDelete={handlePermanentDelete}
          onOpenHistory={() => onOpenHistory?.(note)}
          historyEnabled={!!note.historyEnabled}
          noteId={note.id}
          currentReminder={reminderDate}
          onUpdateReminder={handleUpdateReminder}
          className="absolute bottom-0 start-0 end-0 p-2 opacity-100 md:opacity-0 group-hover:opacity-100 transition-opacity"
        />
      )}

      {/* Collaborator Dialog */}
      {currentUserId && note.userId && (
        <div onClick={(e) => e.stopPropagation()}>
          <CollaboratorDialog
            open={showCollaboratorDialog}
            onOpenChange={setShowCollaboratorDialog}
            noteId={note.id}
            noteOwnerId={note.userId}
            currentUserId={currentUserId}
          />
        </div>
      )}

      {/* Connections Badge - Bottom right (spec: amber, absolute) */}
      <div className="absolute bottom-2 end-2 z-10">
        <ConnectionsBadge
          noteId={note.id}
          onClick={() => {
            if (!isNoteOpenInEditor) {
              setShowConnectionsOverlay(true)
            }
          }}
        />
      </div>

      {/* Connections Overlay */}
      <div onClick={(e) => e.stopPropagation()}>
        <ConnectionsOverlay
          isOpen={showConnectionsOverlay}
          onClose={() => setShowConnectionsOverlay(false)}
          noteId={note.id}
          onOpenNote={(connNoteId) => {
            setShowConnectionsOverlay(false)
            const params = new URLSearchParams(searchParams.toString())
            params.set('note', connNoteId)
            router.push(`?${params.toString()}`)
          }}
          onCompareNotes={(noteIds) => {
            setComparisonNotes(noteIds)
          }}
          onMergeNotes={async (noteIds) => {
            const fetchedNotes = await Promise.all(noteIds.map(async (id) => {
              try {
                const res = await fetch(`/api/notes/${id}`)
                if (!res.ok) return null
                const data = await res.json()
                return data.success && data.data ? data.data : null
              } catch { return null }
            }))
            setFusionNotes(fetchedNotes.filter((n: any) => n !== null) as Array<Partial<Note>>)
          }}
        />
      </div>

      {/* Comparison Modal */}
      {comparisonNotes && comparisonNotesData.length > 0 && (
        <div onClick={(e) => e.stopPropagation()}>
          <ComparisonModal
            isOpen={!!comparisonNotes}
            onClose={() => setComparisonNotes(null)}
            notes={comparisonNotesData}
            onOpenNote={(noteId) => {
              const foundNote = comparisonNotesData.find(n => n.id === noteId)
              if (foundNote) {
                onEdit?.(foundNote, false)
              }
            }}
          />
        </div>
      )}

      {/* Fusion Modal */}
      {fusionNotes.length > 0 && (
        <div onClick={(e) => e.stopPropagation()}>
          <FusionModal
            isOpen={fusionNotes.length > 0}
            onClose={() => setFusionNotes([])}
            notes={fusionNotes}
            onConfirmFusion={async ({ title, content }, options) => {
              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,
                autoGenerated: true,
                aiProvider: 'fusion',
                notebookId: fusionNotes[0].notebookId ?? undefined
              })
              if (options.archiveOriginals) {
                for (const n of fusionNotes) {
                  if (n.id) await updateNote(n.id, { isArchived: true })
                }
              }
              toast.success(t('toast.notesFusionSuccess'))
              setFusionNotes([])
              refreshNotes(note?.notebookId)
            }}
          />
        </div>
      )}

      {/* Delete Confirmation Dialog */}
      <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{t('notes.confirmDeleteTitle') || t('notes.delete')}</AlertDialogTitle>
            <AlertDialogDescription>
              {t('notes.confirmDelete')}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>{t('common.cancel')}</AlertDialogCancel>
            <AlertDialogAction variant="destructive" onClick={handleDelete}>
              {t('notes.delete')}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </Card>
  )
})