'use client'

import { useRef, useEffect, useState } from 'react'
import { useChat } from '@ai-sdk/react'
import { DefaultChatTransport } from 'ai'
import type { UIMessage } from 'ai'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {
  X, Bot, Sparkles, Send, Loader2, Square,
  Briefcase, Palette, GraduationCap, Coffee,
  Lightbulb, Minimize2, AlignLeft, Wand2,
  Globe, BookOpen, FileText, RotateCcw, Check,
  Maximize2, ImageIcon, Link2, Download, ArrowDownToLine,
  GitMerge, PlusCircle, Eye, Code, Languages,
  Presentation, PenTool, ExternalLink, ImagePlus,
  ChevronRight, MessageSquare, History, Scissors, Zap, Layout, ArrowRightLeft,
} from 'lucide-react'
import { motion, AnimatePresence } from 'motion/react'
import { exportExcalidrawSceneToPngBlob } from '@/lib/client/excalidraw-export-image'
import { useLanguage } from '@/lib/i18n'
import { MarkdownContent } from '@/components/markdown-content'
import { toast } from 'sonner'

// ── Custom Toast Helper ──────────────────────────────────────────────────────
const mToast = {
  success: (msg: string, options?: any) => toast.success(msg, { 
    ...options, 
    className: 'memento-toast memento-toast-success',
  }),
  error: (msg: string, options?: any) => toast.error(msg, { 
    ...options, 
    className: 'memento-toast memento-toast-error',
  }),
  loading: (msg: string, options?: any) => toast.loading(msg, { 
    ...options, 
    className: 'memento-toast memento-toast-info',
  }),
}
import { useWebSearchAvailable } from '@/hooks/use-web-search-available'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { getNotebookIcon } from '@/lib/notebook-icon'
import { scrapePageText } from '@/app/actions/scrape'

// ── Helpers ──────────────────────────────────────────────────────────────────

function getMessageContent(msg: UIMessage): string {
  if (typeof (msg as any).content === 'string') return (msg as any).content
  if (msg.parts && Array.isArray(msg.parts)) {
    return msg.parts
      .filter((p: any) => p.type === 'text')
      .map((p: any) => p.text)
      .join('')
  }
  return ''
}

// ── Constants ─────────────────────────────────────────────────────────────────

const TONES = [
  { id: 'professional', label: 'PRO',      full: 'Professional', icon: Briefcase },
  { id: 'creative',     label: 'CRE',      full: 'Creative',     icon: Palette },
  { id: 'academic',     label: 'ACA',      full: 'Academic',     icon: GraduationCap },
  { id: 'casual',       label: 'CAS',      full: 'Casual',       icon: Coffee },
]

interface ActionDef {
  id: string
  icon: any
  apiPath: string
  body: (content: string, images?: string[], lang?: string, format?: string) => any
  resultKey: string
  i18nKey: string
  isImageAction?: boolean
}

const ACTION_IDS = [
  { id: 'clarify', icon: Lightbulb, apiPath: '/api/ai/reformulate', body: (content: string, _images?: string[], lang?: string, format?: string) => ({ text: content, option: 'clarify', language: lang || 'fr', format: format || 'markdown' }), resultKey: 'reformulatedText', i18nKey: 'ai.action.clarify' },
  { id: 'shorten', icon: Minimize2, apiPath: '/api/ai/reformulate', body: (content: string, _images?: string[], lang?: string, format?: string) => ({ text: content, option: 'shorten', language: lang || 'fr', format: format || 'markdown' }), resultKey: 'reformulatedText', i18nKey: 'ai.action.shorten' },
  { id: 'improve', icon: AlignLeft, apiPath: '/api/ai/reformulate', body: (content: string, _images?: string[], lang?: string, format?: string) => ({ text: content, option: 'improve', language: lang || 'fr', format: format || 'markdown' }), resultKey: 'reformulatedText', i18nKey: 'ai.action.improve' },
  { id: 'translate', icon: Languages, apiPath: '/api/ai/reformulate', body: (content: string, _images?: string[], lang?: string, format?: string) => ({ text: content, option: 'translate', language: lang || 'fr', format: format || 'markdown' }), resultKey: 'reformulatedText', i18nKey: 'ai.action.translate' },
  { id: 'markdown', icon: Wand2, apiPath: '/api/ai/transform-markdown', body: (content: string, _images?: string[], _lang?: string, _format?: string) => ({ text: content }), resultKey: 'transformedText', i18nKey: 'ai.action.toMarkdown' },
  { id: 'toRichText', icon: Wand2, apiPath: '/api/ai/convert-markdown', body: (content: string, _images?: string[], _lang?: string, _format?: string) => ({ content }), resultKey: 'html', i18nKey: 'ai.action.toRichText' },
  { id: 'describe-images', icon: ImageIcon, apiPath: '/api/ai/describe-image', body: (_content: string, images?: string[], lang?: string, _format?: string) => ({ imageUrls: images || [], mode: 'description', language: lang || 'fr' }), resultKey: 'descriptions', i18nKey: 'ai.action.describeImages', isImageAction: true },
]

// ── Types ─────────────────────────────────────────────────────────────────────

interface GenerateResult {
  type: 'slides' | 'diagram'
  canvasId?: string
  noteId?: string
}

interface ContextualAIChatProps {
  onClose: () => void
  noteTitle?: string
  noteContent?: string
  noteImages?: string[]
  noteId?: string
  /** Called when an action result should be injected into the note */
  onApplyToNote?: (newContent: string) => void
  /** Called when the user wants to undo the last injected action */
  onUndoLastAction?: () => void
  /** Whether the last action has been applied (so we can show undo) */
  lastActionApplied?: boolean
  /** Notebooks available for scope selection */
  notebooks?: Array<{ id: string; name: string }>
  /** Extra classes forwarded to the aside root element */
  className?: string
  /** How to embed generated diagram images (markdown vs rich text HTML) */
  diagramInsertFormat?: 'markdown' | 'html'
  /** Called to trigger AI title generation for the note */
  onGenerateTitle?: () => void
}

// ── Component ─────────────────────────────────────────────────────────────────

export function ContextualAIChat({
  onClose,
  noteTitle,
  noteContent,
  noteImages,
  noteId,
  onApplyToNote,
  onUndoLastAction,
  lastActionApplied = false,
  notebooks = [],
  className,
  diagramInsertFormat = 'markdown',
  onGenerateTitle,
}: ContextualAIChatProps) {
  const { t, language } = useLanguage()
  const webSearchAvailable = useWebSearchAvailable()

  const [activeTab, setActiveTab]           = useState<'chat' | 'actions' | 'resource'>('actions')
  const [selectedTone, setSelectedTone]     = useState('professional')
  const [input, setInput]                   = useState('')
  const [chatScope, setChatScope]           = useState<'note' | 'all' | string>('note')
  const [webSearch, setWebSearch]           = useState(false)
  const [expanded, setExpanded]             = useState(false)

  // Action state
  const [actionLoading, setActionLoading]   = useState<string | null>(null)
  const [actionPreview, setActionPreview]   = useState<{ label: string; text: string } | null>(null)
  const [showLangPicker, setShowLangPicker] = useState(false)
  const [translateTarget, setTranslateTarget] = useState('')

  // Generate slides / diagram state
  const [generateLoading, setGenerateLoading] = useState<'slides' | 'diagram' | null>(null)
  const [generateResult, setGenerateResult]   = useState<GenerateResult | null>(null)
  const [customLangInput, setCustomLangInput] = useState('')
  // Generation options
  const [slideTheme,   setSlideTheme]   = useState('architectural_mono')
  const [slideStyle,   setSlideStyle]   = useState('professional')
  const [diagramType,  setDiagramType]  = useState('logic_flow')
  const [diagramStyle, setDiagramStyle] = useState('polished')
  const [diagramEmbedLoading, setDiagramEmbedLoading] = useState(false)

  // Resource tab state
  const [resourceUrl, setResourceUrl]       = useState('')
  const [resourceText, setResourceText]     = useState('')
  const [resourceScraping, setResourceScraping] = useState(false)
  const [resourceMode, setResourceMode]     = useState<'replace' | 'complete' | 'merge'>('complete')
  const [resourcePreview, setResourcePreview] = useState<{ text: string; source: string } | null>(null)
  const [resourceEnriching, setResourceEnriching] = useState(false)
  const [resourcePreviewFormat, setResourcePreviewFormat] = useState<'rendered' | 'markdown'>('rendered')
  // hoveredMsgId: which chat message shows inject actions
  const [hoveredMsgId, setHoveredMsgId]     = useState<string | null>(null)

  const messagesEndRef = useRef<HTMLDivElement>(null)

  const transport = useRef(new DefaultChatTransport({ api: '/api/chat' })).current

  const buildChatBody = () => {
    const body: Record<string, any> = { 
      language, 
      webSearch,
      format: diagramInsertFormat || 'markdown'
    }
    if (chatScope === 'note') {
      body.noteContext = {
        title: noteTitle || '',
        content: noteContent || '',
        tone: selectedTone,
        images: noteImages || [],
      }
    } else if (chatScope !== 'all') {
      // scope is a notebook ID
      body.notebookId = chatScope
    }
    return body
  }

  const { messages, sendMessage, status, stop } = useChat({ transport })

  const lastMsg = messages[messages.length - 1]
  const lastMsgHasContent = lastMsg?.role === 'assistant' && !!getMessageContent(lastMsg)
  const isLoading = (status === 'submitted' || status === 'streaming') && !lastMsgHasContent

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [messages, resourcePreview])

  useEffect(() => {
    window.dispatchEvent(new CustomEvent('contextual-ai-visibility', { detail: true }))
    return () => {
      window.dispatchEvent(new CustomEvent('contextual-ai-visibility', { detail: false }))
    }
  }, [])

  // ── Chat send ───────────────────────────────────────────────────────────────
  const handleSend = async () => {
    const text = input.trim()
    if (!text || isLoading) return
    setInput('')
    try {
      await sendMessage({ text }, { body: buildChatBody() })
    } catch (error) {
      console.error('Chat send error:', error)
      toast.error(t('chat.assistantError') || 'Failed to send message')
    }
  }

  // ── Action execution ────────────────────────────────────────────────────────
  const handleAction = async (action: ActionDef, targetLang?: string) => {
    if (action.isImageAction) {
      if (!noteImages || noteImages.length === 0) {
        mToast.error(t('ai.noImagesError') || 'Aucune image dans cette note')
        return
      }
      setActionLoading(action.id)
      setActionPreview(null)
      try {
        const res = await fetch(action.apiPath, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(action.body('', noteImages, language)),
        })
        const data = await res.json()
        if (!res.ok) throw new Error(data.error || t('ai.genericError'))
        const descs = data.descriptions || []
        let resultText = descs.map((d: any) =>
          noteImages.length > 1 ? `**Image ${d.index + 1}:** ${d.description}` : d.description
        ).join('\n\n')
        if (data.combinedSummary) {
          resultText += `\n\n---\n**Résumé:** ${data.combinedSummary}`
        }
        setActionPreview({ label: t(action.i18nKey), text: resultText })
      } catch (e: any) {
        mToast.error(e.message || t('ai.actionError'))
      } finally {
        setActionLoading(null)
      }
      return
    }

    const wc = (noteContent || '').split(/\s+/).filter(Boolean).length
    if (!noteContent || wc < 5) {
      mToast.error(t('ai.minWordsError'))
      return
    }
    setActionLoading(action.id)
    setActionPreview(null)
    try {
      const format = diagramInsertFormat || 'markdown'
      const res = await fetch(action.apiPath, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(action.body(noteContent, undefined, targetLang || language, format)),
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data.error || t('ai.genericError'))
      const result = data[action.resultKey] || ''
      setActionPreview({ label: t(action.i18nKey), text: result })
    } catch (e: any) {
      mToast.error(e.message || t('ai.actionError'))
    } finally {
      setActionLoading(null)
    }
  }

  const handleApplyPreview = () => {
    if (!actionPreview || !onApplyToNote) return
    onApplyToNote(actionPreview.text)
    setActionPreview(null)
    mToast.success(t('ai.appliedToNote'))
  }

  const handleDiscardPreview = () => setActionPreview(null)

  // ── Generate slides / diagram ────────────────────────────────────────────────

  const generatePollRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const handleGenerate = async (type: 'slides' | 'diagram') => {
    if (!noteId) {
      mToast.error(t('ai.generate.noNoteId') || 'Note non sauvegardée')
      return
    }
    setGenerateLoading(type)
    setGenerateResult(null)

    const toastId = mToast.loading(
      type === 'slides' ? '⏳ Génération de la présentation...' : '⏳ Génération du diagramme...',
      { duration: Infinity }
    )

    try {
      const res = await fetch('/api/agents/run-for-note', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          noteId,
          type: type === 'slides' ? 'slide-generator' : 'excalidraw-generator',
          theme: type === 'slides' ? slideTheme : diagramType,
          style: type === 'slides' ? slideStyle : diagramStyle,
          language: language === 'fr' ? 'French' : 'English',
        }),
      })
      const data = await res.json()
      if (!res.ok || !data.success) {
        mToast.error(data.error || 'Erreur', { id: toastId })
        setGenerateLoading(null)
        return
      }

      const { agentId } = data as { agentId: string }

      if (generatePollRef.current) clearInterval(generatePollRef.current)
      generatePollRef.current = setInterval(async () => {
        try {
          const pollRes = await fetch(`/api/agents/run-for-note?agentId=${agentId}`)
          const poll = await pollRes.json()

          if (poll.status === 'success') {
            clearInterval(generatePollRef.current!)
            generatePollRef.current = null
            setGenerateLoading(null)
            setGenerateResult({ type, canvasId: poll.canvasId, noteId: poll.noteId })
            mToast.success('Prêt !', { id: toastId })
          } else if (poll.status === 'failure') {
            clearInterval(generatePollRef.current!)
            generatePollRef.current = null
            setGenerateLoading(null)
            mToast.error(poll.error || 'Erreur', { id: toastId })
          }
        } catch { }
      }, 3000)
    } catch {
      mToast.error('Erreur', { id: toastId })
      setGenerateLoading(null)
    }
  }

  const buildDiagramImageSnippet = (imageUrl: string, alt: string) => {
    if (diagramInsertFormat === 'html') {
      return `\n<p><img src="${imageUrl}" alt="${alt}" loading="lazy" style="max-width:100%;height:auto;border-radius:8px;" /></p>\n`
    }
    return `\n\n![${alt}](${imageUrl})\n\n`
  }

  const handleEmbedDiagramInNote = async (canvasId: string) => {
    if (!onApplyToNote) return
    setDiagramEmbedLoading(true)
    try {
      const res = await fetch(`/api/canvas?id=${encodeURIComponent(canvasId)}`)
      const data = await res.json()
      if (!res.ok || !data.canvas?.data) throw new Error()
      const blob = await exportExcalidrawSceneToPngBlob(data.canvas.data)
      if (!blob) throw new Error()
      const fd = new FormData()
      fd.append('file', blob, `diagram-${canvasId.slice(-8)}.png`)
      const up = await fetch('/api/upload', { method: 'POST', body: fd })
      const upJson = await up.json()
      if (!up.ok || !upJson.url) throw new Error()
      const alt = t('ai.generate.diagramImageAlt')
      onApplyToNote(`${noteContent ?? ''}${buildDiagramImageSnippet(upJson.url as string, alt)}`)
      mToast.success(t('ai.generate.insertedInNote'))
    } catch (e) {
      mToast.error(t('ai.generate.insertExportError'))
    } finally {
      setDiagramEmbedLoading(false)
    }
  }

  // ── Resource tab handlers ────────────────────────────────────────────────────

  const handleScrapeUrl = async () => {
    if (!resourceUrl.trim()) return
    setResourceScraping(true)
    try {
      const result = await scrapePageText(resourceUrl.trim())
      if (!result) { mToast.error(t('ai.resource.failedToLoadUrl')); return }
      setResourceText(result.text)
      mToast.success(t('ai.resource.pageLoaded', { title: result.title.slice(0, 40) }))
    } catch {
      mToast.error(t('ai.resource.pageLoadError'))
    } finally {
      setResourceScraping(false)
    }
  }

  const handleResourcePreview = async () => {
    if (!resourceText.trim()) { mToast.error(t('ai.resource.pasteOrUrlFirst')); return }
    if (resourceMode === 'replace') {
      setResourcePreview({ text: resourceText, source: 'paste' })
      return
    }

    setResourceEnriching(true)
    try {
      const res = await fetch('/api/ai/enrich-from-resource', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          existingContent: noteContent || '',
          resourceText: resourceText.trim(),
          mode: resourceMode,
          language,
          format: diagramInsertFormat || 'markdown',
        }),
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data.error || t('ai.resource.enrichError'))
      setResourcePreview({ text: data.enrichedContent, source: resourceMode })
    } catch (e: any) {
      mToast.error(e.message || t('ai.resource.enrichError'))
    } finally {
      setResourceEnriching(false)
    }
  }

  const handleApplyResourcePreview = () => {
    if (!resourcePreview || !onApplyToNote) return
    onApplyToNote(resourcePreview.text)
    setResourcePreview(null)
    setResourceText('')
    setResourceUrl('')
    mToast.success(t('ai.resource.contentApplied'))
  }

  const handleInjectFromChat = async (msgText: string, mode: 'replace' | 'complete' | 'merge') => {
    setResourceText(msgText)
    setResourceMode(mode)
    
    if (mode === 'replace') {
      setResourcePreview({ text: msgText, source: 'chat' })
      return
    }

    setResourceEnriching(true)
    try {
      const res = await fetch('/api/ai/enrich-from-resource', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          existingContent: noteContent || '',
          resourceText: msgText,
          mode,
          language,
          format: diagramInsertFormat || 'markdown',
        }),
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data.error || 'Erreur IA')
      setResourcePreview({ text: data.enrichedContent, source: mode })
    } catch (e: any) {
      mToast.error(e.message || t('ai.resource.enrichErrorShort'))
    } finally {
      setResourceEnriching(false)
    }
  }

  return (
    <>
      {expanded && (
        <div
          className="fixed inset-0 z-[199] bg-foreground/40 backdrop-blur-sm"
          onClick={() => setExpanded(false)}
        />
      )}
      <aside className={cn(
        'border-l border-border bg-background flex flex-col flex-shrink-0 z-10 transition-all duration-300 shadow-2xl',
        expanded
          ? 'fixed right-0 top-0 h-screen w-[640px] z-[200]'
          : 'h-full w-[360px]',
        !expanded && className,
      )}>

        <div className="p-6 border-b border-border shrink-0">
          <div className="flex items-start justify-between">
            <div className="min-w-0 space-y-2">
              <h2 className="font-serif text-xl font-medium text-foreground flex items-center gap-2 leading-tight">
                <Sparkles className="h-[18px] w-[18px] shrink-0 text-memento-accent" />
                IA Assistant
              </h2>
              <p className="text-[11px] text-foreground/60 uppercase tracking-wider font-medium opacity-60 truncate">
                "{noteTitle || t('ai.currentNote')}"
              </p>
            </div>
            <div className="flex items-center gap-1 shrink-0 -mt-1">
              <button
                onClick={() => setExpanded(e => !e)}
                className="p-1.5 hover:bg-muted/60 rounded-full transition-colors text-foreground/40"
                title={expanded ? t('ai.shrinkPanel') : t('ai.expandPanel')}
              >
                {expanded ? <Minimize2 size={18} /> : <Maximize2 size={18} />}
              </button>
              <button 
                onClick={onClose}
                className="p-1.5 hover:bg-muted/60 rounded-full transition-colors text-foreground/40 group"
              >
                <div className="relative w-5 h-5 flex items-center justify-center">
                  <ChevronRight size={20} className="transition-all duration-200 group-hover:opacity-0 group-hover:scale-0" />
                  <X size={18} className="absolute inset-0 m-auto opacity-0 scale-0 transition-all duration-200 group-hover:opacity-100 group-hover:scale-100" />
                </div>
              </button>
            </div>
          </div>
        </div>

        <div className="flex border-b border-border shrink-0 px-2">
          {[
            { id: 'actions',  label: 'Actions',          icon: <Sparkles size={16} /> },
            { id: 'chat',     label: 'Discussion',       icon: <MessageSquare size={16} /> },
            { id: 'resource', label: 'Ressource',        icon: <Link2 size={16} /> },
          ].map(tab => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id as any)}
              className={cn(
                "flex-1 flex items-center justify-center gap-2 py-3.5 text-[10px] font-bold uppercase tracking-[0.2em] transition-all relative",
                activeTab === tab.id ? 'text-foreground' : 'text-foreground/60 hover:text-foreground'
              )}
            >
              {tab.label}
              {activeTab === tab.id && (
                <motion.div layoutId="activeTab" className="absolute bottom-0 left-0 right-0 h-[2px] bg-memento-blue" />
              )}
            </button>
          ))}
        </div>

        <div className="flex-1 flex flex-col min-h-0 relative">
          {actionPreview && (
            <div className="absolute inset-0 z-20 flex flex-col bg-background/95 backdrop-blur-md animate-in fade-in slide-in-from-top-4 duration-300">
              <div className="px-6 py-4 border-b border-border flex items-center justify-between shrink-0">
                <p className="text-[10px] font-bold uppercase tracking-widest text-memento-blue">{actionPreview.label}</p>
                <button onClick={handleDiscardPreview} className="text-foreground/40 hover:text-foreground"><X size={18} /></button>
              </div>
              <div className="flex-1 overflow-y-auto p-6 custom-scrollbar">
                <div className="bg-card/60 backdrop-blur-sm border border-border p-6 rounded-2xl shadow-sm leading-relaxed text-sm">
                  <MarkdownContent content={actionPreview.text} />
                </div>
              </div>
              <div className="p-6 border-t border-border flex gap-3 shrink-0">
                <button onClick={handleDiscardPreview} className="flex-1 py-3.5 text-[10px] font-bold uppercase tracking-widest text-foreground/40 hover:text-foreground transition-all">ANNULER</button>
                <button onClick={handleApplyPreview} className="flex-1 py-3.5 bg-foreground text-background rounded-xl text-[10px] font-bold uppercase tracking-widest shadow-lg transition-all hover:opacity-90">APPLIQUER À LA NOTE</button>
              </div>
            </div>
          )}

          {resourcePreview && (
            <div className="absolute inset-0 z-20 flex flex-col bg-background/95 backdrop-blur-md animate-in fade-in slide-in-from-top-4 duration-300">
              <div className="px-6 py-4 border-b border-border/40 flex items-center justify-between shrink-0">
                <p className="text-[10px] font-bold uppercase tracking-widest text-memento-blue">
                  {resourcePreview.source === 'chat' ? 'Injecter depuis Discussion' : 'Aperçu IA'}
                </p>
                <button onClick={() => setResourcePreview(null)} className="text-foreground/40 hover:text-foreground">
                  <X size={18} />
                </button>
              </div>
              <div className="flex-1 overflow-y-auto p-6 custom-scrollbar">
                <div className="bg-card/60 backdrop-blur-sm border border-border p-6 rounded-2xl shadow-sm leading-relaxed text-sm">
                  <MarkdownContent content={resourcePreview.text} />
                </div>
              </div>
              <div className="p-6 border-t border-border flex gap-3 shrink-0">
                <button onClick={() => setResourcePreview(null)} className="flex-1 py-3.5 text-[10px] font-bold uppercase tracking-widest text-foreground/40 hover:text-foreground transition-all">ANNULER</button>
                <button onClick={handleApplyResourcePreview} className="flex-1 py-3.5 bg-memento-blue text-white rounded-xl text-[10px] font-bold uppercase tracking-widest shadow-lg shadow-memento-blue/20 transition-all hover:opacity-90">APPLIQUER À LA NOTE</button>
              </div>
            </div>
          )}

          <AnimatePresence mode="wait">
            {activeTab === 'chat' && (
              <motion.div 
                key="chat"
                initial={{ opacity: 0, x: 20 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -20 }}
                className="flex flex-col flex-1 min-h-0"
              >
                <div className="flex-1 overflow-y-auto p-6 custom-scrollbar space-y-8">
                  {messages.length === 0 && (
                    <div className="h-full flex flex-col items-center justify-center text-center space-y-6 py-12">
                      <div className="w-20 h-20 rounded-full bg-card/40 backdrop-blur-sm border border-dashed border-border flex items-center justify-center shadow-sm">
                        <MessageSquare size={32} className="text-memento-blue/60" />
                      </div>
                      <p className="text-xs font-serif italic text-foreground/40 leading-relaxed max-w-[200px]">Posez une question à l'Assistant pour commencer.</p>
                    </div>
                  )}
                  {messages.map((msg: UIMessage) => {
                    const content = getMessageContent(msg)
                    if (msg.role === 'assistant' && !content) return null
                    const isAssistant = msg.role === 'assistant'
                    return (
                      <div key={msg.id} className={cn('flex flex-col gap-3', !isAssistant && 'items-end')} onMouseEnter={() => isAssistant && setHoveredMsgId(msg.id)} onMouseLeave={() => setHoveredMsgId(null)}>
                        <div className="relative group max-w-[95%]">
                          <div className={cn('p-5 rounded-2xl text-sm leading-relaxed transition-all shadow-sm', !isAssistant ? 'bg-foreground text-background' : 'bg-card/60 backdrop-blur-sm border border-border text-foreground')}>
                            {isAssistant ? <MarkdownContent content={content} /> : <p className="font-medium">{content}</p>}
                          </div>
                          {isAssistant && onApplyToNote && (hoveredMsgId === msg.id || messages.at(-1)?.id === msg.id) && (
                            <div className="flex gap-2 mt-3 opacity-0 group-hover:opacity-100 transition-all">
                              <button onClick={() => handleInjectFromChat(content, 'replace')} className="px-3 py-1.5 rounded-lg text-[9px] font-bold uppercase tracking-widest bg-foreground text-background hover:opacity-90">REPLACER</button>
                              <button onClick={() => handleInjectFromChat(content, 'complete')} className="px-3 py-1.5 rounded-lg text-[9px] font-bold uppercase tracking-widest bg-card/40 backdrop-blur-sm border border-border text-foreground hover:bg-card/60">COMPLÉTER</button>
                              <button onClick={() => handleInjectFromChat(content, 'merge')} className="px-3 py-1.5 rounded-lg text-[9px] font-bold uppercase tracking-widest bg-card/40 backdrop-blur-sm border border-border text-foreground hover:bg-card/60">FUSIONNER</button>
                            </div>
                          )}
                        </div>
                      </div>
                    )
                  })}
                  {isLoading && (
                    <div className="flex flex-col gap-3">
                      <div className="bg-card/60 backdrop-blur-sm border border-border p-5 rounded-2xl shadow-sm w-fit">
                        <div className="flex gap-1.5"><span className="w-1.5 h-1.5 bg-memento-blue rounded-full animate-pulse" /><span className="w-1.5 h-1.5 bg-memento-blue rounded-full animate-pulse delay-75" /><span className="w-1.5 h-1.5 bg-memento-blue rounded-full animate-pulse delay-150" /></div>
                      </div>
                    </div>
                  )}
                  <div ref={messagesEndRef} />
                </div>
                
                {/* ── Chat Footer: Context + Tone + Input ── */}
                <div className="px-6 py-8 border-t border-border shrink-0 space-y-6">
                  <div className="grid grid-cols-2 gap-4">
                    <div className="space-y-3">
                      <label className="text-[10px] uppercase tracking-[0.25em] font-bold text-foreground/40 px-1">CONTEXTE</label>
                      <Select value={chatScope} onValueChange={setChatScope}>
                        <SelectTrigger className="w-full h-10 px-3 bg-card/60 backdrop-blur-sm border border-border rounded-xl text-[11px] flex items-center justify-between cursor-pointer hover:border-foreground/20 transition-all outline-none ring-0 shadow-sm text-foreground">
                          <div className="flex items-center gap-2">
                            <BookOpen size={14} className="text-foreground/40" />
                            <SelectValue />
                          </div>
                        </SelectTrigger>
                        <SelectContent className="rounded-xl border-border shadow-xl bg-background">
                          <SelectItem value="note" className="text-[11px] py-2.5 uppercase tracking-wider font-bold">Cette note</SelectItem>
                          <SelectItem value="all" className="text-[11px] py-2.5 uppercase tracking-wider font-bold">Tout Momento</SelectItem>
                          {notebooks.map(nb => (
                            <SelectItem key={nb.id} value={nb.id} className="text-[11px] py-2.5 uppercase tracking-wider font-bold">{nb.name}</SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                    <div className="space-y-3">
                      <label className="text-[10px] uppercase tracking-[0.25em] font-bold text-foreground/40 px-1">TON D'ÉCRITURE</label>
                      <div className="grid grid-cols-4 gap-1.5">
                        {TONES.map((tone) => {
                          const Icon = tone.icon
                          const isActive = selectedTone === tone.id
                          return (
                            <button 
                              key={tone.id} 
                              onClick={() => setSelectedTone(tone.id)} 
                              className={cn(
                                'h-[52px] rounded-xl border transition-all flex flex-col items-center justify-center gap-1.5 shadow-sm',
                                isActive 
                                  ? 'bg-memento-blue/10 border-memento-blue text-memento-blue' 
                                  : 'bg-card/60 border-border text-foreground/40 hover:border-foreground/20'
                              )}
                            >
                              <Icon size={14} className={isActive ? 'text-memento-blue' : 'text-foreground/40'} />
                              <span className="text-[9px] font-bold uppercase tracking-tight">{tone.label}</span>
                            </button>
                          )
                        })}
                      </div>
                    </div>
                  </div>
                  
                  <div className="relative">
                    <textarea
                      rows={4}
                      className="w-full bg-card/60 border border-border rounded-2xl p-5 pr-14 text-sm outline-none focus:border-memento-blue transition-all resize-none leading-relaxed font-light custom-scrollbar shadow-sm text-foreground"
                      placeholder="Posez votre question sur cette note..."
                      value={input}
                      onChange={e => setInput(e.target.value)}
                      onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend() } }}
                      disabled={isLoading}
                    />
                    <div className="absolute right-4 bottom-4 flex gap-2">
                      <button 
                        onClick={() => setWebSearch(!webSearch)}
                        className={cn("p-2.5 rounded-xl transition-colors", webSearch ? "text-memento-blue bg-memento-blue/10" : "text-foreground/20 hover:text-foreground")}
                        title="Web Search"
                      >
                        <Globe size={18} />
                      </button>
                      <button onClick={handleSend} disabled={!input.trim() || isLoading} className="p-2.5 bg-memento-blue text-white rounded-xl transition-all hover:scale-105 active:scale-95 shadow-lg shadow-memento-blue/20 disabled:opacity-30">
                        <Send size={18} />
                      </button>
                    </div>
                  </div>
                  <p className="text-[9px] text-foreground/30 text-center mt-2 uppercase tracking-[0.2em] font-bold italic">Maj+Entrée = nouvelle ligne</p>
                </div>
              </motion.div>
            )}

            {activeTab === 'actions' && (
              <motion.div 
                key="actions"
                initial={{ opacity: 0, x: 20 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -20 }}
                className="flex flex-col flex-1 overflow-y-auto p-6 space-y-10 custom-scrollbar"
              >
                <div className="space-y-6">
                  <div className="flex items-center gap-2">
                    <div className="h-px flex-1 bg-border/40" />
                    <h4 className="text-[9px] uppercase tracking-[0.3em] font-bold text-foreground/40 whitespace-nowrap">{t('ai.transformations')}</h4>
                    <div className="h-px flex-1 bg-border/40" />
                  </div>

                  {lastActionApplied && onUndoLastAction && (
                    <motion.button
                      initial={{ opacity: 0, y: -10 }}
                      animate={{ opacity: 1, y: 0 }}
                      onClick={onUndoLastAction}
                      className="w-full py-3.5 bg-memento-blue/20 border border-memento-blue/50 rounded-xl flex items-center justify-center gap-2 text-[11px] font-bold text-memento-blue uppercase tracking-[0.2em] hover:bg-memento-blue/30 transition-all shadow-md"
                    >
                      <RotateCcw size={12} /> {t('ai.undoLastAction')}
                    </motion.button>
                  )}
                  <div className="grid grid-cols-2 gap-3">
                    {ACTION_IDS.filter(a => a.id !== 'markdown' && a.id !== 'describe-images').map((action, i) => {
                      const loading = actionLoading === action.id
                      const isActive = action.id === 'translate' && showLangPicker
                      const Icon = action.icon
                      return (
                        <button key={i} onClick={() => action.id === 'translate' ? setShowLangPicker(v => !v) : handleAction(action)} disabled={!!actionLoading}                         className={cn("flex flex-col items-center gap-3 p-4 bg-card/40 backdrop-blur-sm border rounded-xl transition-all group shadow-sm", isActive ? "border-memento-blue bg-memento-blue/5" : "border-border hover:border-foreground/20")}>
                          <div className={cn("p-2 rounded-lg bg-card/60 transition-colors group-hover:bg-foreground group-hover:text-background shadow-sm", loading && "animate-pulse", isActive && "bg-memento-blue text-white")}>
                            {loading ? <Loader2 size={14} className="animate-spin" /> : <Icon size={14} />}
                          </div>
                          <span className={cn("text-[10px] font-bold uppercase tracking-widest", isActive ? "text-memento-blue" : "text-foreground/80")}>{t(action.i18nKey)}</span>
                        </button>
                      )
                    })}

                    <AnimatePresence mode="wait">
                      {showLangPicker && (
                        <motion.div 
                          key="lang-picker"
                          initial={{ height: 0, opacity: 0 }}
                          animate={{ height: 'auto', opacity: 1 }}
                          exit={{ height: 0, opacity: 0 }}
                          className="col-span-2 overflow-hidden"
                        >
                          <div className="mt-2 p-5 bg-card/40 backdrop-blur-sm border border-memento-blue/30 rounded-2xl space-y-5 shadow-sm">
                            <div className="grid grid-cols-3 gap-2">
                              {['Français', 'English', 'Español', 'Deutsch', 'Persan', 'Portugais', 'Italiano', 'Chinois', 'Japonais'].map((lang) => (
                                <button
                                  key={lang}
                                  onClick={() => setTranslateTarget(lang)}
                                  className={cn(
                                    "py-2 px-1 rounded-lg border text-[10px] font-bold uppercase tracking-tighter transition-all",
                                    translateTarget === lang 
                                      ? "bg-memento-blue border-memento-blue text-white shadow-md shadow-memento-blue/20" 
                                      : "bg-card/60 border-border text-foreground/60 hover:border-foreground/20"
                                  )}
                                >
                                  {lang}
                                </button>
                              ))}
                            </div>
                            
                            <div className="space-y-2">
                              <span className="text-[8px] uppercase tracking-[0.2em] font-bold text-foreground/40 px-1">{t('ai.otherLanguage')}</span>
                              <input 
                                type="text"
                                value={customLangInput}
                                onChange={(e) => {
                                  setCustomLangInput(e.target.value)
                                  setTranslateTarget(e.target.value)
                                }}
                                placeholder="ex: Arabe, Russe..."
                                className="w-full bg-card/60 border border-border rounded-xl px-4 py-2.5 text-[11px] outline-none focus:border-memento-blue transition-all text-foreground"
                              />
                            </div>

                            <button 
                              onClick={() => handleAction(ACTION_IDS.find(a => a.id === 'translate')!, translateTarget)}
                              disabled={!translateTarget || !!actionLoading}
                              className="w-full py-3 bg-memento-blue text-white rounded-xl text-[10px] font-bold uppercase tracking-[0.2em] flex items-center justify-center gap-2 hover:opacity-90 disabled:opacity-50 shadow-lg shadow-memento-blue/20"
                            >
                              <Languages size={14} /> {t('ai.translateNow')}
                            </button>
                          </div>
                        </motion.div>
                      )}
                    </AnimatePresence>

                    {diagramInsertFormat === 'html' ? (
                      <button 
                        onClick={() => handleAction(ACTION_IDS.find(a => a.id === 'markdown')!)} 
                        disabled={!!actionLoading}
                        className="col-span-2 flex items-center justify-center gap-3 py-3.5 bg-card/40 backdrop-blur-sm border border-border rounded-xl text-[10px] font-bold text-foreground/80 hover:bg-card/60 transition-all uppercase tracking-[0.2em] shadow-sm disabled:opacity-50"
                      >
                        <Code size={14} className="text-foreground/40" /> 
                        {actionLoading === 'markdown' ? <Loader2 size={14} className="animate-spin" /> : t('ai.action.toMarkdown')}
                      </button>
                    ) : (
                      <button 
                        onClick={() => handleAction(ACTION_IDS.find(a => a.id === 'toRichText')!)} 
                        disabled={!!actionLoading}
                        className="col-span-2 flex items-center justify-center gap-3 py-3.5 bg-card/40 backdrop-blur-sm border border-border rounded-xl text-[10px] font-bold text-foreground/80 hover:bg-card/60 transition-all uppercase tracking-[0.2em] shadow-sm disabled:opacity-50"
                      >
                        <Wand2 size={14} className="text-foreground/40" /> 
                        {actionLoading === 'toRichText' ? <Loader2 size={14} className="animate-spin" /> : t('ai.action.toRichText')}
                      </button>
                    )}
                  </div>
                </div>

                <div className="space-y-6">
                  <div className="flex items-center gap-2">
                    <div className="h-px flex-1 bg-border/40" />
                    <h4 className="text-[9px] uppercase tracking-[0.3em] font-bold text-foreground/40 whitespace-nowrap">{t('ai.generationTools')}</h4>
                    <div className="h-px flex-1 bg-border/40" />
                  </div>

                  <div className="group relative p-6 rounded-2xl bg-card/40 backdrop-blur-sm border border-border hover:border-memento-blue/30 transition-all duration-500 overflow-hidden shadow-sm">
                    <div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity">
                      <Layout size={80} className="text-memento-blue" />
                    </div>
                    <div className="relative space-y-5">
                      <div className="flex items-center gap-3">
                        <div className="p-2 bg-card/60 rounded-lg text-memento-blue"><Layout size={18} /></div>
                        <div className="space-y-0.5">
                          <h5 className="text-sm font-bold text-foreground leading-none">{t('ai.generate.slides')}</h5>
                          <p className="text-[9px] text-foreground/40 uppercase tracking-tight">{t('ai.generate.sectionLabel')}</p>
                        </div>
                      </div>
                      <div className="grid grid-cols-2 gap-3">
                        <div className="space-y-1.5">
                          <span className="text-[8px] uppercase tracking-[0.2em] font-bold text-foreground/40 px-1">{t('ai.generate.theme')}</span>
                           <select value={slideTheme} onChange={e => setSlideTheme(e.target.value)} className="w-full bg-card/60 border border-border rounded-lg px-2 py-2 text-[10px] outline-none focus:ring-1 ring-memento-blue/10 transition-all cursor-pointer text-foreground">
                            <option value="architectural_mono">{t('ai.generate.themeArchitecturalMono')}</option>
                            <option value="vibrant_tech">{t('ai.generate.themeVibrantTech')}</option>
                            <option value="minimal_silk">{t('ai.generate.themeMinimalSilk')}</option>
                          </select>
                        </div>
                        <div className="space-y-1.5">
                          <span className="text-[8px] uppercase tracking-[0.2em] font-bold text-foreground/40 px-1">{t('ai.generate.style')}</span>
                           <select value={slideStyle} onChange={e => setSlideStyle(e.target.value)} className="w-full bg-card/60 border border-border rounded-lg px-2 py-2 text-[10px] outline-none focus:ring-1 ring-memento-blue/10 transition-all cursor-pointer text-foreground">
                            <option value="professional">{t('ai.generate.styleProfessional')}</option>
                            <option value="creative">Creative</option>
                            <option value="brutalist">Brutalist</option>
                          </select>
                        </div>
                      </div>
                      <button onClick={() => handleGenerate('slides')} disabled={!!generateLoading} className="w-full py-3.5 bg-memento-blue text-white rounded-xl text-[10px] font-bold flex items-center justify-center gap-2 hover:opacity-90 transition-all shadow-lg shadow-memento-blue/20 uppercase tracking-[0.2em] disabled:opacity-50">
                        {generateLoading === 'slides' ? <Loader2 size={14} className="animate-spin" /> : <><Presentation size={14} className="opacity-80" /> {t('ai.generating')}</>}
                      </button>

                      {generateResult?.type === 'slides' && generateResult.canvasId && (
                          <motion.div
                            initial={{ opacity: 0, y: 10 }}
                            animate={{ opacity: 1, y: 0 }}
                            className="mt-4 p-4 bg-memento-blue/10 border border-memento-blue/20 rounded-xl space-y-3"
                          >
                            <div className="flex items-center justify-between">
                              <span className="text-[9px] font-bold text-memento-blue uppercase tracking-widest flex items-center gap-1.5">
                              <Check size={12} /> Présentation prête
                            </span>
                            <a
                              href={`/lab?id=${generateResult.canvasId}`}
                              target="_blank"
                              rel="noopener noreferrer"
                              className="p-1.5 bg-card/60 rounded-lg text-foreground/50 hover:text-foreground hover:bg-card transition-colors"
                              title="Voir dans L'Atelier"
                            >
                              <ExternalLink size={12} />
                            </a>
                          </div>
                          <button
                            onClick={async () => {
                              try {
                                const res = await fetch(`/api/canvas?id=${generateResult.canvasId}`)
                                const data = await res.json()
                                if (!data.canvas?.data) throw new Error('No data')
                                const parsed = JSON.parse(data.canvas.data)
                                if (!parsed.base64) throw new Error('No base64')
                                const byteChars = atob(parsed.base64)
                                const bytes = new Uint8Array(byteChars.length)
                                for (let i = 0; i < byteChars.length; i++) bytes[i] = byteChars.charCodeAt(i)
                                const blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' })
                                const url = URL.createObjectURL(blob)
                                const a = document.createElement('a')
                                a.href = url
                                a.download = parsed.filename || `${data.canvas.name || 'presentation'}.pptx`
                                document.body.appendChild(a)
                                a.click()
                                document.body.removeChild(a)
                                URL.revokeObjectURL(url)
                              } catch {
                                mToast.error('Échec du téléchargement')
                              }
                            }}
                            className="flex items-center justify-center gap-2 w-full py-2.5 bg-memento-blue text-white rounded-lg text-[10px] font-bold uppercase tracking-[0.15em] hover:opacity-90 transition-opacity shadow-sm"
                          >
                            <Download size={13} />
                            Télécharger .pptx
                          </button>
                        </motion.div>
                      )}

                    </div>
                  </div>

                  <div className="group relative p-6 rounded-2xl bg-card/40 backdrop-blur-sm border border-border hover:border-primary/30 transition-all duration-500 overflow-hidden shadow-sm">
                    <div className="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition-opacity">
                      <BookOpen size={80} className="text-primary" />
                    </div>
                    <div className="relative space-y-5">
                      <div className="flex items-center gap-3">
                        <div className="p-2 bg-card/60 rounded-lg text-primary"><BookOpen size={18} /></div>
                        <div className="space-y-0.5">
                          <h5 className="text-sm font-bold text-foreground leading-none">{t('ai.generate.diagram')}</h5>
                          <p className="text-[9px] text-foreground/40 uppercase tracking-tight">{t('ai.generate.diagramReadyHint')}</p>
                        </div>
                      </div>
                      <div className="grid grid-cols-2 gap-3">
                        <div className="space-y-1.5">
                          <span className="text-[8px] uppercase tracking-[0.2em] font-bold text-foreground/40 px-1">{t('ai.generate.diagramType')}</span>
                           <select value={diagramType} onChange={e => setDiagramType(e.target.value)} className="w-full bg-card/60 border border-border rounded-lg px-2 py-2 text-[10px] outline-none focus:ring-1 ring-primary/10 transition-all cursor-pointer text-foreground">
                            <option value="auto">{t('ai.generate.typeAuto')}</option>
                            <option value="flowchart">{t('ai.generate.typeFlowchart')}</option>
                            <option value="mind_map">{t('ai.generate.typeMindMap')}</option>
                            <option value="timeline">{t('ai.generate.typeTimeline')}</option>
                            <option value="org_chart">{t('ai.generate.typeOrgChart')}</option>
                            <option value="architecture">{t('ai.generate.typeArchitecture')}</option>
                            <option value="process_map">{t('ai.generate.typeProcessMap')}</option>
                          </select>
                        </div>
                        <div className="space-y-1.5">
                          <span className="text-[8px] uppercase tracking-[0.2em] font-bold text-foreground/40 px-1">{t('ai.generate.style')}</span>
                           <select value={diagramStyle} onChange={e => setDiagramStyle(e.target.value)} className="w-full bg-card/60 border border-border rounded-lg px-2 py-2 text-[10px] outline-none focus:ring-1 ring-primary/10 transition-all cursor-pointer text-foreground">
                            <option value="sketchy">{t('ai.generate.styleSketchy')}</option>
                            <option value="soft">{t('ai.generate.styleSoft')}</option>
                            <option value="minimal">{t('ai.generate.styleMinimal')}</option>
                            <option value="professional">{t('ai.generate.styleProfessional')}</option>
                            <option value="draft">{t('ai.generate.styleDraft')}</option>
                            <option value="polished">{t('ai.generate.stylePolished')}</option>
                            <option value="handwritten">{t('ai.generate.styleHandwritten')}</option>
                          </select>
                        </div>
                      </div>
                      <button onClick={() => handleGenerate('diagram')} disabled={!!generateLoading}                        className="w-full py-3.5 bg-primary text-primary-foreground rounded-xl text-[10px] font-bold flex items-center justify-center gap-2 hover:opacity-90 transition-all shadow-lg shadow-primary/20 uppercase tracking-[0.2em] disabled:opacity-50">
                        {generateLoading === 'diagram' ? <Loader2 size={14} className="animate-spin" /> : <>{t('ai.generating')} <ArrowRightLeft size={14} className="opacity-60" /></>}
                      </button>

                      {generateResult?.type === 'diagram' && generateResult.canvasId && (
                        <motion.div 
                          initial={{ opacity: 0, y: 10 }}
                          animate={{ opacity: 1, y: 0 }}
                          className="mt-4 p-4 bg-primary/10 border border-primary/20 rounded-xl space-y-3"
                        >
                          <div className="flex items-center justify-between">
                            <span className="text-[9px] font-bold text-primary uppercase tracking-widest">{t('ai.generate.diagramReady')}</span>
                            <div className="flex gap-2">
                              <a 
                                href={`/lab?id=${generateResult.canvasId}`}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="p-2 bg-card/60 rounded-lg text-foreground hover:bg-card transition-colors"
                                title={t('ai.generate.openInExcalidraw')}
                              >
                                <ExternalLink size={14} />
                              </a>
                              <button 
                                onClick={() => handleEmbedDiagramInNote(generateResult.canvasId!)}
                                disabled={diagramEmbedLoading}
                                className="p-2 bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50"
                                title={t('ai.generate.insertDiagramInNote')}
                              >
                                {diagramEmbedLoading ? <Loader2 size={14} className="animate-spin" /> : <ImagePlus size={14} />}
                              </button>
                            </div>
                          </div>
                        </motion.div>
                      )}
                    </div>
                  </div>
                </div>

                <div className="flex flex-col items-center gap-4 py-8 opacity-20">
                   <PenTool size={20} />
                    <span className="text-[9px] font-bold uppercase tracking-[0.3em] whitespace-nowrap italic text-center">{t('nav.workspace')}</span>
                </div>
              </motion.div>
            )}

            {activeTab === 'resource' && (
              <motion.div 
                key="resource"
                initial={{ opacity: 0, x: 20 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -20 }}
                className="flex flex-col flex-1 min-h-0 overflow-y-auto p-6 space-y-8 custom-scrollbar"
              >
                <div className="space-y-6">
                  <div className="space-y-3">
                    <label className="text-[9px] uppercase tracking-[0.3em] font-bold text-foreground/40">{t('ai.resource.urlLabel')}</label>
                    <div className="relative">
                      <input type="text" placeholder="https://..." className="w-full bg-card/40 backdrop-blur-sm border border-border rounded-xl pl-4 pr-12 py-3.5 text-xs outline-none focus:border-memento-blue transition-colors shadow-sm text-foreground" value={resourceUrl} onChange={e => setResourceUrl(e.target.value)} />
                      <Globe size={16} className="absolute right-4 top-1/2 -translate-y-1/2 text-foreground/20" />
                    </div>
                  </div>
                  <div className="space-y-3">
                    <label className="text-[9px] uppercase tracking-[0.3em] font-bold text-foreground/40">{t('ai.resource.resourceText')}</label>
                     <textarea rows={10} placeholder={t('ai.resource.resourcePlaceholder')} className="w-full bg-card/40 backdrop-blur-sm border border-border rounded-xl p-5 text-sm outline-none focus:border-memento-blue transition-colors resize-none leading-relaxed font-light shadow-sm text-foreground" value={resourceText} onChange={e => setResourceText(e.target.value)} />
                  </div>
                  <div className="space-y-4">
                    <label className="text-[9px] uppercase tracking-[0.3em] font-bold text-foreground/40">{t('ai.resource.integrationMode')}</label>
                    <div className="grid grid-cols-3 gap-2">
                       {[
                        { id: 'replace', label: t('ai.resource.modeReplace'), sub: t('ai.resource.modeReplaceDesc') },
                        { id: 'complete', label: t('ai.resource.modeComplete'), sub: t('ai.resource.modeCompleteDesc') },
                        { id: 'merge', label: t('ai.resource.modeMerge'), sub: t('ai.resource.modeMergeDesc') },
                      ].map((mode) => (
                        <button key={mode.id} onClick={() => setResourceMode(mode.id as any)} className={cn("flex flex-col items-center justify-center p-3 rounded-xl border transition-all text-center", resourceMode === mode.id ? 'bg-memento-blue/10 border-memento-blue ring-1 ring-memento-blue/20' : 'bg-card/40 backdrop-blur-sm border-border hover:bg-card/60 shadow-sm')}>
                           <span className={cn("text-[10px] font-bold uppercase tracking-wider", resourceMode === mode.id ? 'text-memento-blue' : 'text-foreground')}>{mode.label}</span>
                           <span className="text-[8px] text-foreground/40 leading-tight mt-1 font-medium">{mode.sub}</span>
                        </button>
                      ))}
                    </div>
                  </div>
                  <button onClick={handleResourcePreview} disabled={resourceEnriching || resourceScraping || !resourceText.trim()} className="w-full py-4 bg-memento-blue text-white rounded-xl text-[11px] font-bold uppercase tracking-[0.2em] flex items-center justify-center gap-3 hover:opacity-90 transition-opacity shadow-lg shadow-memento-blue/20 disabled:opacity-50">
                    {resourceEnriching || resourceScraping ? <Loader2 size={18} className="animate-spin" /> : <Sparkles size={18} />}
                    {t('ai.resource.generatePreview')}
                  </button>
                </div>
              </motion.div>
            )}
          </AnimatePresence>
        </div>
      </aside>
    </>
  )
}
