'use client'

import { useState, useEffect, useCallback, useRef, type ReactNode } from 'react'
import { ChevronDown, ChevronUp, Sparkles, Link2, X, Loader2, HelpCircle } from 'lucide-react'
import { LinkedNotePreviewDialog } from '@/components/linked-note-preview-dialog'
import { Button } from '@/components/ui/button'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'
import { useLanguage } from '@/lib/i18n/LanguageProvider'
import type { BlockSuggestion } from '@/components/block-picker'
import { toast } from 'sonner'
import { useNoteEditorContext } from '@/components/note-editor/note-editor-context'
import { stripHtmlToPlainText } from '@/lib/text/plain-text'
import { detectTextDirection } from '@/lib/clip/rtl-content'

interface ConnectionData {
  noteId: string
  title: string | null
  content: string
  createdAt: Date
  similarity: number
  daysApart: number
}

interface LiveBlockRefHost {
  targetNoteId: string
  targetNoteTitle: string
  notebookName: string
  blockIds: string[]
  createdAt: string
}

interface MemoryEchoSectionProps {
  noteId: string
  onCompareNotes?: (noteIds: string[], meta?: { similarity?: number }) => void
  onMergeNotes?: (noteIds: string[]) => void
}

interface PreviewTarget {
  noteId: string
  title: string | null
  excerpt: string
}

function excerpt(text: string, max = 150): string {
  const plain = stripHtmlToPlainText(text)
  if (plain.length <= max) return plain
  return `${plain.slice(0, max).trim()}…`
}

function isRtlText(text: string): boolean {
  return detectTextDirection(text) === 'rtl'
}

async function resolveBlockForEmbed(sourceNoteId: string, hint: string): Promise<{ block: BlockSuggestion; mode: 'live' | 'citation' } | null> {
  const params = new URLSearchParams({ noteId: sourceNoteId, hint })
  const res = await fetch(`/api/blocks/resolve?${params}`)
  if (!res.ok) return null
  const data = await res.json()
  if (!data.block) return null
  return { block: data.block as BlockSuggestion, mode: data.mode === 'live' ? 'live' : 'citation' }
}

function dispatchLiveBlockInsert(block: BlockSuggestion) {
  window.dispatchEvent(new CustomEvent('memento-insert-live-block', { detail: { block } }))
}

function dispatchCitationInsert(payload: { noteId: string; noteTitle: string; excerpt: string }) {
  window.dispatchEvent(new CustomEvent('memento-insert-citation', { detail: { ...payload, atEnd: true } }))
}

function ActionWithHelp({
  label,
  help,
  children,
}: {
  label: string
  help: string
  children: ReactNode
}) {
  return (
    <Tooltip>
      <TooltipTrigger asChild>{children}</TooltipTrigger>
      <TooltipContent side="top" className="max-w-[240px] text-left">
        <p className="font-medium mb-0.5">{label}</p>
        <p className="text-background/80">{help}</p>
      </TooltipContent>
    </Tooltip>
  )
}

export function MemoryEchoSection({
  noteId,
  onCompareNotes,
  onMergeNotes,
}: MemoryEchoSectionProps) {
  const { t } = useLanguage()
  const editorCtx = useNoteEditorContext()
  const [connections, setConnections] = useState<ConnectionData[]>([])
  const [retroRefs, setRetroRefs] = useState<LiveBlockRefHost[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [isExpanded, setIsExpanded] = useState(false)
  const [isVisible, setIsVisible] = useState(true)
  const [consentRequired, setConsentRequired] = useState(false)
  const [embeddingId, setEmbeddingId] = useState<string | null>(null)
  const [helpOpen, setHelpOpen] = useState(false)
  const [previewTarget, setPreviewTarget] = useState<PreviewTarget | null>(null)
  const sectionRef = useRef<HTMLDivElement>(null)
  const [sectionInView, setSectionInView] = useState(false)
  const [cueDismissed, setCueDismissed] = useState(false)

  useEffect(() => {
    let cancelled = false
    setIsLoading(true)
    setConsentRequired(false)
    setConnections([])
    setRetroRefs([])
    setCueDismissed(false)
    setSectionInView(false)

    const load = async () => {
      try {
        const [connRes, retroRes] = await Promise.all([
          fetch(`/api/ai/echo/connections?noteId=${noteId}&limit=10`),
          fetch(`/api/notes/${noteId}/live-block-refs`),
        ])

        if (cancelled) return

        if (connRes.status === 403) {
          setConsentRequired(true)
          setConnections([])
        } else if (connRes.ok) {
          const data = await connRes.json()
          setConnections(data.connections || [])
        } else {
          setConnections([])
        }

        if (retroRes.ok) {
          const data = await retroRes.json()
          setRetroRefs(data.refs || [])
        } else {
          setRetroRefs([])
        }
      } catch (error) {
        console.error('[MemoryEchoSection] Failed to fetch:', error)
      } finally {
        if (!cancelled) setIsLoading(false)
      }
    }

    // Lazy load léger : ne bloque pas l'ouverture de la note
    const timer = window.setTimeout(() => { void load() }, 400)
    return () => {
      cancelled = true
      window.clearTimeout(timer)
    }
  }, [noteId])

  // Observe section visibility — never auto-scroll; cue only when off-screen
  useEffect(() => {
    const el = sectionRef.current
    if (!el) return

    const observer = new IntersectionObserver(
      ([entry]) => {
        setSectionInView(entry.isIntersecting && entry.intersectionRatio > 0.08)
      },
      { root: null, threshold: [0, 0.08, 0.2, 0.5] },
    )
    observer.observe(el)
    return () => observer.disconnect()
  }, [noteId, isLoading, connections.length, retroRefs.length, consentRequired, isVisible])

  const scrollToSection = useCallback(() => {
    sectionRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
  }, [])

  const handleEmbed = useCallback(async (conn: ConnectionData) => {
    setEmbeddingId(conn.noteId)
    try {
      const hint = (conn.content || '').trim().slice(0, 12000)
      const resolved = await resolveBlockForEmbed(conn.noteId, hint)
      const noteTitle = conn.title || t('memoryEcho.comparison.untitled')

      if (resolved?.mode === 'live' && resolved.block.blockId) {
        const block = resolved.block
        if (noteId) {
          try {
            await fetch('/api/blocks/embed', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                sourceNoteId: block.noteId,
                blockId: block.blockId,
                targetNoteId: noteId,
              }),
            })
          } catch {
            // non bloquant
          }
        }
        const insertedLive = editorCtx.richTextEditorRef.current?.insertLiveBlock(block, { atEnd: true })
        if (!insertedLive) {
          dispatchLiveBlockInsert(block)
        }
        if (insertedLive || editorCtx.richTextEditorRef.current?.getEditor()) {
          toast.success(t('memoryEcho.editorSection.embedSuccess'))
        } else {
          toast.error(t('memoryEcho.editorSection.embedFailed'))
        }
        return
      }

      const citationText = stripHtmlToPlainText(
        resolved?.block.content || conn.content || hint
      ).slice(0, 1200)

      if (!citationText.trim()) {
        toast.error(t('memoryEcho.editorSection.embedFailed'))
        return
      }

      const payload = { noteId: conn.noteId, noteTitle, excerpt: citationText }

      if (editorCtx.state.isMarkdown) {
        const quoted = citationText.split('\n').map(line => `> ${line}`).join('\n')
        const mdCitation = isRtlText(citationText)
          ? `\n\n<div dir="rtl" lang="fa">\n\n${quoted}\n\n— [${noteTitle}](/home?openNote=${conn.noteId})\n\n</div>\n`
          : `\n\n${quoted}\n\n— [${noteTitle}](/home?openNote=${conn.noteId})\n`
        editorCtx.actions.setContent(editorCtx.state.content + mdCitation)
        toast.success(t('memoryEcho.editorSection.citationSuccess'))
        return
      }

      const inserted = editorCtx.richTextEditorRef.current?.insertCitation(payload, { atEnd: true })
      if (inserted) {
        toast.success(t('memoryEcho.editorSection.citationSuccess'))
        return
      }

      dispatchCitationInsert(payload)
      toast.success(t('memoryEcho.editorSection.citationSuccess'))
    } catch {
      toast.error(t('memoryEcho.editorSection.embedFailed'))
    } finally {
      setEmbeddingId(null)
    }
  }, [t, noteId, editorCtx])

  if (!isVisible) return null

  const hasConnections = connections.length > 0
  const hasRetro = retroRefs.length > 0

  if (!isLoading && !hasConnections && !hasRetro && !consentRequired) {
    return null
  }

  const topConnection = connections[0]
  const restConnections = connections.slice(1)

  // Floating cue: signal activity below without stealing the title viewport
  const showBottomCue =
    !cueDismissed &&
    !sectionInView &&
    (isLoading || hasConnections || hasRetro || consentRequired)

  const cueLabel = isLoading
    ? t('memoryEcho.editorSection.bottomCueLoading')
    : hasConnections
      ? connections.length === 1
        ? t('memoryEcho.editorSection.bottomCueFoundOne')
        : t('memoryEcho.editorSection.bottomCueFound', { count: connections.length })
      : hasRetro
        ? t('memoryEcho.editorSection.bottomCueRetro', { count: retroRefs.length })
        : t('memoryEcho.editorSection.bottomCueConsent')

  return (
    <>
    <div
      id="memory-echo-section"
      ref={sectionRef}
      className="mt-10 space-y-6 scroll-mt-24"
    >
      {isLoading && (
        <div
          className="rounded-2xl border border-indigo-500/10 bg-gradient-to-br from-indigo-500/[0.03] to-transparent p-5 animate-pulse space-y-3"
          aria-busy="true"
        >
          <div className="flex items-center gap-2">
            <Sparkles className="h-4 w-4 text-indigo-400" />
            <span className="text-[10px] font-bold uppercase tracking-[0.25em] text-indigo-500/60">
              {t('memoryEcho.editorSection.badgeLabel')}
            </span>
          </div>
          <div className="h-4 bg-indigo-500/10 rounded w-3/4" />
          <div className="h-16 bg-indigo-500/5 rounded border-l-2 border-indigo-500/20" />
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <Loader2 className="h-4 w-4 animate-spin" />
            {t('memoryEcho.editorSection.loading')}
          </div>
        </div>
      )}

      {!isLoading && consentRequired && (
        <div className="rounded-2xl border border-amber-500/20 bg-amber-500/[0.04] p-4 text-sm text-muted-foreground">
          {t('memoryEcho.editorSection.consentRequired')}
        </div>
      )}

      {!isLoading && hasConnections && topConnection && (
        <div className="rounded-2xl border border-indigo-500/10 bg-gradient-to-br from-indigo-500/[0.03] to-transparent p-4 space-y-3">
          <div className="flex items-center justify-between gap-3">
            <div className="flex items-center gap-2 min-w-0">
              <Sparkles className="h-4 w-4 text-indigo-500 animate-pulse shrink-0" />
              <span className="text-[10px] font-bold uppercase tracking-[0.25em] text-indigo-600/80 dark:text-indigo-400/80 truncate">
                {t('memoryEcho.editorSection.badgeLabel')}
              </span>
              <button
                type="button"
                onClick={() => setHelpOpen(v => !v)}
                className="p-0.5 rounded-md text-indigo-500/70 hover:text-indigo-600 hover:bg-indigo-500/10 transition-colors"
                aria-expanded={helpOpen}
                aria-label={t('memoryEcho.editorSection.helpToggle')}
              >
                <HelpCircle className="h-3.5 w-3.5" />
              </button>
            </div>
            <div className="flex items-center gap-1">
              <span className="text-[11px] font-mono font-semibold px-2 py-0.5 rounded-full bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 border border-indigo-500/15">
                {t('memoryEcho.editorSection.affinityBadge', {
                  percentage: Math.round(topConnection.similarity * 100),
                })}
              </span>
              <Button
                variant="ghost"
                size="sm"
                className="h-7 w-7 p-0"
                onClick={() => setIsVisible(false)}
                title={t('memoryEcho.editorSection.close')}
              >
                <X className="h-4 w-4 text-muted-foreground" />
              </Button>
            </div>
          </div>

          <p className="text-xs text-muted-foreground hidden sm:block">
            {t('memoryEcho.editorSection.intro')}
          </p>

          {helpOpen && (
            <div className="rounded-xl border border-indigo-500/15 bg-indigo-500/[0.04] p-4 space-y-3 text-sm text-muted-foreground">
              <p className="font-medium text-foreground">{t('memoryEcho.editorSection.helpTitle')}</p>
              <ul className="space-y-2.5 list-none pl-0">
                <li><strong className="text-foreground">{t('memoryEcho.editorSection.viewLinkedNote')}</strong> — {t('memoryEcho.editorSection.helpView')}</li>
                <li><strong className="text-foreground">{t('memoryEcho.editorSection.embedPassage')}</strong> — {t('memoryEcho.editorSection.helpCite')}</li>
                <li><strong className="text-foreground">{t('memoryEcho.editorSection.compare')}</strong> — {t('memoryEcho.editorSection.helpCompare')}</li>
                <li><strong className="text-foreground">{t('memoryEcho.editorSection.merge')}</strong> — {t('memoryEcho.editorSection.helpMerge')}</li>
              </ul>
            </div>
          )}

          <blockquote
            className={cn(
              'border-indigo-500/20 pl-3 font-serif italic text-sm leading-relaxed text-foreground/85',
              isRtlText(topConnection.content) ? 'border-r-2 border-l-0 pr-3 pl-0 text-right' : 'border-l-2',
            )}
            dir={isRtlText(topConnection.content) ? 'rtl' : undefined}
            lang={isRtlText(topConnection.content) ? 'fa' : undefined}
          >
            « {excerpt(topConnection.content)} »
          </blockquote>

          <div className="flex items-center justify-between gap-2 pt-1 border-t border-indigo-500/10 flex-wrap text-[11px]">
            <span className="text-muted-foreground min-w-0 truncate">
              {t('memoryEcho.editorSection.detectedIn', {
                title: topConnection.title || t('memoryEcho.comparison.untitled'),
              })}
            </span>
            <div className="flex items-center gap-3 shrink-0">
              <ActionWithHelp
                label={t('memoryEcho.editorSection.viewLinkedNote')}
                help={t('memoryEcho.editorSection.helpView')}
              >
                <button
                  type="button"
                  className="font-semibold text-muted-foreground hover:text-foreground hover:underline transition-colors"
                  onClick={() => setPreviewTarget({
                    noteId: topConnection.noteId,
                    title: topConnection.title,
                    excerpt: excerpt(topConnection.content, 500),
                  })}
                >
                  {t('memoryEcho.editorSection.view')}
                </button>
              </ActionWithHelp>
              <ActionWithHelp
                label={t('memoryEcho.editorSection.embedPassage')}
                help={t('memoryEcho.editorSection.helpCite')}
              >
                <button
                  type="button"
                  disabled={embeddingId === topConnection.noteId}
                  className="inline-flex items-center gap-1 font-bold text-indigo-600 dark:text-indigo-400 hover:underline disabled:opacity-50"
                  onClick={() => void handleEmbed(topConnection)}
                >
                  <Link2 className="h-3 w-3" />
                  {embeddingId === topConnection.noteId
                    ? t('memoryEcho.editorSection.embedding')
                    : t('memoryEcho.editorSection.embedPassage')}
                </button>
              </ActionWithHelp>
              {onCompareNotes && (
                <ActionWithHelp
                  label={t('memoryEcho.editorSection.compare')}
                  help={t('memoryEcho.editorSection.helpCompare')}
                >
                  <button
                    type="button"
                    className="font-semibold text-muted-foreground hover:text-foreground hover:underline transition-colors"
                    onClick={() => onCompareNotes([noteId, topConnection.noteId], { similarity: topConnection.similarity })}
                  >
                    {t('memoryEcho.editorSection.compare')}
                  </button>
                </ActionWithHelp>
              )}
              {onMergeNotes && (
                <ActionWithHelp
                  label={t('memoryEcho.editorSection.merge')}
                  help={t('memoryEcho.editorSection.helpMerge')}
                >
                  <button
                    type="button"
                    className="font-semibold text-purple-600 dark:text-purple-400 hover:underline transition-colors"
                    onClick={() => onMergeNotes([noteId, topConnection.noteId])}
                  >
                    {t('memoryEcho.editorSection.merge')}
                  </button>
                </ActionWithHelp>
              )}
            </div>
          </div>

          {restConnections.length > 0 && (
            <div className="pt-2 border-t border-indigo-500/10">
              <button
                type="button"
                className="flex items-center gap-1.5 text-xs font-medium text-indigo-600 dark:text-indigo-400 hover:underline"
                onClick={() => setIsExpanded(v => !v)}
              >
                {isExpanded
                  ? t('memoryEcho.editorSection.hideAll', { count: connections.length })
                  : t('memoryEcho.editorSection.showAll', { count: connections.length })}
                {isExpanded ? <ChevronUp className="h-3.5 w-3.5" /> : <ChevronDown className="h-3.5 w-3.5" />}
              </button>

              {isExpanded && (
                <div className="mt-3 space-y-2 max-h-[280px] overflow-y-auto">
                  {restConnections.map(conn => (
                    <div
                      key={conn.noteId}
                      className="rounded-xl border border-border/60 p-3 bg-background/60 space-y-2"
                    >
                      <div className="flex items-start justify-between gap-2">
                        <h4 className="text-sm font-medium flex-1">
                          {conn.title || t('memoryEcho.comparison.untitled')}
                        </h4>
                        <span className="text-[10px] font-mono px-2 py-0.5 rounded-full bg-indigo-500/10 text-indigo-700 dark:text-indigo-300">
                          {Math.round(conn.similarity * 100)}%
                        </span>
                      </div>
                      <p className="text-xs text-muted-foreground line-clamp-2 font-serif italic">
                        « {excerpt(conn.content, 120)} »
                      </p>
                      <div className="flex items-center gap-3 text-[11px]">
                        <button
                          type="button"
                          className="font-semibold text-muted-foreground hover:text-foreground hover:underline"
                          onClick={() => setPreviewTarget({
                            noteId: conn.noteId,
                            title: conn.title,
                            excerpt: excerpt(conn.content, 500),
                          })}
                        >
                          {t('memoryEcho.editorSection.view')}
                        </button>
                        <button
                          type="button"
                          disabled={embeddingId === conn.noteId}
                          className="inline-flex items-center gap-1 font-bold text-indigo-600 dark:text-indigo-400 hover:underline disabled:opacity-50"
                          onClick={() => void handleEmbed(conn)}
                        >
                          <Link2 className="h-3 w-3" />
                          {t('memoryEcho.editorSection.embedPassage')}
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}
        </div>
      )}

      {!isLoading && hasRetro && (
        <div className="rounded-2xl border border-blue-500/10 bg-blue-500/[0.02] p-5 space-y-3">
          <div className="flex items-center gap-2">
            <span className="relative flex h-2 w-2">
              <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-60" />
              <span className="relative inline-flex rounded-full h-2 w-2 bg-blue-500" />
            </span>
            <span className="text-[10px] font-bold uppercase tracking-[0.22em] text-blue-600/80 dark:text-blue-400/80">
              {t('memoryEcho.editorSection.retroTitle')}
            </span>
          </div>
          <p className="text-sm text-muted-foreground">
            {t('memoryEcho.editorSection.retroDescription', { count: retroRefs.length })}
          </p>
          <div className="space-y-2">
            {retroRefs.map(ref => (
              <button
                key={ref.targetNoteId}
                type="button"
                onClick={() => setPreviewTarget({
                  noteId: ref.targetNoteId,
                  title: ref.targetNoteTitle,
                  excerpt: '',
                })}
                className={cn(
                  'w-full text-left rounded-xl border border-border/50 p-3',
                  'hover:bg-muted/40 transition-colors flex items-center gap-3'
                )}
              >
                <Link2 className="h-4 w-4 text-blue-500 shrink-0" />
                <div className="min-w-0 flex-1">
                  <p className="text-sm font-medium truncate">
                    {ref.targetNoteTitle || t('memoryEcho.comparison.untitled')}
                  </p>
                  {ref.notebookName && (
                    <p className="text-[11px] text-muted-foreground truncate">{ref.notebookName}</p>
                  )}
                </div>
              </button>
            ))}
          </div>
        </div>
      )}

      {previewTarget && (
        <LinkedNotePreviewDialog
          isOpen
          onClose={() => setPreviewTarget(null)}
          noteId={previewTarget.noteId}
          initialTitle={previewTarget.title}
          initialExcerpt={previewTarget.excerpt}
          citationLoading={embeddingId === previewTarget.noteId}
          onInsertCitation={() => {
            void handleEmbed({
              noteId: previewTarget.noteId,
              title: previewTarget.title,
              content: previewTarget.excerpt || connections.find(c => c.noteId === previewTarget.noteId)?.content || '',
              createdAt: new Date(),
              similarity: connections.find(c => c.noteId === previewTarget.noteId)?.similarity ?? 0,
              daysApart: 0,
            })
          }}
          onCompare={
            onCompareNotes
              ? () => onCompareNotes([noteId, previewTarget.noteId], {
                  similarity: connections.find(c => c.noteId === previewTarget.noteId)?.similarity,
                })
              : undefined
          }
          onMerge={
            onMergeNotes
              ? () => onMergeNotes([noteId, previewTarget.noteId])
              : undefined
          }
        />
      )}
    </div>

    {showBottomCue && (
      <div
        className={cn(
          'fixed bottom-6 left-1/2 z-40 -translate-x-1/2',
          'flex items-center gap-1 rounded-full border border-indigo-500/25',
          'bg-background/95 shadow-lg shadow-indigo-500/10 backdrop-blur-md',
          'pl-3 pr-1.5 py-1.5 max-w-[min(92vw,22rem)]',
          'animate-in fade-in slide-in-from-bottom-2 duration-300',
        )}
        role="status"
        aria-live="polite"
      >
        <button
          type="button"
          onClick={scrollToSection}
          className="flex min-w-0 flex-1 items-center gap-2 rounded-full px-1 py-0.5 text-left transition-colors hover:bg-indigo-500/5"
          title={t('memoryEcho.editorSection.bottomCueScroll')}
        >
          {isLoading ? (
            <Loader2 className="h-3.5 w-3.5 shrink-0 animate-spin text-indigo-500" />
          ) : (
            <Sparkles className="h-3.5 w-3.5 shrink-0 text-indigo-500" />
          )}
          <span className="truncate text-xs font-medium text-foreground/90">
            {cueLabel}
          </span>
          <ChevronDown className="h-3.5 w-3.5 shrink-0 text-indigo-500/80 animate-bounce" />
        </button>
        <button
          type="button"
          onClick={() => setCueDismissed(true)}
          className="shrink-0 rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
          aria-label={t('memoryEcho.editorSection.bottomCueDismiss')}
          title={t('memoryEcho.editorSection.bottomCueDismiss')}
        >
          <X className="h-3.5 w-3.5" />
        </button>
      </div>
    )}
    </>
  )
}

/** @deprecated Use MemoryEchoSection */
export { MemoryEchoSection as EditorConnectionsSection }
