import { TopicItem, HierarchyResult } from "@/types";
import { caclculateX } from "@/utils/hierarchy/rightFishbone";

// branch subtopic
const B2SH = 20;
const S2SH = 20;
const B2SV = 20;
const S2SV = 20;
function firstWalk(node: TopicItem): HierarchyResult {
  const root: HierarchyResult = {
    x: 0,
    y: 0,
    totalHeight: 0,
    totalWidth: 0,
    width: node.width,
    height: node.height,
    id: node.id,
    data: node,
    children: [],
  };

  root.children = node.collapsed
    ? []
    : node.children?.map((child) => firstWalk(child)) || [];

  return root;
}

// 计算每个分支主题位置
function secondWalk(root: HierarchyResult) {
  let startUpX = -B2SH;
  let startDownX = -B2SH;
  let startY = root.height / 2;
  root.children.forEach((branch, i) => {
    // 上排骨架处理
    if(i%2 === 0) {
      const x =  Math.min(startUpX, startDownX);
      const childPosition = thirdWalk(branch, "up", {
        x,
        y: startY,
      });
  
      branch.x = childPosition.endX - branch.width / 2;
      // 本身大于子主题的宽
      if (branch.width >= childPosition.totalWidth) {
        branch.x = x - branch.width;
      }
      branch.y = childPosition.endY - branch.height;
      branch.totalHeight = branch.height + childPosition.totalHeight;
      branch.totalWidth = Math.max(branch.width, childPosition.totalWidth);
      startUpX = x - branch.totalWidth - S2SH;
    } else {
      const previous = root.children[i - 1];
      const x = caclculateX({
        x: previous.x + previous.width / 2,
        y: previous.y + previous.height,
      }, startY, 'left', 'up') - S2SH;
      const childPosition = thirdWalk(branch, "down", {
        x,
        y: startY,
      });
  
      branch.x = childPosition.endX - branch.width / 2;
      // 本身大于子主题的宽
      if (branch.width >= childPosition.totalWidth) {
        branch.x = x - S2SH;
      }
  
      branch.y = childPosition.endY + branch.height;
      branch.totalHeight = branch.height + childPosition.totalHeight;
      branch.totalWidth = Math.max(branch.width, childPosition.totalWidth);
      startDownX = x - branch.totalWidth - S2SH;
    }
  });
}

// 计算一级子主题的宽高位置
function thirdWalk(
  branch: HierarchyResult,
  direction: "up" | "down",
  position: { x: number; y: number }
) {
  let totalHeight = 0;
  let totalWidth = 0;
  // 记录最终分支主题的位置
  let startY = position.y + (direction === "up" ? -2*B2SV : +B2SV);

  for (let i = branch.children.length - 1; i >= 0; i--) {
    const child = branch.children[i];
    const childSize = fourthWalk(child);
    // 根据上下，设置子节点Y的位置
    if(direction === "up") {
      child.y = startY - childSize.totalHeight / 2;
      startY += -childSize.totalHeight - S2SV;
    }
    if(direction === "down") {
      child.y = startY + childSize.totalHeight / 2;
      startY += childSize.totalHeight + S2SV;
    }
    // 计算出在斜线上x的位置 最后的结果加上偏移量
    const x = caclculateX(position, child.y, 'left', direction);
    child.x = x - child.width - S2SH;
    // 总的宽度 = 子节点到最开始的位置的距离中最大的一个
    const w = child.x - childSize.totalWidth - S2SH;
    totalWidth = Math.max(totalWidth, -w);
    totalHeight += childSize.totalHeight + B2SV;

    fivethWalk(child);
  }

  return {
    endX: caclculateX(position, startY, 'left', direction),
    endY: startY,
    totalHeight: Math.max(branch.height, totalHeight),
    totalWidth: Math.max(branch.width, totalWidth),
  };
}

// 获取子主题的宽高
function fourthWalk(node: HierarchyResult) {
  let totalHeight = 0;
  let totalWidth = node.width;

  node.children.forEach((child: HierarchyResult, i) => {
    const childrenSize = fourthWalk(child);
    totalHeight += childrenSize.totalHeight;
    if(i !== node.children.length - 1) {
      totalHeight += S2SV;
    }
    totalWidth = Math.max(totalWidth, node.width + childrenSize.totalWidth);
  });

  node.totalHeight = Math.max(node.height, totalHeight);
  node.totalWidth = totalWidth;
  return {
    totalWidth: node.totalWidth,
    totalHeight: node.totalHeight,
  };
}

// 设置子子主题位置
function fivethWalk(node: HierarchyResult) {
  let startY = node.y + node.height / 2 - node.totalHeight / 2;
  const startX = node.x - S2SH;
  node.children?.forEach((child) => {
    child.x = startX - child.width;
    child.y = startY + child.totalHeight / 2 - child.height / 2;
    startY += child.totalHeight + S2SV;
    if (child.children?.length) {
      fivethWalk(child);
    }
  });
}

export const getLeftFishboneHierarchy = <K>(
  topic: TopicItem,
): K => {
  const root = firstWalk(topic);
  secondWalk(root);

  console.log(root);
  return root as K;
};
