'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,
} from 'lucide-react'
import { useLanguage } from '@/lib/i18n'
import { MarkdownContent } from '@/components/markdown-content'
import { toast } from 'sonner'
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: 'Create',   full: 'Creative',     icon: Palette },
  { id: 'academic',     label: 'Acad.',    full: 'Academic',     icon: GraduationCap },
  { id: 'casual',       label: 'Casual',   full: 'Casual',       icon: Coffee },
]

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

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

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

interface ContextualAIChatProps {
  onClose: () => void
  noteTitle?: string
  noteContent?: string
  noteImages?: 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
}

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

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

  const [activeTab, setActiveTab]           = useState<'chat' | 'actions' | 'resource'>('chat')
  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('')
  const [customLangInput, setCustomLangInput] = useState('')

  // 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 }
    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('')
    await sendMessage({ text }, { body: buildChatBody() })
  }

  // ── Action execution ────────────────────────────────────────────────────────
  const handleAction = async (action: ActionDef, targetLang?: string) => {
    // Image-specific action
    if (action.isImageAction) {
      if (!noteImages || noteImages.length === 0) {
        toast.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'))
        // Format image descriptions for preview
        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**${t('ai.overview') || 'Résumé'}:** ${data.combinedSummary}`
        }
        setActionPreview({ label: t(action.i18nKey), text: resultText })
      } catch (e: any) {
        toast.error(e.message || t('ai.actionError'))
      } finally {
        setActionLoading(null)
      }
      return
    }

    // Text-based actions
    const wc = (noteContent || '').split(/\s+/).filter(Boolean).length
    if (!noteContent || wc < 5) {
      toast.error(t('ai.minWordsError'))
      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(noteContent, undefined, targetLang || language)),
      })
      const data = await res.json()
      if (!res.ok) {
        // Use i18n key if provided by the server
        if (data.errorKey) {
          throw new Error(t(data.errorKey, data.params || {}))
        }
        throw new Error(data.error || t('ai.genericError'))
      }
      const result = data[action.resultKey] || ''
      setActionPreview({ label: t(action.i18nKey), text: result })
    } catch (e: any) {
      toast.error(e.message || t('ai.actionError'))
    } finally {
      setActionLoading(null)
    }
  }

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

  const handleDiscardPreview = () => setActionPreview(null)

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

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

  const handleResourcePreview = async () => {
    if (!resourceText.trim()) { toast.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,
        }),
      })
      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) {
      toast.error(e.message || t('ai.resource.enrichError'))
    } finally {
      setResourceEnriching(false)
    }
  }

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

  /** Called from chat hover-actions: inject a chat message into the note */
  const handleInjectFromChat = async (msgText: string, mode: 'replace' | 'complete' | 'merge') => {
    if (mode === 'replace') {
      // Stay on chat tab — show preview inline via resourcePreview without switching tabs
      setResourceText(msgText)
      setResourceMode('replace')
      setResourcePreview({ text: msgText, source: 'chat' })
      return
    }
    setResourceText(msgText)
    setResourceMode(mode)
    // Do NOT switch tabs — enrich and show preview in current tab
    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,
        }),
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data.error || 'Erreur IA')
      setResourcePreview({ text: data.enrichedContent, source: mode })
    } catch (e: any) {
      toast.error(e.message || t('ai.resource.enrichErrorShort'))
    } finally {
      setResourceEnriching(false)
    }
  }

  // ── Scope label ─────────────────────────────────────────────────────────────
  const scopeLabel =
    chatScope === 'note' ? t('ai.thisNote')
    : chatScope === 'all' ? t('ai.allMyNotes')
    : notebooks.find(n => n.id === chatScope)?.name ?? t('ai.notebookGeneric')


  return (
    <aside className={cn(
      'border-l border-border/40 bg-card flex flex-col self-stretch flex-shrink-0 z-10 transition-all duration-300',
      expanded ? 'w-[560px]' : 'w-[360px]',
      className,
    )}>

      {/* ── Header ───────────────────────────────────────────────── */}
      <div className="px-4 py-3 border-b border-border/40 flex items-center justify-between shrink-0">
        <div className="min-w-0">
          <h2 className="text-base font-semibold text-foreground flex items-center gap-2">
            <Sparkles className="h-4 w-4 text-primary shrink-0" />
            {t('ai.aiNoteTitle')}
          </h2>
          <p className="text-xs text-muted-foreground truncate">
            {noteTitle ? `"${noteTitle}"` : t('ai.currentNote')}
          </p>
        </div>
        <div className="flex items-center gap-0.5 shrink-0">
          {lastActionApplied && onUndoLastAction && (
            <Button
              variant="ghost" size="icon"
              className="h-7 w-7 text-amber-500 hover:text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-950/30"
              onClick={onUndoLastAction}
              title={t('ai.undoLastAction')}
            >
              <RotateCcw className="h-3.5 w-3.5" />
            </Button>
          )}
          {/* Expand / Shrink */}
          <Button
            variant="ghost" size="icon"
            className="h-7 w-7 text-muted-foreground hover:text-foreground"
            onClick={() => setExpanded(e => !e)}
            title={expanded ? t('ai.shrinkPanel') : t('ai.expandPanel')}
          >
            {expanded
              ? <Minimize2 className="h-3.5 w-3.5" />
              : <Maximize2 className="h-3.5 w-3.5" />}
          </Button>
          <Button variant="ghost" size="icon" onClick={onClose} className="h-7 w-7 text-muted-foreground hover:text-foreground">
            <X className="h-3.5 w-3.5" />
          </Button>
        </div>
      </div>

      {/* ── Tabs ─────────────────────────────────────────────────── */}
      <div className="flex border-b border-border/40 shrink-0">
        {([
          { id: 'chat',     icon: Bot,           label: t('ai.chatTab') },
          { id: 'actions',  icon: Wand2,          label: t('ai.noteActions') },
          { id: 'resource', icon: ArrowDownToLine, label: t('ai.resourceTab') },
        ] as const).map(tab => (
          <button
            key={tab.id}
            onClick={() => setActiveTab(tab.id as any)}
            className={cn(
              'flex-1 py-2.5 border-b-2 text-xs font-semibold flex items-center justify-center gap-1.5 transition-all',
              activeTab === tab.id
                ? 'border-primary text-primary'
                : 'border-transparent text-muted-foreground hover:text-foreground',
            )}
          >
            <tab.icon className="h-3 w-3" />
            {tab.label}
          </button>
        ))}
      </div>

      {/* ══════════════════════════════════════════════════════════ */}
      {/* ── TAB: CHAT ─────────────────────────────────────────── */}
      {/* ══════════════════════════════════════════════════════════ */}
      {activeTab === 'chat' && (
        <div className="flex flex-col flex-1 min-h-0 overflow-hidden">
          {/* Messages */}
          <div className="flex-1 min-h-0 overflow-y-auto p-3 space-y-3 flex flex-col">
            {messages.length === 0 && (
              <div className="flex-1 flex flex-col items-center justify-center text-center opacity-60">
                <div className="w-14 h-14 rounded-full bg-primary/5 flex items-center justify-center border border-primary/10 mb-4">
                  <Sparkles className="h-6 w-6 text-primary/50" />
                </div>
                <p className="text-sm text-muted-foreground max-w-[220px]">
                  {t('ai.askToStart')}
                </p>
              </div>
            )}

            {messages.map((msg: UIMessage) => {
              const content = getMessageContent(msg)
              if (msg.role === 'assistant' && !content) return null
              const isAssistant = msg.role === 'assistant'
              const isHovered = hoveredMsgId === msg.id
              return (
                <div
                  key={msg.id}
                  className={cn('flex gap-2', !isAssistant && 'flex-row-reverse')}
                  onMouseEnter={() => isAssistant && setHoveredMsgId(msg.id)}
                  onMouseLeave={() => setHoveredMsgId(null)}
                >
                  <div className={cn(
                    'w-6 h-6 rounded-full flex items-center justify-center flex-shrink-0 border text-[10px] font-bold',
                    !isAssistant
                      ? 'bg-slate-100 dark:bg-slate-800 border-slate-200 dark:border-slate-700 text-slate-600 dark:text-slate-300'
                      : 'bg-primary/10 text-primary border-primary/20',
                  )}>
                    {!isAssistant ? 'U' : <Bot className="h-3 w-3" />}
                  </div>
                  <div className="flex flex-col gap-1 max-w-[88%]">
                    <div className={cn(
                      'p-3 rounded-2xl text-sm leading-relaxed',
                      !isAssistant
                        ? 'bg-primary text-primary-foreground rounded-tr-sm'
                        : 'bg-muted/40 border border-border/40 rounded-tl-sm text-foreground',
                    )}>
                      {isAssistant
                        ? <MarkdownContent content={content} />
                        : <p>{content}</p>}
                    </div>
                    {/* Inject buttons — always visible on last assistant msg */}
                    {isAssistant && onApplyToNote && (() => {
                      const lastAssistantId = messages.filter(m => m.role === 'assistant').at(-1)?.id
                      const alwaysShow = msg.id === lastAssistantId
                      return (
                      <div className={cn(
                        'flex gap-1 transition-all duration-150',
                        (alwaysShow || isHovered) ? 'opacity-100' : 'opacity-0 pointer-events-none',
                      )}>
                        <button
                          onClick={() => handleInjectFromChat(content, 'replace')}
                          className="flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium bg-muted hover:bg-primary/10 hover:text-primary border border-border/40 transition-colors"
                          title={t('ai.injectReplaceTitle')}
                        >
                          <Download className="h-2.5 w-2.5" /> {t('ai.injectReplace')}
                        </button>
                        <button
                          onClick={() => handleInjectFromChat(content, 'complete')}
                          className="flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium bg-muted hover:bg-emerald-50 hover:text-emerald-600 dark:hover:bg-emerald-950/30 border border-border/40 transition-colors"
                          title={t('ai.injectCompleteTitle')}
                        >
                          <PlusCircle className="h-2.5 w-2.5" /> {t('ai.injectComplete')}
                        </button>
                        <button
                          onClick={() => handleInjectFromChat(content, 'merge')}
                          className="flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium bg-muted hover:bg-violet-50 hover:text-violet-600 dark:hover:bg-violet-950/30 border border-border/40 transition-colors"
                          title={t('ai.injectMergeTitle')}
                        >
                          <GitMerge className="h-2.5 w-2.5" /> {t('ai.injectMerge')}
                        </button>
                      </div>
                      )
                    })()}
                  </div>
                </div>
              )
            })}


            {isLoading && (
              <div className="flex gap-2">
                <div className="w-6 h-6 rounded-full bg-primary/10 text-primary flex items-center justify-center flex-shrink-0 border border-primary/20">
                  <Bot className="h-3 w-3" />
                </div>
                <div className="bg-muted/40 border border-border/40 p-3 rounded-2xl rounded-tl-sm">
                  <Loader2 className="h-3.5 w-3.5 animate-spin text-muted-foreground" />
                </div>
              </div>
            )}

            {/* Enrich-in-progress indicator */}
            {resourceEnriching && !isLoading && (
              <div className="flex gap-2">
                <div className="w-6 h-6 rounded-full bg-emerald-500/10 text-emerald-600 flex items-center justify-center flex-shrink-0 border border-emerald-500/20">
                  <Wand2 className="h-3 w-3" />
                </div>
                <div className="bg-muted/40 border border-border/40 p-3 rounded-2xl rounded-tl-sm flex items-center gap-2">
                  <Loader2 className="h-3.5 w-3.5 animate-spin text-emerald-600" />
                  <span className="text-xs text-muted-foreground">{t('ai.resource.enriching') || 'Traitement IA...'}</span>
                </div>
              </div>
            )}

            {/* Inline preview from inject buttons */}
            {resourcePreview && !resourceEnriching && (
              <div className="rounded-xl border border-primary/30 bg-primary/5 overflow-hidden">
                <div className="flex items-center justify-between px-3 py-2 border-b border-primary/20">
                  <span className="text-[10px] font-semibold uppercase tracking-wider text-primary">
                    {resourcePreview.source === 'chat' ? (t('ai.resource.fromChat') || 'Remplacement')
                      : resourcePreview.source === 'replace' ? (t('ai.resource.replacement') || 'Remplacement')
                      : resourcePreview.source === 'complete' ? (t('ai.resource.completedByAI') || 'Complété par IA')
                      : (t('ai.resource.mergedByAI') || 'Fusionné par IA')}
                  </span>
                  <button onClick={() => setResourcePreview(null)} className="text-muted-foreground hover:text-foreground">
                    <X className="h-3 w-3" />
                  </button>
                </div>
                <div className="px-3 py-2 max-h-48 overflow-y-auto">
                  <MarkdownContent content={resourcePreview.text} />
                </div>
                <div className="flex gap-2 px-3 py-2 border-t border-primary/20">
                  <button
                    onClick={() => setResourcePreview(null)}
                    className="flex-1 text-[11px] py-1.5 rounded-lg border border-border/60 text-muted-foreground hover:bg-muted transition-colors"
                  >
                    {t('common.cancel') || 'Annuler'}
                  </button>
                  <button
                    onClick={() => { if (onApplyToNote && resourcePreview) { onApplyToNote(resourcePreview.text); setResourcePreview(null); setResourceText(''); toast.success(t('ai.appliedToNote')) } }}
                    disabled={!onApplyToNote}
                    className="flex-1 text-[11px] py-1.5 rounded-lg bg-primary text-primary-foreground font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 flex items-center justify-center gap-1"
                  >
                    <Check className="h-3 w-3" />
                    {t('ai.resource.applyToNote') || 'Appliquer'}
                  </button>
                </div>
              </div>
            )}

            <div ref={messagesEndRef} />
          </div>

          {/* ══ Inject Preview Panel — fixed, always visible, NO scroll needed ══ */}
          {resourceEnriching && (
            <div className="shrink-0 mx-3 mb-2 flex items-center gap-2 rounded-xl border border-emerald-500/30 bg-emerald-50/50 dark:bg-emerald-950/20 p-3">
              <Loader2 className="h-3.5 w-3.5 animate-spin text-emerald-600 shrink-0" />
              <span className="text-xs text-emerald-700 dark:text-emerald-400">Traitement IA en cours...</span>
            </div>
          )}
          {resourcePreview && !resourceEnriching && (
            <div className="shrink-0 mx-3 mb-2 rounded-xl border border-primary/30 bg-primary/5 overflow-hidden">
              <div className="flex items-center justify-between px-3 py-2 border-b border-primary/20">
                <span className="text-[10px] font-semibold uppercase tracking-wider text-primary">
                  {resourcePreview.source === 'complete' ? 'Complété par IA'
                    : resourcePreview.source === 'merge' ? 'Fusionné par IA'
                    : 'Aperçu'}
                </span>
                <button onClick={() => setResourcePreview(null)} className="text-muted-foreground hover:text-foreground">
                  <X className="h-3 w-3" />
                </button>
              </div>
              <div className="px-3 py-2 max-h-64 overflow-y-auto text-sm">
                <MarkdownContent content={resourcePreview.text} />
              </div>
              <div className="flex gap-2 px-3 py-2 border-t border-primary/20">
                <button
                  onClick={() => setResourcePreview(null)}
                  className="flex-1 text-[11px] py-1.5 rounded-lg border border-border/60 text-muted-foreground hover:bg-muted transition-colors"
                >
                  Annuler
                </button>
                <button
                  onClick={() => {
                    if (onApplyToNote && resourcePreview) {
                      onApplyToNote(resourcePreview.text)
                      setResourcePreview(null)
                      setResourceText('')
                      toast.success('Appliqué à la note')
                    }
                  }}
                  disabled={!onApplyToNote}
                  className="flex-1 text-[11px] py-1.5 rounded-lg bg-primary text-primary-foreground font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 flex items-center justify-center gap-1"
                >
                  <Check className="h-3 w-3" />
                  Appliquer à la note
                </button>
              </div>
            </div>
          )}

          {/* Scope & Tone Control Area */}
          <div className="border-t border-border/20 shrink-0 bg-muted/10">
            {/* Scope bar */}
            <div className="px-3 py-2 border-b border-border/10 flex flex-col gap-1.5">
              <label className="text-xs font-bold tracking-wider text-muted-foreground uppercase">
                {t('ai.contextLabel')}
              </label>
              <div className="flex items-center gap-2">
                <Select value={chatScope} onValueChange={setChatScope}>
                  <SelectTrigger className="h-8 flex-1 text-sm bg-card">
                    <SelectValue placeholder={t('ai.selectContext')} />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="note" className="text-sm">
                      <div className="flex items-center gap-2">
                        <FileText className="h-3 w-3 text-muted-foreground" /> {t('ai.thisNote')}
                      </div>
                    </SelectItem>
                    <SelectItem value="all" className="text-sm">
                      <div className="flex items-center gap-2">
                        <Bot className="h-3 w-3 text-muted-foreground" /> {t('ai.allMyNotes')}
                      </div>
                    </SelectItem>
                    {notebooks.map(nb => (
                      <SelectItem key={nb.id} value={nb.id} className="text-xs">
                        <div className="flex items-center gap-2">
                          {(() => {
                            const Icon = getNotebookIcon((nb as any).icon)
                            return <Icon className="w-3 h-3 text-muted-foreground" />
                          })()}
                          {nb.name.length > 25 ? nb.name.slice(0, 25) + '…' : nb.name}
                        </div>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>

            {/* Tone selector */}
            <div className="px-3 py-2 flex flex-col gap-1.5">
              <label className="text-xs font-bold tracking-wider text-muted-foreground uppercase">
                {t('ai.writingTone')}
              </label>
              <div className="grid grid-cols-4 gap-1">
                {TONES.map(tone => {
                  const Icon = tone.icon
                  const sel  = selectedTone === tone.id
                  return (
                    <button
                      key={tone.id}
                      onClick={() => setSelectedTone(tone.id)}
                      title={tone.full}
                      className={cn(
                        'py-1.5 rounded border text-xs font-medium transition-all flex flex-col items-center gap-1',
                        sel
                          ? 'border-primary bg-primary/10 text-primary'
                          : 'border-border/40 text-muted-foreground hover:bg-muted bg-card',
                      )}
                    >
                      <Icon className="h-3 w-3" />
                      {tone.label}
                    </button>
                  )
                })}
              </div>
            </div>
          </div>

          {/* Input */}
          <div className="p-3 border-t border-border/40 shrink-0 bg-card">
            <div className="relative bg-card border border-border/60 rounded-xl p-1 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary/20 transition-all">
              <textarea
                className="w-full bg-transparent border-none focus:ring-0 resize-none text-sm text-foreground placeholder:text-muted-foreground/60 p-2 min-h-[64px] max-h-[120px]"
                placeholder={
                  chatScope === 'note'
                    ? t('ai.askAboutThisNote')
                    : t('ai.askAboutYourNotes')
                }
                value={input}
                onChange={e => setInput(e.target.value)}
                onKeyDown={e => {
                  if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend() }
                }}
                disabled={isLoading}
              />
              <div className="flex justify-between items-center px-1 pb-1 pt-1">
                <div className="flex items-center gap-2">
                  {webSearchAvailable && (
                    <button
                      onClick={() => setWebSearch(w => !w)}
                      title={t('ai.webSearchLabel')}
                      className={cn(
                        'flex items-center justify-center gap-1.5 h-8 px-3 rounded-md border transition-all text-xs font-medium',
                        webSearch
                          ? 'border-emerald-500 bg-emerald-50 text-emerald-600 dark:bg-emerald-950/30'
                          : 'border-border/50 text-muted-foreground hover:bg-muted bg-card',
                      )}
                    >
                      <Globe className="h-3 w-3" />
                      Web
                    </button>
                  )}
                </div>
                {isLoading ? (
                  <Button
                    size="icon"
                    className="h-7 w-7 rounded-lg bg-red-500 text-white shadow-sm hover:bg-red-600"
                    onClick={() => stop()}
                  >
                    <Square className="h-3.5 w-3.5" />
                  </Button>
                ) : (
                  <Button
                    size="icon"
                    className="h-7 w-7 rounded-lg bg-primary text-primary-foreground shadow-sm disabled:opacity-50"
                    onClick={handleSend}
                    disabled={!input.trim()}
                  >
                    <Send className="h-3.5 w-3.5 ml-0.5" />
                  </Button>
                )}
              </div>
            </div>
            <p className="text-[9px] text-muted-foreground/40 text-center mt-1">{t('ai.newLineHint')}</p>
          </div>
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════ */}
      {/* ── TAB: ACTIONS ─────────────────────────────────────── */}
      {/* ══════════════════════════════════════════════════════════ */}
      {activeTab === 'actions' && (
        <div className="flex flex-col flex-1 overflow-hidden">
          {/* Preview panel — result to apply */}
          {actionPreview ? (
            <div className="flex flex-col flex-1 overflow-hidden">
              <div className="px-4 py-2.5 border-b border-border/40 flex items-center justify-between shrink-0">
                <p className="text-xs font-semibold text-foreground">{t('ai.resultLabel')} — {actionPreview.label}</p>
                <button onClick={handleDiscardPreview} className="text-muted-foreground hover:text-foreground">
                  <X className="h-3.5 w-3.5" />
                </button>
              </div>
              <div className="flex-1 overflow-y-auto p-4">
                <div className="text-xs leading-relaxed text-foreground bg-muted/30 border border-border/40 rounded-xl p-3 whitespace-pre-wrap">
                  {actionPreview.text}
                </div>
              </div>
              <div className="p-3 border-t border-border/40 flex gap-2 shrink-0">
                <Button
                  variant="ghost" size="sm"
                  className="flex-1 text-xs gap-1.5"
                  onClick={handleDiscardPreview}
                >
                  <X className="h-3.5 w-3.5" /> {t('ai.discardAction')}
                </Button>
                <Button
                  size="sm"
                  className="flex-1 text-xs gap-1.5 bg-primary"
                  onClick={handleApplyPreview}
                  disabled={!onApplyToNote}
                >
                  <Check className="h-3.5 w-3.5" /> {t('ai.applyToNote')}
                </Button>
              </div>
            </div>
          ) : (
            <div className="flex-1 overflow-y-auto p-4 space-y-2.5">
              <p className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground mb-3">
                {t('ai.transformationsDesc')}
              </p>

              {/* Image actions — shown when note has images */}
              {noteImages && noteImages.length > 0 && ACTION_IDS.filter(a => a.isImageAction).map(action => {
                const Icon = action.icon
                const loading = actionLoading === action.id
                return (
                  <button
                    key={action.id}
                    onClick={() => handleAction(action)}
                    disabled={!!actionLoading}
                    className="w-full flex items-center gap-3 rounded-xl border border-border/60 bg-card px-4 py-3 text-sm font-medium text-foreground hover:bg-muted hover:border-primary/40 transition-all text-left disabled:opacity-60"
                  >
                    {loading
                      ? <Loader2 className="h-4 w-4 text-primary animate-spin shrink-0" />
                      : <Icon className="h-4 w-4 text-primary shrink-0" />
                    }
                    <div className="flex flex-col">
                      <span>{t(action.i18nKey)}</span>
                      {noteImages.length > 1 && (
                        <span className="text-[10px] text-muted-foreground">{t('ai.imagesCount', { count: noteImages.length })}</span>
                      )}
                    </div>
                    {loading && <span className="ml-auto text-[10px] text-muted-foreground">{t('ai.processingAction')}</span>}
                  </button>
                )
              })}

              {/* Text actions — shown when note has sufficient text */}
              {!noteContent || noteContent.trim().split(/\s+/).filter(Boolean).length < 5 ? (
                <div className="flex items-start gap-2 p-3 rounded-xl border border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/30">
                  <Lightbulb className="h-4 w-4 text-amber-500 shrink-0 mt-0.5" />
                  <p className="text-xs text-amber-700 dark:text-amber-400">
                    {t('ai.writeMinWordsAction')}
                  </p>
                </div>
              ) : (
                ACTION_IDS.filter(a => !a.isImageAction).map(action => {
                  const Icon = action.icon
                  const loading = actionLoading === action.id
                  if (action.id === 'translate') {
                    return (
                      <div key={action.id} className="flex flex-col gap-1.5">
                        <button
                          onClick={() => setShowLangPicker(v => !v)}
                          disabled={!!actionLoading}
                          className="w-full flex items-center gap-3 rounded-xl border border-border/60 bg-card px-4 py-3 text-sm font-medium text-foreground hover:bg-muted hover:border-primary/40 transition-all text-left disabled:opacity-60"
                        >
                          {loading ? <Loader2 className="h-4 w-4 text-primary animate-spin shrink-0" /> : <Icon className="h-4 w-4 text-primary shrink-0" />}
                          <span>{t(action.i18nKey)}</span>
                          {translateTarget && <span className="ml-auto text-xs text-primary/70 font-normal">{translateTarget}</span>}
                        </button>
                        {showLangPicker && (
                          <div className="flex flex-col gap-2 px-3 py-3 rounded-xl border border-border/40 bg-muted/30">
                            <div className="flex flex-wrap gap-1.5">
                              {['Francais','English','Espanol','Deutsch','Persan','Portugais','Italiano','Chinois','Japonais'].map(l => (
                                <button
                                  key={l}
                                  className={`text-xs px-2.5 py-1 rounded-lg border transition-colors ${translateTarget === l ? 'bg-primary text-primary-foreground border-primary' : 'bg-card border-border hover:bg-accent'}`}
                                  onClick={() => { setTranslateTarget(l); setCustomLangInput(l); }}
                                >{l}</button>
                              ))}
                            </div>
                            <input
                              className="text-xs px-3 py-1.5 rounded-lg border border-border bg-card outline-none focus:border-primary w-full"
                              placeholder={t('ai.action.customLang') || 'Autre langue...'}
                              value={customLangInput}
                              onChange={e => { const val = e.target.value; setCustomLangInput(val); setTranslateTarget(val); }}
                              onKeyDown={e => { if (e.key === 'Enter' && translateTarget.trim()) { handleAction(action, translateTarget.trim()); } }}
                            />
                            <button
                              disabled={!!actionLoading || !translateTarget}
                              onClick={() => handleAction(action, translateTarget)}
                              className="flex items-center justify-center gap-2 rounded-lg bg-primary text-primary-foreground px-3 py-1.5 text-xs font-medium disabled:opacity-50 hover:bg-primary/90 transition-colors"
                            >
                              {loading ? <Loader2 className="h-3 w-3 animate-spin" /> : <Languages className="h-3 w-3" />}
                              {t('ai.action.translate')} {translateTarget}
                            </button>
                          </div>
                        )}
                      </div>
                    )
                  }
                  return (
                    <button
                      key={action.id}
                      onClick={() => handleAction(action)}
                      disabled={!!actionLoading}
                      className="w-full flex items-center gap-3 rounded-xl border border-border/60 bg-card px-4 py-3 text-sm font-medium text-foreground hover:bg-muted hover:border-primary/40 transition-all text-left disabled:opacity-60"
                    >
                      {loading
                        ? <Loader2 className="h-4 w-4 text-primary animate-spin shrink-0" />
                        : <Icon className="h-4 w-4 text-primary shrink-0" />
                      }
                      <span>{t(action.i18nKey)}</span>
                      {loading && <span className="ml-auto text-[10px] text-muted-foreground">{t('ai.processingAction')}</span>}
                    </button>
                  )
                })
              )}

              {/* Undo last action shortcut */}
              {lastActionApplied && onUndoLastAction && (
                <button
                  onClick={onUndoLastAction}
                  className="w-full mt-2 flex items-center gap-3 rounded-xl border border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/30 px-4 py-2.5 text-sm font-medium text-amber-700 dark:text-amber-400 hover:bg-amber-100 dark:hover:bg-amber-950/50 transition-all text-left"
                >
                  <RotateCcw className="h-4 w-4 shrink-0" />
                  {t('ai.undoLastAction')}
                </button>
              )}
            </div>
          )}
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════ */}
      {/* ── TAB: RESSOURCE ──────────────────────────────────── */}
      {/* ══════════════════════════════════════════════════════════ */}
      {activeTab === 'resource' && (
        <div className="flex flex-col flex-1 min-h-0 overflow-hidden">
          {/* Preview panel */}
          {resourcePreview ? (
            <div className="flex flex-col flex-1 min-h-0">
              {/* Preview header */}
              <div className="px-4 py-2.5 border-b border-border/40 flex items-center justify-between shrink-0">
                <div className="flex items-center gap-2">
                  <p className="text-xs font-semibold text-foreground">
                    {resourcePreview.source === 'chat' ? t('ai.resource.fromChat')
                      : resourcePreview.source === 'replace' ? t('ai.resource.replacement')
                      : resourcePreview.source === 'complete' ? t('ai.resource.completedByAI')
                      : t('ai.resource.mergedByAI')}
                  </p>
                  {/* Format toggle */}
                  <div className="flex rounded-md border border-border/40 overflow-hidden">
                    <button
                      onClick={() => setResourcePreviewFormat('rendered')}
                      className={cn(
                        'flex items-center gap-1 px-2 py-1 text-[10px] font-medium transition-colors',
                        resourcePreviewFormat === 'rendered'
                          ? 'bg-primary text-primary-foreground'
                          : 'bg-card text-muted-foreground hover:bg-muted',
                      )}
                    >
                      <Eye className="h-2.5 w-2.5" /> {t('ai.resource.rendered')}
                    </button>
                    <button
                      onClick={() => setResourcePreviewFormat('markdown')}
                      className={cn(
                        'flex items-center gap-1 px-2 py-1 text-[10px] font-medium transition-colors',
                        resourcePreviewFormat === 'markdown'
                          ? 'bg-primary text-primary-foreground'
                          : 'bg-card text-muted-foreground hover:bg-muted',
                      )}
                    >
                      <Code className="h-2.5 w-2.5" /> Markdown
                    </button>
                  </div>
                </div>
                <button onClick={() => setResourcePreview(null)} className="text-muted-foreground hover:text-foreground">
                  <X className="h-3.5 w-3.5" />
                </button>
              </div>
              {/* Preview content */}
              <div className="flex-1 overflow-y-auto p-3">
                {resourcePreviewFormat === 'rendered' ? (
                  <div className="text-sm leading-relaxed text-foreground bg-muted/20 border border-border/30 rounded-xl p-3">
                    <MarkdownContent content={resourcePreview.text} />
                  </div>
                ) : (
                  <pre className="text-xs leading-relaxed text-foreground bg-muted/20 border border-border/30 rounded-xl p-3 whitespace-pre-wrap font-mono overflow-x-auto">
                    {resourcePreview.text}
                  </pre>
                )}
              </div>
              {/* Apply / Discard */}
              <div className="p-3 border-t border-border/40 flex gap-2 shrink-0">
                <Button
                  variant="ghost" size="sm"
                  className="flex-1 text-xs gap-1.5"
                  onClick={() => setResourcePreview(null)}
                >
                  <X className="h-3.5 w-3.5" /> {t('ai.resource.cancel')}
                </Button>
                <Button
                  size="sm"
                  className="flex-1 text-xs gap-1.5 bg-primary"
                  onClick={handleApplyResourcePreview}
                  disabled={!onApplyToNote}
                >
                  <Check className="h-3.5 w-3.5" /> {t('ai.resource.applyToNote')}
                </Button>
              </div>
            </div>
          ) : (
            <div className="flex flex-col flex-1 min-h-0 overflow-y-auto">
              <div className="p-3 space-y-3">
                {/* URL loader */}
                <div>
                  <label className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5">
                    <Link2 className="h-3 w-3 inline mr-1" />{t('ai.resource.urlLabel')}
                  </label>
                  <div className="flex gap-1.5">
                    <input
                      type="url"
                      value={resourceUrl}
                      onChange={e => setResourceUrl(e.target.value)}
                      onKeyDown={e => e.key === 'Enter' && handleScrapeUrl()}
                      placeholder="https://..."
                      className="flex-1 h-8 px-2.5 text-xs bg-card border border-border/60 rounded-lg focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20 transition-all"
                    />
                    <Button
                      size="sm"
                      variant="outline"
                      className="h-8 px-3 text-xs shrink-0"
                      onClick={handleScrapeUrl}
                      disabled={resourceScraping || !resourceUrl.trim()}
                    >
                      {resourceScraping
                        ? <Loader2 className="h-3 w-3 animate-spin" />
                        : <Download className="h-3 w-3" />}
                    </Button>
                  </div>
                </div>

                {/* Text area */}
                <div>
                  <label className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5">
                    <FileText className="h-3 w-3 inline mr-1" />{t('ai.resource.resourceText')}
                  </label>
                  <textarea
                    value={resourceText}
                    onChange={e => setResourceText(e.target.value)}
                    placeholder={t('ai.resource.resourcePlaceholder')}
                    rows={8}
                    className="w-full px-2.5 py-2 text-xs bg-card border border-border/60 rounded-lg focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20 resize-none transition-all font-mono leading-relaxed"
                  />
                  {resourceText && (
                    <p className="text-[9px] text-muted-foreground mt-0.5 text-right">
                      {resourceText.split(/\s+/).filter(Boolean).length} {t('ai.resource.words')}
                    </p>
                  )}
                </div>

                {/* Mode selector */}
                <div>
                  <label className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5">
                    {t('ai.resource.integrationMode')}
                  </label>
                  <div className="grid grid-cols-3 gap-1.5">
                    {([
                       { id: 'replace', label: t('ai.resource.modeReplace'), desc: t('ai.resource.modeReplaceDesc'), icon: Download, color: 'primary' },
                       { id: 'complete', label: t('ai.resource.modeComplete'), desc: t('ai.resource.modeCompleteDesc'), icon: PlusCircle, color: 'emerald' },
                       { id: 'merge',   label: t('ai.resource.modeMerge'), desc: t('ai.resource.modeMergeDesc'), icon: GitMerge, color: 'violet' },
                    ] as const).map(m => {
                      const Icon = m.icon
                      const sel = resourceMode === m.id
                      return (
                        <button
                          key={m.id}
                          onClick={() => setResourceMode(m.id)}
                          className={cn(
                            'flex flex-col items-center gap-1 py-2 px-1 rounded-lg border text-center transition-all',
                            sel
                              ? m.color === 'primary'
                                ? 'border-primary bg-primary/10 text-primary'
                                : m.color === 'emerald'
                                ? 'border-emerald-500 bg-emerald-50 text-emerald-700 dark:bg-emerald-950/30'
                                : 'border-violet-500 bg-violet-50 text-violet-700 dark:bg-violet-950/30'
                              : 'border-border/40 text-muted-foreground bg-card hover:bg-muted',
                          )}
                        >
                          <Icon className="h-3.5 w-3.5" />
                          <span className="text-[10px] font-semibold leading-tight">{m.label}</span>
                          <span className="text-[9px] leading-tight opacity-70">{m.desc}</span>
                        </button>
                      )
                    })}
                  </div>
                </div>

                {/* Preview button */}
                <Button
                  className="w-full gap-2 text-sm"
                  onClick={handleResourcePreview}
                  disabled={!resourceText.trim() || resourceEnriching}
                >
                  {resourceEnriching
                    ? <><Loader2 className="h-4 w-4 animate-spin" /> {t('ai.resource.aiProcessing')}</>
                    : resourceMode === 'replace'
                    ? <><Eye className="h-4 w-4" /> {t('ai.resource.preview')}</>
                    : <><Sparkles className="h-4 w-4" /> {t('ai.resource.generatePreview')}</>
                  }
                </Button>

                {/* Hint */}
                {!noteContent && resourceMode !== 'replace' && (
                  <p className="text-[10px] text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-800 rounded-lg px-3 py-2">
                    {t('ai.resource.emptyNoteHint')}
                  </p>
                )}
              </div>
            </div>
          )}
        </div>
      )}
    </aside>
  )
}



