import { TopicType } from "@/enum";
import { MindMapProjectInfo, TopicItem } from "@/types";
import { Graph, Cell, Node } from "@antv/x6";
import TopicComponent from "@/components/mindMap/Topic";
import { topicData } from "@/config/data";
import { uuid } from "@/utils";
import { hierarchyMethodMap } from "@/pages/mindmap/hierarchy";
import { createEdge } from "./edge";
import { getTheme } from "./theme";

interface HierarchyResult {
  id: string;
  x: number;
  y: number;
  data: TopicItem;
  children?: HierarchyResult[];
}
/**
 * 渲染思维导图项目
 * @param graph 
 */
export const renderMindMap = (
  graph: Graph,
  setMindProjectInfo: () => void
) => {
  const projectInfo = getMindMapProjectByLocal();
  if(!projectInfo) return;
  const { topics, pageSetting } = projectInfo;
  const cells: Cell[] = [];
  topics.forEach((topic) => {
    // 遍历出层次结构
    const result: HierarchyResult = hierarchyMethodMap[projectInfo.structure]?.(topic, pageSetting);

    let originPosition = { x: topic?.x ?? -10, y: topic?.y ?? -10 };
    if(graph.hasCell(topic.id)) {
      const node = graph.getCellById(topic.id);
      if(node.isNode()) {
        originPosition = node.position();
      }
    }
    const offsetX = originPosition.x - result.x;
    const offsetY = originPosition.y - result.y;
    const traverse = (
      hierarchyItem: HierarchyResult,
      parent?: Node
    ) => {
      if (hierarchyItem) {
        const { data, children, x, y } = hierarchyItem;
        const id = data?.id || uuid();
        // 创建主题
        const node = graph.createNode({
          ...TopicComponent,
          width: data.width,
          height: data.height,
          data: {
            ...data,
            // 节点内部执行数据更新方法
            setMindProjectInfo,
          },
          id,
          x: offsetX + x,
          y: offsetY + y,
        });
        cells.push(node);
        parent && parent.addChild(node);

        if (children) {
          children.forEach((item: HierarchyResult) => {
            cells.push(
              // 创建连线
              createEdge(graph, id, item, projectInfo.structure, projectInfo.theme)
            );
            // 递归遍历
            traverse(item, node);
          });
        }
      }
    };
    
    traverse(result);
  });
  // 处理节点
  cells.filter(cell => cell.isNode()).forEach((cell) => {
    // 存在更新位置，否则添加
    if (graph.hasCell(cell.id)) {
      const oldCell = graph.getCellById(cell.id);
      if(oldCell.isNode()) {
        oldCell.position(cell.position().x, cell.position().y);
        oldCell.setData({
          ...cell.data
        })
      }
    } else {
      graph.addCell(cell);
    }
  });
  cells.filter(cell => cell.isEdge()).forEach((cell) => {
    graph.removeCell(cell.id);
    graph.addCell(cell);
  })
  const oldCells = graph.getCells();
  // 移除不存在的节点
  oldCells.forEach((cell) => {
    if (!cells.find(item => cell.id === item.id)) {
      graph.removeCell(cell.id + '-edge');
      graph.removeCell(cell);
    }
  });
  // graph.centerContent();
};

/**
 * 添加分支主题
 */
export const addTopic = (
  type: TopicType,
  setMindProjectInfo: (info: MindMapProjectInfo) => void,
  node?: Node,
  otherData: Record<string, any> = {},
) => {
  const projectInfo = getMindMapProjectByLocal();
  if (!projectInfo || !setMindProjectInfo) return;

  const topic = buildTopic(type, {
    ...(otherData || {}),
    parentId: node?.id
  }, node);

  if( node) {
    const parentId = node.id;
    const traverse = (topics: TopicItem[]) => {
      topics.forEach((item) => {
        if (item.id === parentId) {
          if (item.children) {
            item.children?.push(topic);
          } else {
            item.children = [topic];
          }
        }
        if (item.children) {
          traverse(item.children);
        }
      });
    };
    traverse(projectInfo?.topics || []);
  } else {
    projectInfo.topics.push(topic);
  }

  setMindProjectInfo(projectInfo);
  return topic;
};

const topicMap = {
  [TopicType.main]: {
    label: "中心主题",
    width: 206,
    height: 70
  },
  [TopicType.branch]: {
    label: "分支主题",
    width: 104,
    height: 40
  },
  [TopicType.sub]: {
    label: "子主题",
    width: 76,
    height: 27
  }
};

/**
 * 构建一个主题数据
 * @param type 主题类型
 * @param options 配置项
 * @returns
 */
export const buildTopic = (
  type: TopicType,
  options: Record<string, any> = {},
  parentNode?: Node
) => {
  const projectInfo = getMindMapProjectByLocal();

  const theme = getTheme(projectInfo?.theme, type === TopicType.sub ? parentNode : undefined);
  return {
    ...topicData,
    id: uuid(),
    type,
    label: topicMap[type].label || "自由主题",
    width: topicMap[type].width || 206,
    height: topicMap[type].height || 70,
    fill: {
      ...topicData.fill,
      ...theme[type]?.fill,
    },
    text: {
      ...topicData.text,
      ...theme[type]?.text,
    },
    stroke: {
      ...topicData.stroke,
      ...theme[type]?.stroke,
    },
    edge: {
      ...topicData.edge,
      color: theme[type]?.edge.color,
    },
    ...options,
  };
};

/**
 * 从本地获取项目信息
 * @returns
 */
export const getMindMapProjectByLocal = (): MindMapProjectInfo | null => {
  return JSON.parse(localStorage.getItem("minMapProjectInfo") || "null");
};

/**
 * 更新主题数据
 * @param id 主题id
 * @param value 更新的数据
 * @param setMindProjectInfo 更新项目信息方法
 */
export const updateTopic = (
  id: string,
  value: Partial<TopicItem>,
  setMindProjectInfo: (info: MindMapProjectInfo) => void
) => {
  const projectInfo = getMindMapProjectByLocal();
  if (!projectInfo || !setMindProjectInfo) return;
  
  const traverse = (topics: TopicItem[]) => {
    topics.forEach((item) => {
      if (item.id === id) {
        Object.assign(item, value);
      }
      if (item.children) {
        traverse(item.children);
      }
    });
  };

  traverse(projectInfo?.topics || []);
  setMindProjectInfo(projectInfo);
}
