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 { SessionAPI } 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';

const lastRoomKey = (agentId: string) => `chat:lastRoom:${agentId}`;
const isValidRoomId = (v: string | null): v is string => !!v && !String(v).startsWith('legacy_');

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

  const [roomId, setRoomId] = 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(() => {
    if (!id) return;
    abortRef.current?.abort();
    setRoomId(null);
    setHighlightId(null);

    const s = searchParams.get('session');
    const m = searchParams.get('msg');

    if (isValidRoomId(s)) {
      setRoomId(s);
      try {
        localStorage.setItem(lastRoomKey(id), s);
      } catch {
        // ignore
      }
      if (m) {
        setHighlightId(m);
        const next = new URLSearchParams(searchParams);
        next.delete('msg');
        setSearchParams(next, { replace: true });
      }
      return;
    }
    if (s && !isValidRoomId(s)) {
      const next = new URLSearchParams(searchParams);
      next.delete('session');
      next.delete('msg');
      setSearchParams(next, { replace: true });
    }

    const saved = (() => {
      try {
        return localStorage.getItem(lastRoomKey(id));
      } catch {
        return null;
      }
    })();
    if (isValidRoomId(saved)) {
      setRoomId(saved);
      return;
    }
    if (saved && !isValidRoomId(saved)) {
      try {
        localStorage.removeItem(lastRoomKey(id));
      } catch {
        // ignore
      }
    }

    (async () => {
      try {
        const list = await SessionAPI.list(id, '0');
        if (list.length > 0) {
          setRoomId(list[0].id);
          return;
        }
        const created = await SessionAPI.create(id);
        setRoomId(created.id);
      } catch (e: any) {
        message.error('加载房间失败：' + (e?.message ?? e));
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id]);

  useEffect(() => {
    if (!id || !roomId) return;
    try {
      localStorage.setItem(lastRoomKey(id), roomId);
    } catch {
      // ignore
    }
    const cur = searchParams.get('session');
    if (cur === roomId) return;
    const next = new URLSearchParams(searchParams);
    next.set('session', roomId);
    next.delete('msg');
    setSearchParams(next, { replace: true });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id, roomId]);

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

  const sender = useChatSender({
    agentId: id,
    agent,
    agentList,
    roomId,
    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}
                agentList={agentList}
                currentAgentId={id!}
                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) }));
              }}
              onOpenHistory={() => setHistoryDrawerOpen(true)}
              onNewSession={async () => {
                if (!id) return;
                abortRef.current?.abort();
                try {
                  const created = await SessionAPI.create(id);
                  setHighlightId(null);
                  setMessages(() => []);
                  setBranches({});
                  setRoomId(created.id);
                } catch (e: any) {
                  message.error('创建房间失败：' + (e?.message ?? e));
                }
              }}
              agentList={agentList}
              onInsertMention={() => {}}
            />
          </>
        )}
      </section>

      <ChatDrawers
        agentId={id}
        agent={agent}
        input={sender.input}
        setInput={(updater) => sender.setInput(updater(sender.input))}
        overrides={overrides}
        setOverrides={(updater) => setOverrides(updater)}
        roomId={roomId}
        setRoomId={setRoomId}
        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>
  );
}
