'use client'

import { useState, useRef, useEffect, useMemo } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { X, Send, Bot, User, Sparkles, Maximize2, Minimize2, ArrowRight } from 'lucide-react'
import { ChatMessage, Language, SlideId } from '@/lib/types'
import { t } from '@/lib/i18n'

interface ChatFABProps {
  lang: Language
  currentSlide: SlideId
  currentIndex: number
  visitedSlides: Set<number>
  onGoToSlide: (index: number) => void
}

interface ParsedMessage {
  text: string
  followUps: string[]
  gotos: { index: number; label: string }[]
}

function parseAgentResponse(content: string, lang: Language): ParsedMessage {
  const followUps: string[] = []
  const gotos: { index: number; label: string }[] = []

  // Split on the follow-up separator — flexible: "---", "- - -", "___", or multiple dashes
  const parts = content.split(/\n\s*[-_]{3,}\s*\n/)
  let text = parts[0]

  // Parse follow-up questions from second part
  if (parts.length > 1) {
    const qSection = parts.slice(1).join('\n')
    // Match [Q], **[Q]**, or numbered/bulleted question patterns
    const qMatches = qSection.matchAll(/(?:\[Q\]|\*\*\[Q\]\*\*)\s*(.+?)(?:\n|$)/g)
    for (const m of qMatches) {
      const q = m[1].trim().replace(/^\*\*|\*\*$/g, '')
      if (q.length > 5) followUps.push(q)
    }

    // Fallback: if no [Q] markers found, look for numbered or bulleted questions in the section
    if (followUps.length === 0) {
      const lineMatches = qSection.matchAll(/(?:^|\n)\s*(?:\d+[\.\)]\s*|[-•]\s*)(.+?\?)\s*$/gm)
      for (const m of lineMatches) {
        const q = m[1].trim()
        if (q.length > 5 && followUps.length < 3) followUps.push(q)
      }
    }
  }

  // Also look for [Q] questions anywhere in the text (sometimes model puts them without ---)
  if (followUps.length === 0) {
    const inlineMatches = content.matchAll(/\[Q\]\s*(.+?)(?:\n|$)/g)
    const inlineQs: string[] = []
    for (const m of inlineMatches) {
      inlineQs.push(m[1].trim())
    }
    if (inlineQs.length >= 2) {
      followUps.push(...inlineQs)
      // Remove [Q] lines from main text
      text = text.replace(/\n?\s*\[Q\]\s*.+?(?:\n|$)/g, '\n').trim()
    }
  }

  // Parse GOTO markers from the text
  const gotoRegex = /\[GOTO:(\d+)\]/g
  let gotoMatch
  while ((gotoMatch = gotoRegex.exec(text)) !== null) {
    const slideIndex = parseInt(gotoMatch[1])
    gotos.push({
      index: slideIndex,
      label: lang === 'de' ? `Zu Slide ${slideIndex + 1} springen` : `Jump to slide ${slideIndex + 1}`,
    })
  }
  // Remove GOTO markers from visible text
  text = text.replace(/\s*\[GOTO:\d+\]/g, '')

  // Clean up trailing reminder instruction that might leak through
  text = text.replace(/\n*\(Erinnerung:.*?\)\s*$/s, '').trim()

  return { text: text.trim(), followUps, gotos }
}

export default function ChatFAB({ lang, currentSlide, currentIndex, visitedSlides, onGoToSlide }: ChatFABProps) {
  const i = t(lang)
  const [isOpen, setIsOpen] = useState(false)
  const [isExpanded, setIsExpanded] = useState(false)
  const [messages, setMessages] = useState<ChatMessage[]>([])
  const [input, setInput] = useState('')
  const [isStreaming, setIsStreaming] = useState(false)
  const [parsedResponses, setParsedResponses] = useState<Map<number, ParsedMessage>>(new Map())
  const messagesEndRef = useRef<HTMLDivElement>(null)
  const inputRef = useRef<HTMLInputElement>(null)
  const abortRef = useRef<AbortController | null>(null)

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

  useEffect(() => {
    if (isOpen && inputRef.current) {
      setTimeout(() => inputRef.current?.focus(), 200)
    }
  }, [isOpen])

  // Parse the latest assistant message when streaming ends
  const lastAssistantIndex = useMemo(() => {
    for (let i = messages.length - 1; i >= 0; i--) {
      if (messages[i].role === 'assistant') return i
    }
    return -1
  }, [messages])

  useEffect(() => {
    if (!isStreaming && lastAssistantIndex >= 0 && !parsedResponses.has(lastAssistantIndex)) {
      const msg = messages[lastAssistantIndex]
      const parsed = parseAgentResponse(msg.content, lang)
      setParsedResponses(prev => new Map(prev).set(lastAssistantIndex, parsed))
    }
  }, [isStreaming, lastAssistantIndex, messages, parsedResponses, lang])

  async function sendMessage(text?: string) {
    const message = text || input.trim()
    if (!message || isStreaming) return

    setInput('')
    setMessages(prev => [...prev, { role: 'user', content: message }])
    setIsStreaming(true)

    abortRef.current = new AbortController()

    try {
      const res = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message,
          history: messages.slice(-10),
          lang,
          slideContext: {
            currentSlide,
            currentIndex,
            visitedSlides: Array.from(visitedSlides),
            totalSlides: 13,
          },
        }),
        signal: abortRef.current.signal,
      })

      if (!res.ok) throw new Error(`HTTP ${res.status}`)

      const reader = res.body!.getReader()
      const decoder = new TextDecoder()
      let content = ''

      setMessages(prev => [...prev, { role: 'assistant', content: '' }])

      while (true) {
        const { done, value } = await reader.read()
        if (done) break

        content += decoder.decode(value, { stream: true })
        const currentText = content
        setMessages(prev => {
          const updated = [...prev]
          updated[updated.length - 1] = { role: 'assistant', content: currentText }
          return updated
        })
      }
    } catch (err: unknown) {
      if (err instanceof Error && err.name === 'AbortError') return
      console.error('Chat error:', err)
      setMessages(prev => [
        ...prev,
        { role: 'assistant', content: lang === 'de'
          ? 'Verbindung fehlgeschlagen. Bitte versuchen Sie es erneut.'
          : 'Connection failed. Please try again.'
        },
      ])
    } finally {
      setIsStreaming(false)
      abortRef.current = null
    }
  }

  function stopGeneration() {
    if (abortRef.current) {
      abortRef.current.abort()
      setIsStreaming(false)
    }
  }

  const suggestions = i.aiqa.suggestions.slice(0, 3)

  function renderMessageContent(msg: ChatMessage, idx: number) {
    const parsed = parsedResponses.get(idx)
    const displayText = parsed ? parsed.text : msg.content

    return (
      <>
        <div className="whitespace-pre-wrap">{displayText}</div>
        {isStreaming && idx === messages.length - 1 && msg.role === 'assistant' && (
          <span className="inline-block w-1.5 h-3.5 bg-indigo-400 animate-pulse ml-0.5" />
        )}

        {/* GOTO Buttons */}
        {parsed && parsed.gotos.length > 0 && (
          <div className="mt-2 space-y-1">
            {parsed.gotos.map((g, gi) => (
              <button
                key={gi}
                onClick={() => onGoToSlide(g.index)}
                className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg
                  bg-indigo-500/20 border border-indigo-500/30
                  hover:bg-indigo-500/30 transition-colors
                  text-xs text-indigo-300"
              >
                <ArrowRight className="w-3 h-3" />
                {g.label}
              </button>
            ))}
          </div>
        )}

        {/* Follow-Up Suggestions */}
        {parsed && parsed.followUps.length > 0 && !isStreaming && (
          <div className="mt-3 space-y-1.5 border-t border-white/10 pt-2">
            {parsed.followUps.map((q, qi) => (
              <button
                key={qi}
                onClick={() => sendMessage(q)}
                className="block w-full text-left px-2.5 py-2 rounded-lg
                  bg-white/[0.05] border border-white/10
                  hover:bg-white/[0.1] transition-colors
                  text-xs text-white/60 hover:text-white/90"
              >
                {q}
              </button>
            ))}
          </div>
        )}
      </>
    )
  }

  return (
    <>
      {/* FAB Button — sits to the left of NavigationFAB */}
      <AnimatePresence>
        {!isOpen && (
          <motion.button
            initial={{ scale: 0 }}
            animate={{ scale: 1 }}
            exit={{ scale: 0 }}
            whileHover={{ scale: 1.1 }}
            whileTap={{ scale: 0.95 }}
            onClick={() => setIsOpen(true)}
            className="fixed bottom-6 right-[5.5rem] z-50 w-14 h-14 rounded-full
              bg-indigo-600 hover:bg-indigo-500 text-white
              flex items-center justify-center shadow-lg shadow-indigo-600/30
              transition-colors"
            aria-label={lang === 'de' ? 'Investor Agent oeffnen' : 'Open Investor Agent'}
          >
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" />
              <circle cx="9" cy="10" r="1" fill="currentColor" />
              <circle cx="12" cy="10" r="1" fill="currentColor" />
              <circle cx="15" cy="10" r="1" fill="currentColor" />
            </svg>
          </motion.button>
        )}
      </AnimatePresence>

      {/* Chat Panel */}
      <AnimatePresence>
        {isOpen && (
          <motion.div
            initial={{ opacity: 0, scale: 0.9, y: 20 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            exit={{ opacity: 0, scale: 0.9, y: 20 }}
            transition={{ duration: 0.2 }}
            className={`fixed bottom-6 right-6 z-50
              ${isExpanded ? 'w-[700px] h-[80vh]' : 'w-[400px] h-[520px]'}
              rounded-2xl overflow-hidden
              bg-black/90 backdrop-blur-xl border border-white/10
              shadow-2xl shadow-black/50 flex flex-col
              transition-all duration-200`}
          >
            {/* Header */}
            <div className="flex items-center justify-between px-4 py-3 border-b border-white/10 shrink-0">
              <div className="flex items-center gap-2">
                <div className="w-7 h-7 rounded-full bg-indigo-500/20 flex items-center justify-center">
                  <Bot className="w-4 h-4 text-indigo-400" />
                </div>
                <div>
                  <span className="text-sm font-semibold text-white">Investor Agent</span>
                  <span className="text-xs text-white/30 ml-2">
                    {isStreaming
                      ? (lang === 'de' ? 'antwortet...' : 'responding...')
                      : (lang === 'de' ? 'online' : 'online')
                    }
                  </span>
                </div>
              </div>
              <div className="flex items-center gap-1">
                <button
                  onClick={() => setIsExpanded(prev => !prev)}
                  className="w-7 h-7 rounded-full bg-white/10 flex items-center justify-center hover:bg-white/20 transition-colors"
                >
                  {isExpanded ? <Minimize2 className="w-3.5 h-3.5 text-white/60" /> : <Maximize2 className="w-3.5 h-3.5 text-white/60" />}
                </button>
                <button
                  onClick={() => setIsOpen(false)}
                  className="w-7 h-7 rounded-full bg-white/10 flex items-center justify-center hover:bg-white/20 transition-colors"
                >
                  <X className="w-4 h-4 text-white/60" />
                </button>
              </div>
            </div>

            {/* Messages */}
            <div className="flex-1 overflow-y-auto px-4 py-3 space-y-3">
              {messages.length === 0 && (
                <div className="space-y-2">
                  <div className="flex items-center gap-2 text-white/40 text-xs mb-3">
                    <Sparkles className="w-3.5 h-3.5" />
                    <span>{lang === 'de' ? 'Fragen Sie den Investor Agent:' : 'Ask the Investor Agent:'}</span>
                  </div>
                  {suggestions.map((q, idx) => (
                    <motion.button
                      key={idx}
                      initial={{ opacity: 0, y: 8 }}
                      animate={{ opacity: 1, y: 0 }}
                      transition={{ delay: 0.1 + idx * 0.08 }}
                      onClick={() => sendMessage(q)}
                      className="block w-full text-left px-3 py-2.5 rounded-xl
                        bg-white/[0.05] border border-white/10
                        hover:bg-white/[0.1] transition-colors
                        text-xs text-white/70 hover:text-white"
                    >
                      {q}
                    </motion.button>
                  ))}
                </div>
              )}

              {messages.map((msg, idx) => (
                <div
                  key={idx}
                  className={`flex gap-2.5 ${msg.role === 'user' ? 'justify-end' : ''}`}
                >
                  {msg.role === 'assistant' && (
                    <div className="w-7 h-7 rounded-full bg-indigo-500/20 flex items-center justify-center shrink-0 mt-0.5">
                      <Bot className="w-3.5 h-3.5 text-indigo-400" />
                    </div>
                  )}
                  <div
                    className={`
                      max-w-[85%] rounded-2xl px-3.5 py-2.5 text-xs leading-relaxed
                      ${msg.role === 'user'
                        ? 'bg-indigo-500/20 text-white'
                        : 'bg-white/[0.06] text-white/80'
                      }
                    `}
                  >
                    {msg.role === 'assistant' ? renderMessageContent(msg, idx) : (
                      <div className="whitespace-pre-wrap">{msg.content}</div>
                    )}
                  </div>
                  {msg.role === 'user' && (
                    <div className="w-7 h-7 rounded-full bg-white/10 flex items-center justify-center shrink-0 mt-0.5">
                      <User className="w-3.5 h-3.5 text-white/60" />
                    </div>
                  )}
                </div>
              ))}
              <div ref={messagesEndRef} />
            </div>

            {/* Input */}
            <div className="border-t border-white/10 px-4 py-3 shrink-0">
              {isStreaming && (
                <button
                  onClick={stopGeneration}
                  className="w-full mb-2 px-3 py-1.5 rounded-lg bg-white/[0.06] hover:bg-white/[0.1]
                    text-xs text-white/50 transition-colors"
                >
                  {lang === 'de' ? 'Antwort stoppen' : 'Stop response'}
                </button>
              )}
              <div className="flex gap-2">
                <input
                  ref={inputRef}
                  type="text"
                  value={input}
                  onChange={(e) => setInput(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && sendMessage()}
                  placeholder={lang === 'de' ? 'Frage stellen...' : 'Ask a question...'}
                  disabled={isStreaming}
                  className="flex-1 bg-white/[0.06] border border-white/10 rounded-xl px-3.5 py-2.5
                    text-xs text-white placeholder-white/30 outline-none
                    focus:border-indigo-500/50 focus:ring-1 focus:ring-indigo-500/20
                    disabled:opacity-50 transition-all"
                />
                <button
                  onClick={() => sendMessage()}
                  disabled={isStreaming || !input.trim()}
                  className="px-3.5 py-2.5 bg-indigo-500 hover:bg-indigo-600 disabled:opacity-30
                    rounded-xl transition-all text-white"
                >
                  <Send className="w-3.5 h-3.5" />
                </button>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  )
}
