"use client";

import { useParams } from "next/navigation";
import {
  useCallback,
  useEffect,
  useRef,
  useState,
  type MouseEvent as ReactMouseEvent,
} from "react";
import MindmapCanvas from "../../../components/MindmapCanvas";
import ChatPanel from "../../../components/ChatPanel";
import { getMindmap } from "../../../lib/api";
import type { Mindmap } from "../../../types/mindmap";

type TriggerRequest = {
  id: number;
  content: string;
};

const MIN_CHAT_PANEL_WIDTH = 320;
const DEFAULT_CHAT_PANEL_WIDTH = 420;
const MAX_CHAT_PANEL_WIDTH_RATIO = 0.55;

export default function MindmapDetailPage() {
  const params = useParams<{ id: string }>();
  const uniqueId = params?.id ?? "";
  const containerRef = useRef<HTMLElement | null>(null);
  const [mindmap, setMindmap] = useState<Mindmap | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [showChat, setShowChat] = useState(false);
  const [isResizingChatPanel, setIsResizingChatPanel] = useState(false);
  const [chatPanelWidth, setChatPanelWidth] = useState(DEFAULT_CHAT_PANEL_WIDTH);
  const [triggerRequest, setTriggerRequest] = useState<TriggerRequest | undefined>();

  const clampChatPanelWidth = useCallback((nextWidth: number) => {
    const containerWidth =
      containerRef.current?.clientWidth ??
      (typeof window === "undefined" ? DEFAULT_CHAT_PANEL_WIDTH : window.innerWidth);
    const maxWidth = Math.max(
      MIN_CHAT_PANEL_WIDTH,
      Math.floor(containerWidth * MAX_CHAT_PANEL_WIDTH_RATIO),
    );

    return Math.min(Math.max(nextWidth, MIN_CHAT_PANEL_WIDTH), maxWidth);
  }, []);

  useEffect(() => {
    async function loadPageData() {
      if (!uniqueId) {
        setLoading(false);
        setError("缺少脑图 ID");
        return;
      }

      try {
        setLoading(true);
        setError("");
        const mindmapData = await getMindmap(uniqueId);
        setMindmap(mindmapData);
      } catch (pageError) {
        const message =
          pageError instanceof Error ? pageError.message : "加载脑图失败";
        setError(message);
      } finally {
        setLoading(false);
      }
    }

    void loadPageData();
  }, [uniqueId]);

  const handleNodeChat = useCallback(
    (nodeLabel: string) => {
      setShowChat(true);
      setChatPanelWidth((currentWidth) => clampChatPanelWidth(currentWidth));
      setTriggerRequest({
        id: Date.now() + Math.floor(Math.random() * 1000),
        content: `帮我解释一下 ${nodeLabel}`,
      });
    },
    [clampChatPanelWidth],
  );

  const handleCloseChat = useCallback(() => {
    setIsResizingChatPanel(false);
    setShowChat(false);
    setTriggerRequest(undefined);
  }, []);

  const handleResizeStart = useCallback(
    (event: ReactMouseEvent<HTMLDivElement>) => {
      event.preventDefault();
      setChatPanelWidth((currentWidth) => clampChatPanelWidth(currentWidth));
      setIsResizingChatPanel(true);
    },
    [clampChatPanelWidth],
  );

  useEffect(() => {
    if (!showChat) {
      setIsResizingChatPanel(false);
      return;
    }

    const handleWindowResize = () => {
      setChatPanelWidth((currentWidth) => clampChatPanelWidth(currentWidth));
    };

    handleWindowResize();
    window.addEventListener("resize", handleWindowResize);
    return () => window.removeEventListener("resize", handleWindowResize);
  }, [clampChatPanelWidth, showChat]);

  useEffect(() => {
    if (!showChat || !isResizingChatPanel) {
      return;
    }

    const handleMouseMove = (event: MouseEvent) => {
      if (!containerRef.current) {
        return;
      }

      const bounds = containerRef.current.getBoundingClientRect();
      const nextWidth = bounds.right - event.clientX;
      setChatPanelWidth(clampChatPanelWidth(nextWidth));
    };

    const stopResizing = () => {
      setIsResizingChatPanel(false);
    };

    const { style } = document.body;
    const previousCursor = style.cursor;
    const previousUserSelect = style.userSelect;

    style.cursor = "col-resize";
    style.userSelect = "none";

    window.addEventListener("mousemove", handleMouseMove);
    window.addEventListener("mouseup", stopResizing);
    window.addEventListener("blur", stopResizing);

    return () => {
      style.cursor = previousCursor;
      style.userSelect = previousUserSelect;
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseup", stopResizing);
      window.removeEventListener("blur", stopResizing);
    };
  }, [clampChatPanelWidth, isResizingChatPanel, showChat]);

  if (loading) {
    return (
      <main className="flex h-screen w-screen items-center justify-center bg-white">
        <div className="rounded-3xl bg-white px-8 py-6 shadow-panel">
          正在加载思维导图...
        </div>
      </main>
    );
  }

  if (error || !mindmap) {
    return (
      <main className="flex h-screen w-screen flex-col items-center justify-center bg-white px-6 text-center">
        <div className="rounded-3xl bg-white px-8 py-8 shadow-panel">
          <p className="text-lg font-semibold text-rose-600">
            {error || "未找到对应脑图"}
          </p>
        </div>
      </main>
    );
  }

  return (
    <main ref={containerRef} className="flex h-screen w-screen overflow-hidden bg-white">
      <section className="min-w-0 flex-1">
        <MindmapCanvas tree={mindmap.tree} onNodeChat={handleNodeChat} />
      </section>
      {showChat && (
        <>
          <div
            role="separator"
            aria-label="调整聊天区域宽度"
            aria-orientation="vertical"
            onMouseDown={handleResizeStart}
            className="group relative w-3 shrink-0 cursor-col-resize bg-transparent"
          >
            <div
              className={`absolute inset-y-0 left-1/2 w-px -translate-x-1/2 transition-colors ${
                isResizingChatPanel
                  ? "bg-blue-500"
                  : "bg-slate-200 group-hover:bg-blue-300"
              }`}
            />
            <div
              className={`absolute left-1/2 top-1/2 h-16 w-1.5 -translate-x-1/2 -translate-y-1/2 rounded-full transition-colors ${
                isResizingChatPanel
                  ? "bg-blue-500"
                  : "bg-slate-300 group-hover:bg-blue-400"
              }`}
            />
          </div>
          <aside
            style={{ width: `${chatPanelWidth}px` }}
            className="min-w-0 shrink-0 overflow-hidden bg-slate-50 shadow-[-18px_0_36px_rgba(15,23,42,0.06)]"
          >
            <ChatPanel
              sessionId={mindmap.session_id}
              triggerRequest={triggerRequest}
              onClose={handleCloseChat}
            />
          </aside>
        </>
      )}
    </main>
  );
}
