import * as Dialog from '@radix-ui/react-dialog'
import { PanelRightOpen, Radar, Sparkles } from 'lucide-react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'

import { Button } from '../../components/ui/button'
import type { Message, Source } from '../../lib/types'
import { announceSessionChange, createSession, listMessages } from './api'
import { ChatComposer } from './ChatComposer'
import { EvidencePanel } from './EvidencePanel'
import { MessageList } from './MessageList'
import { useChatStreamStore } from './store'
import { useChatStream } from './useChatStream'

export function ChatPage() {
  const { sessionId } = useParams()
  const navigate = useNavigate()
  const [messages, setMessages] = useState<Message[]>([])
  const [evidenceOpen, setEvidenceOpen] = useState(false)
  const currentSessionId = useRef(sessionId)
  const stream = useChatStreamStore()

  useEffect(() => { currentSessionId.current = sessionId }, [sessionId])

  const refreshMessages = useCallback(async () => {
    if (!sessionId) {
      if (currentSessionId.current === sessionId) setMessages([])
      return
    }
    const target = sessionId
    const page = await listMessages(target)
    if (currentSessionId.current !== target) return
    setMessages(page.items); announceSessionChange()
  }, [sessionId])

  useEffect(() => {
    if (!sessionId) return
    const target = sessionId
    let cancelled = false
    void listMessages(target).then((page) => {
      if (!cancelled && currentSessionId.current === target) setMessages(page.items)
    })
    return () => { cancelled = true }
  }, [sessionId])

  const { send, cancel } = useChatStream(async () => { await refreshMessages(); useChatStreamStore.getState().reset() })

  async function handleSend(query: string) {
    let target = sessionId
    if (!target) {
      const session = await createSession(); target = session.id; navigate(`/chat/${target}`); announceSessionChange()
    }
    await send(target, query)
    const page = await listMessages(target)
    if (currentSessionId.current !== target) return
    setMessages(page.items)
    announceSessionChange()
  }

  function chooseSource(source: Source, sources: Source[] = stream.sources) {
    stream.setSources(sources)
    stream.selectSource(source)
    setEvidenceOpen(true)
  }
  const streaming = stream.phase === 'researching' || stream.phase === 'answering'

  return (
    <section className="chat-workspace">
      <main className="chat-main">
        <header className="chat-header"><div><p className="eyebrow">KNOWLEDGE CONVERSATION</p><h1>{sessionId ? '知识库对话' : '开始新研究'}</h1></div><Button className="evidence-trigger" variant="secondary" size="sm" onClick={() => setEvidenceOpen(true)}><PanelRightOpen size={15} />本轮证据</Button></header>
        <div className="conversation-scroll"><MessageList messages={messages} onSource={chooseSource} />{stream.activeQuery && <div className="streaming-turn"><article className="message message--user"><div className="message-body"><p>{stream.activeQuery}</p></div></article><article className="message message--assistant"><div className="message-avatar"><Sparkles size={15} /></div><div className="message-body">{stream.phase === 'researching' && <p className="research-state"><Radar className="pulse" size={16} />研究 Agent 正在检索知识库…</p>}{stream.text && <p className="answer-copy">{stream.text}<span className="typing-cursor" /></p>}{stream.error && <p className="failed-message">{stream.error}</p>}</div></article></div>}</div>
        <ChatComposer streaming={streaming} onSend={(query) => void handleSend(query)} onCancel={cancel} />
      </main>
      <div className="evidence-desktop"><EvidencePanel sources={stream.sources} selected={stream.selectedSource} onSelect={stream.selectSource} /></div>
      <Dialog.Root open={evidenceOpen} onOpenChange={setEvidenceOpen}><Dialog.Portal><Dialog.Overlay className="dialog-overlay" /><Dialog.Content className="evidence-drawer"><Dialog.Title className="sr-only">本轮证据</Dialog.Title><EvidencePanel sources={stream.sources} selected={stream.selectedSource} onSelect={stream.selectSource} onClose={() => setEvidenceOpen(false)} /></Dialog.Content></Dialog.Portal></Dialog.Root>
    </section>
  )
}
