import { useState, useRef, useEffect, useCallback } from 'react'
import { Input, Button, theme, Typography, App } from 'antd'
import {
  SendOutlined, RobotOutlined, UserOutlined, PlusOutlined,
  DeleteOutlined, StopOutlined, MessageOutlined,
} from '@ant-design/icons'
import { streamChat, type StreamEvent } from '@/services/ai-chat'
import {
  listConversations, createConversation, deleteConversation,
  getMessages, updateConversation, type Conversation,
} from '@/services/conversation-api'
import Markdown from '@/components/Markdown'

const { Text } = Typography

interface Message {
  id: string
  role: 'user' | 'assistant'
  content: string
  timestamp: number
  streaming?: boolean
}

function ChatPage() {
  const { modal } = App.useApp()
  const [conversations, setConversations] = useState<Conversation[]>([])
  const [activeId, setActiveId] = useState<string | null>(null)
  const [messages, setMessages] = useState<Message[]>([])
  const [input, setInput] = useState('')
  const [streaming, setStreaming] = useState(false)
  const [editingId, setEditingId] = useState<string | null>(null)
  const [editTitle, setEditTitle] = useState('')
  const [deleting, setDeleting] = useState(false)
  const composingRef = useRef(false)
  const abortRef = useRef<AbortController | null>(null)
  const messagesEndRef = useRef<HTMLDivElement>(null)
  const editInputRef = useRef<any>(null)
  const { token } = theme.useToken()

  const loadConversations = useCallback(async () => {
    try { setConversations(await listConversations()) } catch { /* */ }
  }, [])
  useEffect(() => { loadConversations() }, [loadConversations])

  // Auto-select first conversation on load
  useEffect(() => {
    if (!activeId && conversations.length > 0) {
      switchConversation(conversations[0].id)
    }
  }, [conversations, activeId])
  useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }) }, [messages])

  const switchConversation = useCallback(async (id: string) => {
    if (streaming) { abortRef.current?.abort(); setStreaming(false) }
    setActiveId(id); setMessages([])
    try {
      const records = await getMessages(id)
      setMessages(records.map(m => ({
        id: m.id, role: m.role, content: m.content,
        timestamp: new Date(m.createdAt).getTime(),
      })))
    } catch { /* */ }
  }, [streaming])

  const handleNew = async () => {
    if (streaming) { abortRef.current?.abort(); setStreaming(false) }
    try {
      const conv = await createConversation()
      setConversations(prev => [conv, ...prev])
      setActiveId(conv.id); setMessages([]); setInput('')
    } catch { /* */ }
  }

  const handleDelete = (id: string) => modal.confirm({
    title: '删除对话', content: '确定？', okText: '删除', okType: 'danger', cancelText: '取消',
    onOk: async () => {
      setDeleting(true)
      try { await deleteConversation(id); setConversations(prev => prev.filter(c => c.id !== id)); if (activeId === id) { setActiveId(null); setMessages([]) } } catch { /* */ }
      setDeleting(false)
    },
  })

  const startEdit = (conv: Conversation) => { setEditingId(conv.id); setEditTitle(conv.title); setTimeout(() => editInputRef.current?.focus(), 50) }
  const saveTitle = async (id: string) => {
    const title = editTitle.trim()
    if (title && title !== conversations.find(c => c.id === id)?.title) {
      await updateConversation(id, title).catch(() => {})
      setConversations(prev => prev.map(c => c.id === id ? { ...c, title } : c))
    }
    setEditingId(null)
  }

  const handleSend = async () => {
    const text = input.trim()
    if (!text || streaming) return
    setInput('')

    const userMsg: Message = { id: Date.now().toString(), role: 'user', content: text, timestamp: Date.now() }
    const prevMessages = [...messages, userMsg]
    setMessages(prevMessages)
    setStreaming(true)

    const controller = new AbortController()
    abortRef.current = controller

    const streamMsgId = (Date.now() + 1).toString()
    const streamMsg: Message = { id: streamMsgId, role: 'assistant', content: '', timestamp: Date.now(), streaming: true }
    setMessages(prev => [...prev, streamMsg])

    let currentContent = ''
    let completedConvId: string | undefined

    const update = (updates: Partial<Message>) =>
      setMessages(prev => prev.map(m => m.id === streamMsgId ? { ...m, ...updates } : m))

    try {
      await streamChat(
        prevMessages.map(m => ({ role: m.role, content: m.content })),
        activeId,
        (event: StreamEvent) => {
          switch (event.event) {
            case 'meta':
              completedConvId = event.conversationId
              if (event.conversationId && event.conversationId !== activeId) { setActiveId(event.conversationId); loadConversations() }
              break
            case 'message.delta':
              currentContent += event.delta || ''
              update({ content: currentContent, streaming: true })
              break
            case 'run.completed':
              if (event.output) currentContent = event.output
              update({ content: currentContent, streaming: false })
              break
            case 'done':
              completedConvId = event.conversationId || completedConvId; update({ streaming: false })
              break
            case 'error':
              update({ content: `❌ ${event.error}`, streaming: false })
              break
          }
        },
        controller.signal,
      )
      if (completedConvId) loadConversations()
    } catch (err: any) {
      if (err.name !== 'AbortError') update({ content: `❌ ${err.message}`, streaming: false })
      else update({ streaming: false })
    } finally {
      setStreaming(false); abortRef.current = null
    }
  }

  const handleStop = () => { abortRef.current?.abort(); setStreaming(false) }

  return (
    <div style={{ display: 'flex', height: 'calc(100vh - 112px)', gap: 12 }}>
      <div style={{ width: 260, flexShrink: 0, display: 'flex', flexDirection: 'column', background: token.colorBgContainer, borderRadius: token.borderRadiusLG, border: `1px solid ${token.colorBorderSecondary}`, overflow: 'hidden' }}>
        <div style={{ padding: 12, borderBottom: `1px solid ${token.colorBorderSecondary}` }}>
          <Button type="primary" icon={<PlusOutlined />} block onClick={handleNew}>新对话</Button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '4px 8px' }}>
          {conversations.map(conv => (
            <div key={conv.id} onClick={() => activeId !== conv.id && switchConversation(conv.id)}
              style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 10px', marginBottom: 2, borderRadius: 8, cursor: 'pointer', background: activeId === conv.id ? token.colorFillSecondary : 'transparent' }}>
              <MessageOutlined style={{ color: token.colorTextQuaternary, fontSize: 14, marginRight: 8, flexShrink: 0 }} />
              {editingId === conv.id ? (
                <Input ref={editInputRef} size="small" value={editTitle} onChange={e => setEditTitle(e.target.value)}
                  onBlur={() => saveTitle(conv.id)} onPressEnter={() => saveTitle(conv.id)}
                  onClick={e => e.stopPropagation()} style={{ flex: 1, fontSize: 13 }} />
              ) : (
                <Text ellipsis style={{ flex: 1, fontSize: 13, lineHeight: '28px' }}
                  onDoubleClick={e => { e.stopPropagation(); startEdit(conv) }}>{conv.title}</Text>
              )}
              <Button type="text" size="small" danger icon={<DeleteOutlined />} disabled={deleting}
                onClick={e => { e.stopPropagation(); handleDelete(conv.id) }} style={{ marginLeft: 4, flexShrink: 0 }} />
            </div>
          ))}
          {conversations.length === 0 && <div style={{ textAlign: 'center', padding: 24 }}><Text type="secondary" style={{ fontSize: 13 }}>暂无对话</Text></div>}
        </div>
      </div>

      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        <div style={{ flex: 1, overflowY: 'auto', background: token.colorBgContainer, borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`, padding: '20px 24px', border: `1px solid ${token.colorBorderSecondary}`, borderBottom: 'none' }}>
          {messages.length === 0 && (
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
              <RobotOutlined style={{ fontSize: 48, marginBottom: 16, color: token.colorTextQuaternary }} />
              <Text type="secondary" style={{ fontSize: 16 }}>{activeId ? '开始新对话' : '点击「新对话」开始'}</Text>
              <Text type="secondary" style={{ fontSize: 13, marginTop: 8 }}>Hermes Agent · 流式响应 · xhigh 推理</Text>
            </div>
          )}

          {messages.map(msg => (
            <div key={msg.id} style={{ display: 'flex', gap: 12, marginBottom: 20, flexDirection: msg.role === 'user' ? 'row-reverse' : 'row' }}>
              <div style={{ maxWidth: '75%', minWidth: 0, padding: '12px 16px', borderRadius: 12, lineHeight: 1.8, wordBreak: 'break-word', background: msg.role === 'user' ? token.colorPrimary : token.colorFillAlter, color: msg.role === 'user' ? '#fff' : token.colorText }}>
                {msg.role === 'assistant'
                  ? (msg.content
                    ? <Markdown content={msg.content + (msg.streaming ? '▊' : '')} />
                    : <Text type="secondary" style={{ fontSize: 13 }}>思考中...</Text>)
                  : msg.content}
              </div>
            </div>
          ))}
          <div ref={messagesEndRef} />
        </div>

        <div style={{ background: token.colorBgContainer, border: `1px solid ${token.colorBorderSecondary}`, borderRadius: `0 0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px`, padding: '16px 20px' }}>
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 10, background: token.colorFillTertiary, borderRadius: 12, padding: '8px 8px 8px 14px', border: `1px solid ${token.colorBorderSecondary}` }}>
            <Input.TextArea value={input} onChange={e => setInput(e.target.value)}
              onCompositionStart={() => { composingRef.current = true }}
              onCompositionEnd={() => { composingRef.current = false }}
              onKeyDown={e => { if (composingRef.current) return; if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend() } }}
              placeholder={activeId ? '输入消息，Enter 发送' : '请先新建或选择对话'}
              autoSize={{ minRows: 1, maxRows: 5 }} disabled={streaming || !activeId}
              variant="borderless" style={{ flex: 1, resize: 'none', padding: '4px 0', fontSize: 14 }} />
            {streaming ? (
              <Button danger type="primary" icon={<StopOutlined />} onClick={handleStop} style={{ borderRadius: 8, height: 34, minWidth: 72 }}>停止</Button>
            ) : (
              <Button type="primary" icon={<SendOutlined />} onClick={handleSend}
                disabled={!input.trim() || !activeId} style={{ borderRadius: 8, height: 34, minWidth: 72 }}>发送</Button>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}

export default function TaskAssistant() { return <App><ChatPage /></App> }
