'use client'

import { useState, useTransition, useEffect } from 'react'
import type { Note } from '@/lib/types'
import { getNoteFeedImage, getNotePlainExcerpt, getNoteDisplayTitle } from '@/lib/note-preview'
import { useLanguage } from '@/lib/i18n'
import { useRefresh } from '@/lib/use-refresh'
import { motion, AnimatePresence } from 'motion/react'
import { ChevronRight, MoreHorizontal, Trash2, Archive, Pin, History, Pencil, Sparkles, Loader2, Bell, FolderOpen } from 'lucide-react'
import { useLabelsQuery } from '@/lib/query-hooks'
import { useSession } from 'next-auth/react'
import { getAISettings } from '@/app/actions/ai-settings'
import { generateNoteIllustrationSvg } from '@/app/actions/note-illustration'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
} from '@/components/ui/dropdown-menu'
import { deleteNote, toggleArchive, togglePin, updateNote } from '@/app/actions/notes'
import { ReminderDialog } from '@/components/reminder-dialog'
import { useNotebooks } from '@/context/notebooks-context'
import { toast } from 'sonner'

type NotesEditorialViewProps = {
  notes: Note[]
  onOpen: (note: Note, readOnly?: boolean) => void
  notebookName?: string
  onOpenHistory?: (note: Note) => void
}

function formatNoteDate(date: Date | string): string {
  const d = typeof date === 'string' ? new Date(date) : date
  return d.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  }).toUpperCase()
}

function EditorialNoteMenu({ note, onOpen, onOpenHistory }: {
  note: Note
  onOpen: (note: Note) => void
  onOpenHistory?: (note: Note) => void
}) {
  const { t } = useLanguage()
  const { refreshNotes } = useRefresh()
  const { notebooks } = useNotebooks()
  const [, startTransition] = useTransition()
  const [showReminder, setShowReminder] = useState(false)

  const handleDelete = (e: React.MouseEvent) => {
    e.stopPropagation()
    startTransition(async () => {
      try {
        await deleteNote(note.id)
        refreshNotes(note?.notebookId)
        toast.success(t('notes.deleted') || 'Note supprimée')
      } catch {
        toast.error(t('general.error'))
      }
    })
  }

  const handleArchive = (e: React.MouseEvent) => {
    e.stopPropagation()
    startTransition(async () => {
      try {
        await toggleArchive(note.id, !note.isArchived)
        refreshNotes(note?.notebookId)
        toast.success(note.isArchived ? (t('notes.unarchived') || 'Désarchivée') : (t('notes.archived') || 'Archivée'))
      } catch {
        toast.error(t('general.error'))
      }
    })
  }

  const handlePin = (e: React.MouseEvent) => {
    e.stopPropagation()
    startTransition(async () => {
      try {
        await togglePin(note.id, !note.isPinned)
        refreshNotes(note?.notebookId)
      } catch {
        toast.error(t('general.error'))
      }
    })
  }

  const handleMoveToNotebook = (notebookId: string | null) => {
    startTransition(async () => {
      try {
        await updateNote(note.id, { notebookId })
        refreshNotes(note?.notebookId)
        toast.success(t('notebookSuggestion.movedToNotebook') || 'Note déplacée')
      } catch {
        toast.error(t('general.error'))
      }
    })
  }

  return (
    <>
      <DropdownMenu>
        <DropdownMenuTrigger asChild onClick={e => e.stopPropagation()}>
          <button className="opacity-0 group-hover:opacity-100 transition-opacity p-1.5 rounded-md hover:bg-muted/60 text-muted-foreground hover:text-foreground">
            <MoreHorizontal size={15} />
          </button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" className="w-52">
          <DropdownMenuItem onClick={e => { e.stopPropagation(); onOpen(note) }}>
            <Pencil className="h-4 w-4 mr-2 text-foreground/50" />
            {t('notes.open') || 'Ouvrir'}
          </DropdownMenuItem>
          <DropdownMenuItem onClick={handlePin}>
            <Pin className="h-4 w-4 mr-2 text-foreground/50" />
            {note.isPinned ? (t('notes.unpin') || 'Désépingler') : (t('notes.pin') || 'Épingler')}
          </DropdownMenuItem>
          <DropdownMenuItem onClick={handleArchive}>
            <Archive className="h-4 w-4 mr-2 text-foreground/50" />
            {note.isArchived ? (t('notes.unarchive') || 'Désarchiver') : (t('notes.archive') || 'Archiver')}
          </DropdownMenuItem>
          {onOpenHistory && (
            <DropdownMenuItem onClick={e => { e.stopPropagation(); onOpenHistory(note) }}>
              <History className="h-4 w-4 mr-2 text-foreground/50" />
              {t('notes.history') || 'Historique'}
            </DropdownMenuItem>
          )}

          {/* Rappel */}
          <DropdownMenuItem onClick={e => { e.stopPropagation(); setShowReminder(true) }}>
            <Bell className="h-4 w-4 mr-2 text-foreground/50" />
            {note.reminder
              ? (t('reminder.changeReminder') || 'Modifier le rappel')
              : (t('reminder.setReminder') || 'Définir un rappel')}
          </DropdownMenuItem>

          {/* Déplacer vers un carnet */}
          <DropdownMenuSub>
            <DropdownMenuSubTrigger onClick={e => e.stopPropagation()}>
              <FolderOpen className="h-4 w-4 mr-2 text-foreground/50" />
              {t('notebookSuggestion.moveToNotebook') || 'Déplacer vers…'}
            </DropdownMenuSubTrigger>
            <DropdownMenuSubContent className="w-52">
              <DropdownMenuItem onClick={e => { e.stopPropagation(); handleMoveToNotebook(null) }}>
                <span className="w-4 h-4 rounded-full bg-foreground text-background flex items-center justify-center text-[9px] font-semibold mr-2 shrink-0">N</span>
                {t('notebookSuggestion.generalNotes') || 'Notes générales'}
              </DropdownMenuItem>
              {notebooks.map((nb: any) => (
                <DropdownMenuItem key={nb.id} onClick={e => { e.stopPropagation(); handleMoveToNotebook(nb.id) }}>
                  <span className="w-4 h-4 rounded-full bg-foreground text-background flex items-center justify-center text-[9px] font-semibold mr-2 shrink-0">{nb.name.charAt(0).toUpperCase()}</span>
                  {nb.name}
                </DropdownMenuItem>
              ))}
            </DropdownMenuSubContent>
          </DropdownMenuSub>

          <DropdownMenuSeparator />
          <DropdownMenuItem onClick={handleDelete} className="text-destructive focus:text-destructive focus:bg-destructive/10">
            <Trash2 className="h-4 w-4 mr-2" />
            {t('notes.delete') || 'Supprimer'}
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      {/* ReminderDialog hors du DropdownMenu pour éviter les conflits de portail */}
      <ReminderDialog
        open={showReminder}
        onOpenChange={setShowReminder}
        currentReminder={note.reminder ? new Date(note.reminder) : null}
        onSave={(date) => {
          startTransition(async () => {
            await updateNote(note.id, { reminder: date })
            refreshNotes(note?.notebookId)
            setShowReminder(false)
          })
        }}
        onRemove={() => {
          startTransition(async () => {
            await updateNote(note.id, { reminder: null })
            refreshNotes(note?.notebookId)
            setShowReminder(false)
          })
        }}
      />
    </>
  )
}

/** Deterministic hue from a string — consistent per note */
function stringToHue(s: string): number {
  let h = 0
  for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) & 0xffff
  return h % 360
}

function EditorialThumbnail({
  note,
  title,
  aiIllustrationEnabled,
}: {
  note: Note
  title: string
  aiIllustrationEnabled: boolean
}) {
  const { t } = useLanguage()
  const { refreshNotes } = useRefresh()
  const [busy, setBusy] = useState(false)
  const img = getNoteFeedImage(note)

  const handleGenerateSvg = async (e: React.MouseEvent) => {
    e.stopPropagation()
    if (!aiIllustrationEnabled || busy || img) return
    setBusy(true)
    try {
      const res = await generateNoteIllustrationSvg(note.id)
      if (!res.ok) {
        toast.error(res.error)
      } else {
        toast.success(t('notes.illustrationGenerated') || 'Illustration générée')
        refreshNotes(note?.notebookId)
      }
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="relative w-full md:w-56 aspect-[4/3] bg-card/80 border border-border overflow-hidden rounded shadow-sm flex-shrink-0 group/thumb">
      {img ? (
        <img
          src={img}
          alt=""
          className="w-full h-full object-cover mix-blend-multiply opacity-80 grayscale contrast-125 hover:grayscale-0 hover:opacity-100 transition-all duration-500"
        />
      ) : note.illustrationSvg ? (
        <div
          className="w-full h-full flex items-center justify-center bg-muted/30 p-2 [&_svg]:max-w-full [&_svg]:max-h-full [&_svg]:w-auto [&_svg]:h-auto"
          // SVG déjà sanitisé côté serveur (note-illustration.ts)
          dangerouslySetInnerHTML={{ __html: note.illustrationSvg }}
          aria-hidden
        />
      ) : (
        <>
          <NoteThumbnailPlaceholder title={title} noteId={note.id} />
          {aiIllustrationEnabled && (
            <button
              type="button"
              aria-label={t('notes.generateIllustration') || 'Générer une illustration IA'}
              title={t('notes.generateIllustration') || 'Générer une illustration IA'}
              className="absolute bottom-2 right-2 flex h-9 w-9 items-center justify-center rounded-full border border-border bg-background/95 text-foreground shadow-card-rest backdrop-blur-sm transition-colors hover:bg-accent z-10 opacity-0 group-hover/thumb:opacity-100 md:opacity-100 focus-visible:opacity-100"
              onClick={handleGenerateSvg}
              disabled={busy}
            >
              {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : <Sparkles className="h-4 w-4 text-primary" />}
            </button>
          )}
        </>
      )}
    </div>
  )
}

/** SVG thumbnail for notes without an image */
function NoteThumbnailPlaceholder({ title, noteId }: { title: string; noteId: string }) {
  // Try to extract the first emoji from the title
  const emojiMatch = title.match(/\p{Emoji_Presentation}|\p{Emoji}\uFE0F/u)
  const emoji = emojiMatch?.[0]
  const letter = title.replace(/\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu, '').trim()[0]?.toUpperCase() || '?'
  const hue = stringToHue(noteId)

  return (
    <div
      className="h-full w-full flex items-center justify-center relative overflow-hidden"
      style={{ background: `linear-gradient(145deg, hsl(${hue} 25% var(--thumb-lightness-1, 94%)) 0%, hsl(${hue} 18% var(--thumb-lightness-2, 87%)) 100%)` }}
    >
      {/* Decorative concentric circles */}
      <svg
        className="absolute inset-0 w-full h-full"
        viewBox="0 0 224 168"
        fill="none"
        aria-hidden
        style={{ color: `hsl(${hue} 30% 60%)` }}
      >
        <circle cx="112" cy="84" r="90" stroke="currentColor" strokeWidth="0.6" opacity="0.25" />
        <circle cx="112" cy="84" r="64" stroke="currentColor" strokeWidth="0.6" opacity="0.2" />
        <circle cx="112" cy="84" r="38" stroke="currentColor" strokeWidth="0.6" opacity="0.15" />
        <line x1="22" y1="84" x2="202" y2="84" stroke="currentColor" strokeWidth="0.4" opacity="0.15" />
        <line x1="112" y1="4" x2="112" y2="164" stroke="currentColor" strokeWidth="0.4" opacity="0.15" />
      </svg>
      {emoji ? (
        <span
          className="relative text-5xl leading-none select-none"
          style={{ filter: `drop-shadow(0 2px 8px hsl(${hue} 40% 40% / 0.2))` }}
        >
          {emoji}
        </span>
      ) : (
        <span
          className="relative font-memento-serif font-bold select-none leading-none"
          style={{
            fontSize: '4.5rem',
            color: `hsl(${hue} 35% 35%)`,
            opacity: 0.35,
          }}
        >
          {letter}
        </span>
      )}
    </div>
  )
}

function NoteTag({ labelName, allLabels }: { labelName: string; allLabels: any[] }) {
  const labelDef = allLabels?.find(l => l.name === labelName)
  const isAI = labelDef?.type === 'ai'
  
  return (
    <div className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md bg-paper dark:bg-white/5 text-[9px] font-bold uppercase tracking-[0.15em] text-muted-foreground border border-border/40">
      {isAI && <Sparkles size={8} className="text-blueprint" />}
      {labelName}
    </div>
  )
}

export function NotesEditorialView({
  notes,
  onOpen,
  notebookName,
  onOpenHistory,
}: NotesEditorialViewProps) {
  const { t } = useLanguage()
  const { data: session } = useSession()
  const { data: allLabels } = useLabelsQuery()
  const [aiIllustrationEnabled, setAiIllustrationEnabled] = useState(false)

  useEffect(() => {
    if (!session?.user?.id) {
      setAiIllustrationEnabled(false)
      return
    }
    getAISettings(session.user.id)
      .then((s) => setAiIllustrationEnabled(s.paragraphRefactor !== false))
      .catch(() => setAiIllustrationEnabled(false))
  }, [session?.user?.id])

  return (
    <div className="mx-auto w-full max-w-3xl space-y-8">
      <AnimatePresence>
        {notes.map((note: Note, index: number) => {
          const title = getNoteDisplayTitle(note, t('notes.untitled') || 'Untitled')
          const excerpt = getNotePlainExcerpt(note)
          const dateStr = formatNoteDate(note.createdAt)

          return (
            <motion.article
              key={note.id}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ delay: 0.05 * index, duration: 0.6 }}
              className="space-y-4 group cursor-pointer relative pb-8"
              onClick={() => onOpen(note)}
            >
              {/* Date / breadcrumb */}
              <div className="note-date-badge">
                {notebookName ? `${notebookName} — ${dateStr}` : dateStr}
              </div>

              {/* Actions menu — absolutely positioned at top-right */}
              <div
                className="absolute top-0 right-0 opacity-0 group-hover:opacity-100 transition-opacity"
                onClick={e => e.stopPropagation()}
              >
                <EditorialNoteMenu note={note} onOpen={onOpen} onOpenHistory={onOpenHistory} />
              </div>

              <h2 className="font-memento-serif text-2xl font-medium text-foreground flex items-center justify-between">
                {title}
                <span className="opacity-0 group-hover:opacity-30 transition-opacity shrink-0">
                  <ChevronRight size={20} />
                </span>
              </h2>

              <div className="flex flex-col md:flex-row gap-8 items-start">
                <EditorialThumbnail note={note} title={title} aiIllustrationEnabled={aiIllustrationEnabled} />
                <div className="space-y-3 flex-1">
                  {note.labels && note.labels.length > 0 && (
                    <div className="flex flex-wrap gap-2">
                      {note.labels.slice(0, 2).map((labelName) => (
                        <NoteTag key={labelName} labelName={labelName} allLabels={allLabels || []} />
                      ))}
                    </div>
                  )}
                  {excerpt ? (
                    <p className="text-[14px] leading-relaxed text-foreground/80 font-light max-w-lg line-clamp-4">
                      {excerpt}
                    </p>
                  ) : (
                    <p className="text-sm italic text-muted-foreground/50">{t('notes.noContent')}</p>
                  )}
                  <span className="text-[11px] text-muted-foreground uppercase tracking-widest font-medium inline-flex items-center gap-1 group-hover:gap-2 transition-all">
                    {t('notes.readMore') || 'Read more'}
                    <ChevronRight size={10} />
                  </span>
                </div>
              </div>
            </motion.article>
          )
        })}
      </AnimatePresence>
    </div>
  )
}
