import chatStyles from "@/app/components/chat.module.scss";
import homeStyles from "@/app/components/home.module.scss";

import { MindSiderBar } from "./mind-siderBar";
import MindElixir, {
  type Options,
  type MindElixirData,
  NodeObj,
} from "mind-elixir";
import { WindowContent } from "@/app/components/home";
import { useMobileScreen } from "@/app/utils";
import { IconButton } from "../button";
import Locale from "@/app/locales";
import { Path } from "@/app/constant";
import { useNavigate, useLocation } from "react-router-dom";
import clsx from "clsx";
import { getClientConfig } from "@/app/config/client";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useAppConfig } from "@/app/store";

import ReturnIcon from "@/app/icons/return.svg";
import MinIcon from "@/app/icons/min.svg";
import MaxIcon from "@/app/icons/max.svg";
import SDIcon from "@/app/icons/sd.svg";
import BoldIcon from "@/app/icons/bold.svg";
import FontColorIcon from "@/app/icons/fontColor.svg";
import FontBgIcon from "@/app/icons/fontBg.svg";
import CenterIcon from "@/app/icons/center.svg";
import MindIcon from "@/app/icons/mind.svg";
import LeftIcon from "@/app/icons/leftMind.svg";
import RightIcon from "@/app/icons/rightMind.svg";
import LineIcon from "@/app/icons/line.svg";
import InitSideIcon from "@/app/icons/initSide.svg";

import { useChatStore, useMindMapStore } from "@/app/store";
import {
  message,
  Select,
  ColorPicker,
  Button,
  Space,
  Slider,
  Popover,
} from "antd";
import type { ColorPickerProps, GetProp } from "antd";

import {
  INITIAL_DATA,
  LOADING_DATA,
  FONT_SIZE_OPTIONS,
  EXPORT_OPTIONS,
  useColor,
} from "./mind-utils";

type Color = Extract<
  GetProp<ColorPickerProps, "value">,
  string | { cleared: any }
>;
const ScaleControl = ({
  value,
  onChange,
}: {
  value: number;
  onChange: (v: number) => void;
}) => (
  <Slider
    vertical
    value={value}
    onChange={onChange}
    style={{ height: "100px" }}
    min={35}
    max={200}
    tooltip={{ formatter: (v) => `${v}%` }}
  />
);

export function MindPage() {
  const isMobileScreen = useMobileScreen();
  const navigate = useNavigate();
  const clientConfig = useMemo(() => getClientConfig(), []);
  const showMaxIcon = !isMobileScreen && !clientConfig?.isApp;
  const config = useAppConfig();
  const scrollRef = useRef<HTMLDivElement>(null);
  const isMind = location.pathname === Path.Mind;
  const [isLoading, setIsLoading] = useState(false); //加载 辅助
  const containerRef = useRef<HTMLDivElement>(null); //思维导图容器
  const mindInstance = useRef<InstanceType<typeof MindElixir> | null>(null); //思维导图实例
  const chatStore = useChatStore();
  const { newMessages, content } = useMindMapStore.getState(); //聊天页面跳转时要生成的信息
  const query = useLocation();
  let { msg } = query.state || {};
  const [data, setData] = useState<MindElixirData>(INITIAL_DATA); //思维导图数据

  const [fontColor, setFontColor] = useColor("#1677ff"); //字体颜色
  const [nodeBgColor, setNodeBgColor] = useColor("#1677ff"); //节点背景颜色
  const [lineColor, setLinrColor] = useColor("#1677ff"); //分支颜色
  const [selectedNode, setSelectedNode] = useState<NodeObj | null>(null);
  const [scaleValue, setScaleValue] = useState(100);
  //如果是在聊天页面跳转过来时需要发起请求
  const fetchData = async () => {
    if (!msg) return;
    if (!content) return;
    setIsLoading(true);
    try {
      const response = await chatStore.sendContext(newMessages, "gpt-4o-mini");
      const cleanedContent = response.replace(/^```json|```$/g, "");
      const parsedData: MindElixirData = JSON.parse(cleanedContent);
      // 增强校验逻辑
      if (
        !parsedData?.nodeData?.id ||
        !Array.isArray(parsedData.nodeData.children)
      ) {
        throw new Error("数据结构不完整");
      }
      setData(parsedData);
      navigate(Path.Mind, { replace: true, state: { msg: null } });
    } catch (error) {
      message.error("请求失败,请重试");
    } finally {
      setIsLoading(false); // 确保关闭加载状态
    }
  };

  useEffect(() => {
    // 确保容器元素已挂载
    if (!containerRef.current) return;
    // 初始化配置项
    const options: Options = {
      el: containerRef.current,
      locale: "zh_CN",
      draggable: true,
      contextMenu: true,
      toolBar: false,
      nodeMenu: false,
    };
    // 创建实例
    mindInstance.current = new MindElixir(options);
    mindInstance.current.init(data);
    const el = mindInstance.current?.container.querySelector("me-root");
    //添加鼠标移入中心主题时鼠标变手的样式
    const style = document.createElement("style");
    // 添加 CSS 样式
    style.textContent = `
      me-root:hover {
        cursor: pointer;
      }
    `;
    // 将样式插入到文档中
    document.head.appendChild(style);

    const handleContainerClick = (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      // 检查点击的目标是否是某个特定的元素(比如 me-root)
      if (target.closest("me-root")) {
        // 获取 me-nodes 父元素
        const parentElement = target.closest("me-nodes");
        // 确保父元素存在并且是 HTMLElement 类型
        if (parentElement && parentElement instanceof HTMLElement) {
          // 鼠标按下时开始跟随
          const onMouseDown = (e: MouseEvent) => {
            // 记录鼠标按下的初始位置和父元素的初始位置
            const initialX = e.clientX;
            const initialY = e.clientY;
            const initialElementX = parentElement.offsetLeft;
            const initialElementY = parentElement.offsetTop;
            // 鼠标移动时更新父元素位置
            const onMouseMove = (moveEvent: MouseEvent) => {
              const deltaX = moveEvent.clientX - initialX;
              const deltaY = moveEvent.clientY - initialY;
              parentElement.style.position = "absolute";
              parentElement.style.left = `${initialElementX + deltaX}px`;
              parentElement.style.top = `${initialElementY + deltaY}px`;
            };
            // 鼠标松开时停止跟随
            const onMouseUp = () => {
              window.removeEventListener("mousemove", onMouseMove);
              window.removeEventListener("mouseup", onMouseUp);
            };
            // 添加事件监听器
            window.addEventListener("mousemove", onMouseMove);
            window.addEventListener("mouseup", onMouseUp);
          };
          // 添加鼠标按下事件监听器
          target.addEventListener("mousedown", onMouseDown);
        }
      }
    };
    //注册点击事件
    mindInstance.current.container.addEventListener(
      "click",
      handleContainerClick,
    );
    fetchData();
    //设置选择的节点用于调节样式
    mindInstance.current?.bus.addListener("selectNode", (node) => {
      setSelectedNode(node);
    });

    return () => {
      mindInstance.current?.container.removeEventListener(
        "click",
        handleContainerClick,
      );
      if (mindInstance.current) {
        mindInstance.current.destroy();
        mindInstance.current = null;
      }
    };
  }, []);

  //data更新思维导图更新数据
  useEffect(() => {
    mindInstance.current?.refresh(data);
  }, [data]);

  useEffect(() => {
    if (isLoading) {
      mindInstance.current?.refresh(LOADING_DATA);
    }
  }, [isLoading]);

  useEffect(() => {
    if (selectedNode) {
      // 更新字体颜色
      updateNodeStyle({ color: fontColor });
    }
  }, [fontColor]);

  useEffect(() => {
    if (selectedNode) {
      // 更新节点背景颜色
      updateNodeStyle({ background: nodeBgColor });
    }
  }, [nodeBgColor]);
  // 导出函数
  const handleDownload = async (type: "png" | "svg") => {
    try {
      const blob =
        type === "png"
          ? await mindInstance.current?.exportPng(false)
          : await mindInstance.current?.exportSvg(false);

      if (!blob) return;

      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${data.nodeData.topic}.${type}`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (error) {
      console.error("导出失败:", error);
      message.error("导出失败,请重试");
    }
  };
  //思维导图缩放函数
  const handleScaleChange = (value: number) => {
    setScaleValue(value);
    mindInstance.current?.scale(value / 100);
  };
  //更新样式
  const updateNodeStyle = (style: Partial<NodeObj["style"]>) => {
    if (selectedNode) {
      mindInstance.current?.reshapeNode(MindElixir.E(selectedNode.id), {
        style: { ...selectedNode.style, ...style },
      });
    }
  };
  //更新分支颜色
  const updateBranchColor = (value: string) => {
    if (selectedNode) {
      mindInstance.current?.reshapeNode(MindElixir.E(selectedNode.id), {
        branchColor: value,
      });
    }
  };

  const mindType = (
    <div>
      <Button
        icon={<LeftIcon />}
        onClick={() => {
          mindInstance.current?.initLeft();
        }}
      />
      <Button
        icon={<RightIcon />}
        onClick={() => {
          mindInstance.current?.initRight();
        }}
      />
      <Button
        icon={
          <InitSideIcon
            onClick={() => {
              mindInstance.current?.initSide();
            }}
          />
        }
      />
    </div>
  );
  //工具栏
  const renderToolbar = () => (
    <Space>
      <Popover
        content={
          <ScaleControl value={scaleValue} onChange={handleScaleChange} />
        }
      >
        <Button>{scaleValue}%</Button>
      </Popover>
      <Popover content={mindType}>
        <Button icon={<MindIcon />}></Button>
      </Popover>
      <Select
        options={EXPORT_OPTIONS}
        onSelect={handleDownload}
        placeholder="导出"
        style={{ width: 120 }}
      />

      <Select
        options={FONT_SIZE_OPTIONS}
        onSelect={(v) => updateNodeStyle({ fontSize: v })}
        placeholder="字号"
        style={{ width: 100 }}
        disabled={!selectedNode}
      />

      <Button
        icon={<CenterIcon />}
        onClick={() => mindInstance.current?.toCenter()}
      />

      <Button
        icon={<BoldIcon />}
        onClick={() =>
          updateNodeStyle({
            fontWeight:
              selectedNode?.style?.fontWeight === "bold" ? "normal" : "bold",
          })
        }
        disabled={!selectedNode}
      />
      <ColorPicker
        value={fontColor}
        onChange={(value) => {
          setFontColor(value || "#000000"); // 处理可能的空值
          updateNodeStyle({ color: value?.toHexString() || "#000000" });
        }}
        disabled={!selectedNode}
        showText
      >
        <Button icon={<FontColorIcon />} />
      </ColorPicker>

      <ColorPicker
        value={nodeBgColor}
        onChange={(value) => {
          setNodeBgColor(value || "#ffffff");
          updateNodeStyle({ background: value?.toHexString() || "#ffffff" });
        }}
        disabled={!selectedNode}
        showText
      >
        <Button icon={<FontBgIcon />} />
      </ColorPicker>

      <ColorPicker
        value={lineColor}
        onChange={(value) => {
          setLinrColor(value || "#ffffff");
          updateBranchColor(value?.toHexString() || "#ffffff");
        }}
        disabled={!selectedNode}
        showText
      >
        <Button icon={<LineIcon />} />
      </ColorPicker>
    </Space>
  );

  return (
    <>
      <MindSiderBar
        className={clsx({ [homeStyles["sidebar-show"]]: isMind })}
        setData={setData}
        isLoading={isLoading}
        setIsLoading={setIsLoading}
      />
      <WindowContent>
        <div className={chatStyles.chat} key={"1"}>
          <div className="window-header" data-tauri-drag-region>
            {isMobileScreen && (
              <div className="window-actions">
                <div className={"window-action-button"}>
                  <IconButton
                    icon={<ReturnIcon />}
                    bordered
                    title={Locale.Chat.Actions.ChatList}
                    onClick={() => navigate(Path.BgRemoval)}
                  />
                </div>
              </div>
            )}
            <div
              className={clsx(
                "window-header-title",
                chatStyles["chat-body-title"],
              )}
            >
              <div className={`window-header-main-title`}>生成思维导图</div>
            </div>
            <div className={chatStyles["chat-message-actions"]}>
              <div className={chatStyles["chat-input-actions"]}>
                {renderToolbar()}
              </div>
            </div>
            <div className="window-actions">
              {showMaxIcon && (
                <div className="window-action-button">
                  <IconButton
                    aria={Locale.Chat.Actions.FullScreen}
                    icon={config.tightBorder ? <MinIcon /> : <MaxIcon />}
                    bordered
                    onClick={() => {
                      config.update(
                        (config) => (config.tightBorder = !config.tightBorder),
                      );
                    }}
                  />
                </div>
              )}
              {isMobileScreen && <SDIcon width={50} height={50} />}
            </div>
          </div>
          <div className={chatStyles["chat-body"]} ref={scrollRef}>
            <div ref={containerRef} style={{ width: "100%", height: "100%" }} />
          </div>
        </div>
      </WindowContent>
    </>
  );
}