import { useEffect, useRef, useState } from 'react';
import { App as AntApp, Empty } from 'antd';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import type { ModelOverrides } from '../../api';
import AgentSidebar from './components/AgentSidebar';
import ChatHeader from './components/ChatHeader';
import ChatBody from './components/ChatBody';
import ChatInput from './components/ChatInput';
import ChatDrawers from './components/ChatDrawers';
import ChatOutline from './components/ChatOutline';
import { useChatScroll } from './hooks/useChatScroll';
import { useChatData } from './hooks/useChatData';
import { useChatSender } from './hooks/useChatSender';
import { markdownToPlainText } from './utils/copy';

export default function ChatPage() {
  const { id } = useParams();
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const { message } = AntApp.useApp();

  const [sessionId, setSessionId] = useState<string | null>(null);
  const [highlightId, setHighlightId] = useState<string | null>(null);
  const [overrides, setOverrides] = useState<ModelOverrides>({});

  const [historyDrawerOpen, setHistoryDrawerOpen] = useState(false);
  const [mcpDrawerOpen, setMcpDrawerOpen] = useState(false);
  const [paramsDrawerOpen, setParamsDrawerOpen] = useState(false);
  const [tplDrawerOpen, setTplDrawerOpen] = useState(false);

  const abortRef = useRef<AbortController | null>(null);
  const { bodyRef, scrollBottom, initialScrollDoneRef } = useChatScroll();

  useEffect(() => {
    const s = searchParams.get('session');
    const m = searchParams.get('msg');
    if (s) {
      setSessionId(s);
      if (m) setHighlightId(m);
      const next = new URLSearchParams(searchParams);
      next.delete('session');
      next.delete('msg');
      setSearchParams(next, { replace: true });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchParams]);

  const { agent, agentList, messages, setMessages, branches, setBranches, loadMessages } = useChatData({
    agentId: id,
    sessionId,
    highlightId,
    setHighlightId,
    scrollBottom,
    initialScrollDoneRef,
    setOverrides: (updater) => setOverrides(updater),
    abort: () => abortRef.current?.abort()
  });

  const sender = useChatSender({
    agentId: id,
    agent,
    sessionId,
    overrides,
    setOverrides: (updater) => setOverrides(updater),
    messages,
    setMessages,
    setBranches,
    loadMessages,
    scrollBottom,
    notify: { success: (t) => message.success(t), error: (t) => message.error(t) },
    abortRef
  });

  return (
    <div className="chat-shell">
      <AgentSidebar
        agentList={agentList}
        activeAgentId={id}
        onCreate={() => navigate('/agents/new')}
        onSelect={(aid) => navigate(`/chat/${aid}`)}
      />

      <section className="chat-main">
        {!agent ? (
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Empty description="请在左侧选择一个智能体开始对话" />
          </div>
        ) : (
          <>
            <ChatHeader
              agent={agent}
              useStream={sender.useStream}
              setUseStream={sender.setUseStream}
              onOpenHistory={() => setHistoryDrawerOpen(true)}
              onOpenParams={() => setParamsDrawerOpen(true)}
              onOpenMcp={() => setMcpDrawerOpen(true)}
              onManageAgent={() => navigate(`/agents/${id}`)}
              onClear={sender.handleClear}
            />

            <div className="chat-content-row">
              <ChatBody
                bodyRef={bodyRef}
                agent={agent}
                messages={messages}
                branches={branches}
                highlightId={highlightId}
                sending={sender.sending}
                streaming={sender.streaming}
                onRegenerate={sender.handleRegenerate}
                onSwitchBranch={sender.handleSwitchBranch}
                onCopy={(text, mode) => {
                  const content = mode === 'markdown' ? text : markdownToPlainText(text);
                  return navigator.clipboard
                    ?.writeText(content)
                    .then(() => message.success(mode === 'markdown' ? '已复制（Markdown）' : '已复制（纯文本）'));
                }}
              />

              <ChatOutline
                messages={messages}
                activeId={highlightId}
                onJump={(msgId) => {
                  setHighlightId(msgId);
                  const el = document.getElementById('msg-' + msgId);
                  if (el) el.scrollIntoView({ block: 'start', behavior: 'smooth' });
                }}
              />
            </div>

            <ChatInput
              input={sender.input}
              setInput={sender.setInput}
              sending={sender.sending}
              attachments={sender.attachments}
              setAttachments={(updater) => sender.setAttachments(updater)}
              imageUrls={sender.imageUrls}
              setImageUrls={(updater) => sender.setImageUrls(updater)}
              onSend={sender.handleSend}
              onStop={sender.handleStop}
              onAttach={sender.handleAttach}
              onOpenTpl={() => setTplDrawerOpen(true)}
              modelOptions={sender.modelOptions}
              activeModelValue={sender.activeModelValue}
              onChangeModel={(modelId) => {
                const selected = sender.modelOptions.find((m) => m.value === modelId);
                setOverrides((o) => ({ ...o, model_id: String(modelId), model: selected?.label || String(modelId) }));
              }}
            />
          </>
        )}
      </section>

      <ChatDrawers
        agentId={id}
        agent={agent}
        input={sender.input}
        setInput={(updater) => sender.setInput(updater(sender.input))}
        overrides={overrides}
        setOverrides={(updater) => setOverrides(updater)}
        sessionId={sessionId}
        setSessionId={setSessionId}
        setHighlightId={setHighlightId}
        sessionRefresh={sender.sessionRefresh}
        mcpDrawerOpen={mcpDrawerOpen}
        setMcpDrawerOpen={setMcpDrawerOpen}
        tplDrawerOpen={tplDrawerOpen}
        setTplDrawerOpen={setTplDrawerOpen}
        paramsDrawerOpen={paramsDrawerOpen}
        setParamsDrawerOpen={setParamsDrawerOpen}
        historyDrawerOpen={historyDrawerOpen}
        setHistoryDrawerOpen={setHistoryDrawerOpen}
        notify={{ success: (t) => message.success(t) }}
      />
    </div>
  );
}
