'use client'

import { Note, NOTE_COLORS, NoteColor } 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,
} from '@/components/ui/dropdown-menu'
import { Pin, Bell, GripVertical, X, Link2, FolderOpen, StickyNote, LucideIcon, Folder, Briefcase, FileText, Zap, BarChart3, Globe, Sparkles, Book, Heart, Crown, Music, Building2 } from 'lucide-react'
import { useState, useEffect, useTransition, useOptimistic } from 'react'
import { useSession } from 'next-auth/react'
import { useRouter, useSearchParams } from 'next/navigation'
import { deleteNote, toggleArchive, togglePin, updateColor, updateNote, updateSize, getNoteAllUsers, leaveSharedNote, removeFusedBadge } from '@/app/actions/notes'
import { cn } from '@/lib/utils'
import { formatDistanceToNow, Locale } from 'date-fns'
import * as dateFnsLocales from 'date-fns/locale'
import { MarkdownContent } from './markdown-content'
import { LabelBadge } from './label-badge'
import { NoteImages } from './note-images'
import { NoteChecklist } from './note-checklist'
import { NoteActions } from './note-actions'
import { CollaboratorDialog } from './collaborator-dialog'
import { CollaboratorAvatars } from './collaborator-avatars'
import { ConnectionsBadge } from './connections-badge'
import { ConnectionsOverlay } from './connections-overlay'
import { ComparisonModal } from './comparison-modal'
import { useConnectionsCompare } from '@/hooks/use-connections-compare'
import { useLabels } from '@/context/LabelContext'
import { useLanguage } from '@/lib/i18n'
import { useNotebooks } from '@/context/notebooks-context'
import { toast } from 'sonner'

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

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

// 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
}

// 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-blue-500',
    'bg-purple-500',
    'bg-green-500',
    'bg-orange-500',
    'bg-pink-500',
    'bg-teal-500',
    'bg-red-500',
    'bg-indigo-500',
  ]

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

export function NoteCard({ note, onEdit, isDragging, isDragOver, onDragStart, onDragEnd }: NoteCardProps) {
  const router = useRouter()
  const searchParams = useSearchParams()
  const { refreshLabels } = useLabels()
  const { data: session } = useSession()
  const { t, language } = useLanguage()
  const { notebooks, moveNoteToNotebookOptimistic } = useNotebooks()
  const [isPending, startTransition] = useTransition()
  const [isDeleting, setIsDeleting] = 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 [showNotebookMenu, setShowNotebookMenu] = useState(false)

  // Move note to a notebook
  const handleMoveToNotebook = async (notebookId: string | null) => {
    await moveNoteToNotebookOptimistic(note.id, notebookId)
    setShowNotebookMenu(false)
    // No need for router.refresh() - triggerRefresh() is already called in moveNoteToNotebookOptimistic
  }
  const colorClasses = NOTE_COLORS[note.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
  )

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

  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 when note changes
  useEffect(() => {
    const loadCollaborators = async () => {
      if (note.userId) {
        try {
          const users = await getNoteAllUsers(note.id)
          setCollaborators(users)
          // Owner is always first in the list
          if (users.length > 0) {
            setOwner(users[0])
          }
        } catch (error) {
          console.error('Failed to load collaborators:', error)
          setCollaborators([])
        }
      }
    }

    loadCollaborators()
  }, [note.id, note.userId])

  const handleDelete = async () => {
    if (confirm(t('notes.confirmDelete'))) {
      setIsDeleting(true)
      try {
        await deleteNote(note.id)
        // Refresh global labels to reflect garbage collection
        await refreshLabels()
      } catch (error) {
        console.error('Failed to delete note:', error)
        setIsDeleting(false)
      }
    }
  }

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

      // Show toast notification
      if (!note.isPinned) {
        toast.success('Note épinglée')
      } else {
        toast.info('Note désépinglée')
      }
    })
  }

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

  const handleColorChange = async (color: string) => {
    startTransition(async () => {
      addOptimisticNote({ color })
      await updateColor(note.id, color)
      router.refresh()
    })
  }

  const handleSizeChange = async (size: 'small' | 'medium' | 'large') => {
    startTransition(async () => {
      addOptimisticNote({ size })
      await updateSize(note.id, size)
    })
  }

  const handleCheckItem = async (checkItemId: string) => {
    if (note.type === 'checklist' && note.checkItems) {
      const updatedItems = note.checkItems.map(item =>
        item.id === checkItemId ? { ...item, checked: !item.checked } : item
      )
      startTransition(async () => {
        addOptimisticNote({ checkItems: updatedItems })
        await updateNote(note.id, { checkItems: updatedItems })
        router.refresh()
      })
    }
  }

  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)
      router.refresh()
    })
  }

  if (isDeleting) return null

  return (
    <Card
      data-testid="note-card"
      className={cn(
        'note-card group relative rounded-lg p-4 transition-all duration-200 border shadow-sm hover:shadow-md',
        colorClasses.bg,
        colorClasses.card,
        colorClasses.hover,
        isDragging && 'opacity-30'
      )}
      onClick={(e) => {
        // 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 left-2 z-20 cursor-grab active:cursor-grabbing p-2 md:hidden"
        aria-label={t('notes.dragToReorder') || 'Drag to reorder'}
        title={t('notes.dragToReorder') || 'Drag to reorder'}
      >
        <GripVertical className="h-5 w-5 text-muted-foreground" />
      </div>

      {/* Move to Notebook Dropdown Menu */}
      <div onClick={(e) => e.stopPropagation()} className="absolute top-2 right-2 z-20">
        <DropdownMenu open={showNotebookMenu} onOpenChange={setShowNotebookMenu}>
          <DropdownMenuTrigger asChild>
            <Button
              variant="ghost"
              size="sm"
              className="h-8 w-8 p-0 bg-blue-100 dark:bg-blue-900/30 hover:bg-blue-200 dark:hover:bg-blue-900/50 text-blue-600 dark:text-blue-400"
              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 mr-2" />
              {t('notebookSuggestion.generalNotes')}
            </DropdownMenuItem>
            {notebooks.map((notebook: any) => {
              const NotebookIcon = getNotebookIcon(notebook.icon || 'folder')
              return (
                <DropdownMenuItem
                  key={notebook.id}
                  onClick={() => handleMoveToNotebook(notebook.id)}
                >
                  <NotebookIcon className="h-4 w-4 mr-2" />
                  {notebook.name}
                </DropdownMenuItem>
              )
            })}
          </DropdownMenuContent>
        </DropdownMenu>
      </div>

      {/* Pin Button - Visible on hover or if pinned */}
      <Button
        variant="ghost"
        size="sm"
        className={cn(
          "absolute top-2 right-12 z-20 min-h-[44px] min-w-[44px] 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 right-10 h-4 w-4 text-primary"
        />
      )}

      {/* Memory Echo Badges - Fusion + Connections (BEFORE Title) */}
      <div className="flex flex-wrap gap-1 mb-2">
        {/* Fusion Badge with remove button */}
        {note.autoGenerated && (
          <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">
            <Link2 className="h-2.5 w-2.5" />
            {t('memoryEcho.fused')}
            <button
              onClick={handleRemoveFusedBadge}
              className="ml-1 opacity-0 group-hover/badge:opacity-100 hover:opacity-100 transition-opacity"
              title={t('notes.remove') || 'Remove'}
            >
              <X className="h-2.5 w-2.5" />
            </button>
          </div>
        )}

        {/* Connections Badge */}
        <ConnectionsBadge
          noteId={note.id}
          onClick={() => {
            // Only open overlay if note is NOT open in editor
            // (to avoid having 2 Dialogs with 2 close buttons)
            if (!isNoteOpenInEditor) {
              setShowConnectionsOverlay(true)
            }
          }}
        />
      </div>

      {/* Title */}
      {optimisticNote.title && (
        <h3 className="text-base font-medium mb-2 pr-10 text-foreground">
          {optimisticNote.title}
        </h3>
      )}

      {/* Search Match Type Badge */}
      {optimisticNote.matchType && (
        <Badge
          variant={optimisticNote.matchType === 'exact' ? 'default' : 'secondary'}
          className={cn(
            'mb-2 text-xs',
            optimisticNote.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-blue-100 text-blue-800 border-blue-200 dark:bg-blue-900/30 dark:text-blue-300 dark:border-blue-800'
          )}
        >
          {t(`semanticSearch.${optimisticNote.matchType === 'exact' ? 'exactMatch' : 'related'}`)}
        </Badge>
      )}

      {/* Shared badge */}
      {isSharedNote && owner && (
        <div className="flex items-center justify-between mb-2">
          <span className="text-xs text-blue-600 dark:text-blue-400 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()
            }}
          >
            <X className="h-3 w-3 mr-1" />
            {t('notes.leaveShare')}
          </Button>
        </div>
      )}

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

      {/* Link Previews */}
      {optimisticNote.links && optimisticNote.links.length > 0 && (
        <div className="flex flex-col gap-2 mb-2">
          {optimisticNote.links.map((link, idx) => (
            <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-blue-500 mt-1 block">
                  {new URL(link.url).hostname}
                </span>
              </div>
            </a>
          ))}
        </div>
      )}

      {/* Content */}
      {optimisticNote.type === 'text' ? (
        <div className="text-sm text-foreground line-clamp-10">
          <MarkdownContent content={optimisticNote.content} />
        </div>
      ) : (
        <NoteChecklist
          items={optimisticNote.checkItems || []}
          onToggleItem={handleCheckItem}
        />
      )}

      {/* Labels - ONLY show if note belongs to a notebook (labels are contextual per PRD) */}
      {optimisticNote.notebookId && optimisticNote.labels && optimisticNote.labels.length > 0 && (
        <div className="flex flex-wrap gap-1 mt-3">
          {optimisticNote.labels.map((label) => (
            <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">
          {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 left-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 - Only for owner */}
      {isOwner && (
        <NoteActions
          isPinned={optimisticNote.isPinned}
          isArchived={optimisticNote.isArchived}
          currentColor={optimisticNote.color}
          currentSize={optimisticNote.size}
          onTogglePin={handleTogglePin}
          onToggleArchive={handleToggleArchive}
          onColorChange={handleColorChange}
          onSizeChange={handleSizeChange}
          onDelete={handleDelete}
          onShareCollaborators={() => setShowCollaboratorDialog(true)}
          className="absolute bottom-0 left-0 right-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 Overlay */}
      <div onClick={(e) => e.stopPropagation()}>
        <ConnectionsOverlay
          isOpen={showConnectionsOverlay}
          onClose={() => setShowConnectionsOverlay(false)}
          noteId={note.id}
          onOpenNote={(noteId) => {
            // Find the note and open it
            onEdit?.(note, false)
          }}
          onCompareNotes={(noteIds) => {
            setComparisonNotes(noteIds)
          }}
        />
      </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>
      )}
    </Card>
  )
}