import { useState, useRef, useEffect, KeyboardEvent, Dispatch, SetStateAction } from 'react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { askQuestionStream } from '../api'
import type { Citation, Document, HistoryMessage } from '../api'
import type { Message } from '../types'
import type { Tr } from '../i18n'
import styles from './ChatView.module.css'

const STATUS_LABELS: Record<string, string> = {
  searching: 'Recherche dans les documents…',
  querying: 'Analyse des données…',
  generating: 'Rédaction de la réponse…',
}

function formatCitation(c: Citation): string {
  const page = c.page
  if (typeof page === 'string') return `${c.filename} · ${page}`
  if (page > 0) return `${c.filename} p.${page}`
  return c.filename
}

interface Props {
  documents: Document[]
  messages: Message[]
  setMessages: Dispatch<SetStateAction<Message[]>>
  onSave?: (msgs: Message[]) => void
  tr: Tr
  lang: string
}

export default function ChatView({ documents, messages, setMessages, onSave, tr, lang }: Props) {
  const [input, setInput] = useState('')
  const [loading, setLoading] = useState(false)
  const [streamStatus, setStreamStatus] = useState<string>('')
  const bottomRef = useRef<HTMLDivElement>(null)

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

  const send = async () => {
    const q = input.trim()
    if (!q || loading) return
    setInput('')
    setStreamStatus('')

    const userMsg: Message = { role: 'user', text: q }
    setMessages(prev => [...prev, userMsg])
    setLoading(true)

    const history: HistoryMessage[] = messages.map(m => ({ role: m.role, content: m.text }))

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

    try {
      await askQuestionStream(
        q,
        history,
        6,
        '',
        (token) => {
          setStreamStatus('')
          setMessages(prev => {
            const copy = [...prev]
            copy[copy.length - 1] = {
              ...copy[copy.length - 1],
              text: copy[copy.length - 1].text + token,
            }
            return copy
          })
        },
        (meta) => {
          setStreamStatus('')
          setMessages(prev => {
            const copy = [...prev]
            const last = copy[copy.length - 1]
            const text = meta.path === 'sql' && meta.answer ? meta.answer : last.text
            copy[copy.length - 1] = { ...last, text, meta }
            onSave?.(copy)
            return copy
          })
        },
        (err) => {
          setStreamStatus('')
          setMessages(prev => {
            const copy = [...prev]
            copy[copy.length - 1] = { role: 'assistant', text: `Error: ${err}` }
            return copy
          })
        },
        (s) => setStreamStatus(s),
        lang,
      )
    } finally {
      setLoading(false)
      setStreamStatus('')
    }
  }

  const onKey = (e: KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      send()
    }
  }

  const empty = documents.length === 0

  return (
    <div className={styles.root}>
      <div className={styles.toolbar}>
        <span className={styles.docCount}>
          {tr.docCount(documents.length)}
        </span>
        {messages.length > 0 && (
          <button className={styles.clearBtn} onClick={() => setMessages([])}>
            {tr.clearChat}
          </button>
        )}
      </div>

      <div className={styles.thread}>
        {messages.length === 0 && (
          <div className={styles.empty}>
            {empty ? tr.emptyNoDoc : tr.emptyWithDoc}
          </div>
        )}
        {messages.map((m, i) => (
          <div key={i} className={`${styles.msg} ${styles[m.role]}`}>
            {m.role === 'assistant' && <span className={styles.senderName}>Julia</span>}
            {m.role === 'assistant' ? (
              loading && i === messages.length - 1 && m.text === '' ? (
                <span className={styles.thinking}>
                  {streamStatus ? (STATUS_LABELS[streamStatus] ?? tr.thinking) : tr.thinking}
                </span>
              ) : (
                <div className={styles.markdown}>
                  <ReactMarkdown remarkPlugins={[remarkGfm]}>{m.text}</ReactMarkdown>
                </div>
              )
            ) : (
              <p className={styles.text}>{m.text}</p>
            )}
            {m.meta && (
              <div className={styles.meta}>
                {m.meta.citations.length > 0 && (
                  <div className={styles.citations}>
                    {m.meta.citations.map((c, j) => (
                      <span key={j} className={styles.citation} title={c.snippet ?? ''}>
                        {formatCitation(c)}
                      </span>
                    ))}
                  </div>
                )}
                <span className={styles.pathBadge} data-path={m.meta.path}>
                  {m.meta.path === 'sql' ? 'SQL' : 'Vector'} · {m.meta.chunks_used} chunks
                </span>
              </div>
            )}
          </div>
        ))}
        <div ref={bottomRef} />
      </div>

      <div className={styles.inputRow}>
        <textarea
          className={styles.textarea}
          rows={2}
          placeholder={tr.askPlaceholder}
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={onKey}
          disabled={loading}
        />
        <button
          className={styles.sendBtn}
          onClick={send}
          disabled={loading || !input.trim()}
        >
          {tr.send}
        </button>
      </div>
    </div>
  )
}
