'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,
  Briefcase, Palette, GraduationCap, Coffee,
  Lightbulb, Minimize2, AlignLeft, Wand2,
  Globe, BookOpen, FileText, RotateCcw, Check,
  Maximize2,
} 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'

// ── 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) => object
  resultKey: string
  i18nKey: string
}

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: 'markdown', icon: Wand2, apiPath: '/api/ai/transform-markdown', body: (content: string) => ({ text: content }), resultKey: 'transformedText', i18nKey: 'ai.action.toMarkdown' },
]

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

interface ContextualAIChatProps {
  onClose: () => void
  noteTitle?: string
  noteContent?: 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,
  onApplyToNote,
  onUndoLastAction,
  lastActionApplied = false,
  notebooks = [],
  className,
}: ContextualAIChatProps) {
  const { t, language } = useLanguage()
  const webSearchAvailable = useWebSearchAvailable()

  const [activeTab, setActiveTab]           = useState<'chat' | 'actions'>('chat')
  const [selectedTone, setSelectedTone]     = useState('professional')
  const [input, setInput]                   = useState('')
  const [chatScope, setChatScope]           = useState<'note' | 'all' | string>('note') // 'note', 'all', or notebook ID
  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 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 }
    } else if (chatScope !== 'all') {
      // scope is a notebook ID
      body.notebookId = chatScope
    }
    return body
  }

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

  const isLoading = status === 'submitted' || status === 'streaming'

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

  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) => {
    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)),
      })
      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) {
      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)

  // ── 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.assistantTitle')}
          </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">
        {(['chat', 'actions'] as const).map(tab => (
          <button
            key={tab}
            onClick={() => setActiveTab(tab)}
            className={cn(
              'flex-1 py-3 border-b-2 text-sm font-semibold flex items-center justify-center gap-2 transition-all capitalize',
              activeTab === tab
                ? 'border-primary text-primary'
                : 'border-transparent text-muted-foreground hover:text-foreground',
            )}
          >
            {tab === 'chat'    && <Bot className="h-3.5 w-3.5" />}
            {tab === 'actions' && <Wand2 className="h-3.5 w-3.5" />}
            {tab === 'chat' ? t('ai.chatTab') : t('ai.noteActions')}
          </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)
              return (
                <div key={msg.id} className={cn('flex gap-2', msg.role === 'user' && 'flex-row-reverse')}>
                  <div className={cn(
                    'w-6 h-6 rounded-full flex items-center justify-center flex-shrink-0 border text-[10px] font-bold',
                    msg.role === 'user'
                      ? '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',
                  )}>
                    {msg.role === 'user' ? 'U' : <Bot className="h-3 w-3" />}
                  </div>
                  <div className={cn(
                    'max-w-[88%] p-3 rounded-2xl text-sm leading-relaxed',
                    msg.role === 'user'
                      ? 'bg-primary text-primary-foreground rounded-tr-sm'
                      : 'bg-muted/40 border border-border/40 rounded-tl-sm text-foreground',
                  )}>
                    {msg.role === 'assistant'
                      ? <MarkdownContent content={content} />
                      : <p>{content}</p>}
                  </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>
            )}
            <div ref={messagesEndRef} />
          </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>
                <Button
                  size="icon"
                  className="h-7 w-7 rounded-lg bg-primary text-primary-foreground shadow-sm disabled:opacity-50"
                  onClick={handleSend}
                  disabled={isLoading || !input.trim()}
                >
                  {isLoading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <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>

              {!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.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" />
                      }
                      <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>
      )}
    </aside>
  )
}
