import type { MessageInstance } from "antd/lib/message/interface";
import type { TopicItem, HierarchyResult } from "../types";

/**
 * 遍历主题树
 * @param topics
 * @param callback
 * @returns
 */
export const traverseNode = (
  topics: TopicItem[],
  callback: (topic: TopicItem, index: number) => void
): TopicItem[] => {
  return topics.map((topic, index) => {
    callback && callback(topic, index);
    if (topic.children?.length) {
      topic.children = traverseNode(topic.children, callback);
    }
    // 遍历概要
    if (topic?.summary?.topic) {
      topic.summary.topic = traverseNode([topic.summary.topic], callback)[0];
    }
    return topic;
  });
};

/**
 * 计算当前节点总大小
 * @param topItem 
 * @param children 
 * @returns 
 */
export const cacluculateExtremeValue = (topItem: HierarchyResult, children: HierarchyResult[]) => {
  let minX = topItem.x;
  let minY = topItem.y;
  let maxX = minX + topItem.data.width;
  let maxY = minY + topItem.data.height;
  children.forEach((child) => {
    const childXY = cacluculateExtremeValue(child, child.children);
    minX = Math.min(minX, child.x, childXY.minX);
    minY = Math.min(minY, child.y, childXY.minY);
    maxX = Math.max(maxX, child.x + child.data.width, childXY.maxX);
    maxY = Math.max(maxY, child.y + child.data.height, childXY.maxY);
  });

  return {
    minX,
    minY,
    maxX,
    maxY
  }
};

/**
 * 获取边框位置及大小
 * @param hierarchyItem
 * @returns
 */
export const getBorderPositionAndSize = (hierarchyItem: HierarchyResult) => {
  const firstChild = hierarchyItem?.children?.[0];
  let totalHeigth = hierarchyItem?.totalHeight || 0;
  let totalWidth = hierarchyItem?.totalWidth || 0;
  let x = hierarchyItem?.x || 0;
  let y = hierarchyItem?.y || 0;

  // 是否存在子节点
  if (firstChild) {
    const position = cacluculateExtremeValue(hierarchyItem, hierarchyItem.children || []);
    x = position.minX;
    y = position.minY;
    totalHeigth = position.maxY - position.minY;
    totalWidth = position.maxX - position.minX;
  } else {
    totalWidth = hierarchyItem.data.width;
    totalHeigth = hierarchyItem.data.height;
  }
  return {
    x: x - 10,
    y: y - 10,
    width: totalWidth + 20,
    height: totalHeigth + 20,
  };
};

type TreeNode = {
  id: string;
  parentId?: string;
  name: string;
  children?: TreeNode[];
} & Record<string, any>;

/**
 * 列表转树结构
 * @param list
 * @param pid
 * @param parentKey
 */
export const listToTree = (list: TreeNode[], parent: TreeNode): TreeNode => {
  const map: { [key: string]: TreeNode } = {
    [parent.id]: parent,
  };

  // 首先将所有节点放入 map 中
  list.forEach((node) => {
    map[node.id] = { ...node, children: [] };
  });
  // 再次遍历列表，构建树结构
  list.forEach((node) => {
    const currentNode = map[node.id];
    if (node.parentId && map[node.parentId]) {
      // 如果有父节点，则将当前节点添加到父节点的 children 中
      map?.[node.parentId]?.children?.push(currentNode);
    }
  });
  return parent;
};

/**
 * 获取token
 */
export const getToken = () => {
  const enterpriseCode = sessionStorage.getItem("enterpriseCode");
  const token = localStorage.getItem("token_" + enterpriseCode);

  return token;
};

// Mermaid 流程图检测
export function isMermaidFlowchart(code: string): boolean {
  const flowchartRegex = /^\s*graph|flowchart\s+(TD|LR|RL|TB)\s*\n/i;
  const nodeRegex = /(\w+)\[(.*?)\]|\{|\}/;
  return flowchartRegex.test(code) && nodeRegex.test(code);
}

function regexExtractJSON(markdown: string) {
  const jsonRegex = /```(?:json)?\n([\s\S]*?)\n```/g;
  const matches = [];
  let match;

  while ((match = jsonRegex.exec(markdown)) !== null) {
    try {
      const jsonObj = JSON.parse(match[1]);
      matches.push(jsonObj);
    } catch (e) {
      console.warn("无效JSON:", match[0]);
    }
  }
  return matches;
}

/**
 * 转换解析出ai数据
 * @param content
 * @param message
 * @param onSuccess
 * @param onError
 */
export const handleParseFowlAIData = ({
  content,
  message,
  onSuccess,
  onError,
}: {
  content: string;
  message: {
    key: string;
    instance: MessageInstance;
  };
  onSuccess?: (data: any) => void;
  onError?: (err: Error) => void;
}) => {
  try {
    // 根据markdown格式取出json部分数据
    let json: string;
    if (content.includes("```json")) {
      json = regexExtractJSON(content)?.[0];
    } else {
      json = JSON.parse(content);
    }

    onSuccess?.(json);
  } catch (error) {
    message.instance.open({
      key: message.key,
      type: "error",
      content: "AI创作失败",
      duration: 2,
      style: {
        marginTop: 300,
      },
    });
    console.error(error);
    onError?.(new Error("AI创作失败"));
  }
};
