import {
  LinkHorizontal,
  LinkHorizontalCurve,
  LinkHorizontalLine,
  LinkHorizontalStep,
  LinkVertical,
  LinkVerticalCurve,
  LinkVerticalLine,
  LinkVerticalStep,
} from "@visx/shape";
import _, { uniqueId } from "lodash";
import ZoomOutMapIcon from "@mui/icons-material/ZoomOutMap";
import ZoomInMapIcon from "@mui/icons-material/ZoomInMap";
import HorizontalIcon from "@mui/icons-material/AlignHorizontalLeft";
import VerticalIcon from "@mui/icons-material/AlignVerticalTop";
import { IconButton } from "@mui/material";
import { ActionButtonProps, DimensionType } from "./interface";

export const adjustZoom = (
  dimension: DimensionType,
  action: boolean,
  initialDimension: DimensionType
): DimensionType => {
  if (action) {
    const zoomData: DimensionType = {
      ...dimension,
      muliplier: 2,
      container: {
        style: {
          height: "105vh",
          width: "100vw",
          position: "fixed",
          top: 0,
          left: 0,
          zIndex: 1200,
        },
      },
      graphHeight: "100vh",
      graphWidth: "calc(100vw - 15px)",
      width: Number(dimension.width) * 1.4,
      height: Number(dimension.height) * 1.2,
    };
    return zoomData;
  }
  return { ...initialDimension, orientation: dimension.orientation };
};

export const validate = (value) => {
  if (!_.isEmpty(value) && _.isObject(value)) {
    return value;
  }
  return { label1: "No Data Found", iconName1: "No_Data" };
};

export const ActionButton = ({
  dimension,
  adjustZoom,
  setDimension,
  // forceUpdate,
  zoom,
  setZoom,
  dimensionInitial,
}: ActionButtonProps) => {
  return (
    <>
      <IconButton
        style={{
          color: "white",
          position: "absolute",
          zIndex: 400,
          top: zoom ? 3 : 2,
          right: zoom ? 13 : 5,
        }}
        onClick={() => {
          const value = adjustZoom(dimension, !zoom, dimensionInitial);
          setDimension(value);
          // forceUpdate();
          setZoom((pre) => !pre);
        }}
      >
        {zoom ? (
          <ZoomInMapIcon
            titleAccess="Zoom Out"
            sx={{ fontSize: "15px", color: "black" }}
          />
        ) : (
          <ZoomOutMapIcon
            titleAccess="Zoom In"
            sx={{ fontSize: "15px", color: "black" }}
          />
        )}
      </IconButton>
      <IconButton
        style={{
          color: "white",
          position: "absolute",
          zIndex: 400,
          top: zoom ? 3 : 2,
          right: zoom ? 34 : 28,
        }}
        onClick={() => {
          setDimension({
            ...dimension,
            orientation:
              dimension.orientation === "vertical" ? "horizontal" : "vertical",
          });
        }}
      >
        {dimension.orientation === "horizontal" ? (
          <VerticalIcon
            titleAccess="Vertical orientation"
            sx={{ fontSize: "15px", color: "black" }}
          />
        ) : (
          <HorizontalIcon
            titleAccess="Horizontal orientation"
            sx={{ fontSize: "15px", color: "black" }}
          />
        )}
      </IconButton>
    </>
  );
};

export const colorsProvider = (uischema: any): Record<string, string> => {
  return (
    uischema.config?.mian?.colorsArray || [
      "#03992e",
      "#15727a",
      "#15157a",
      "#7a2415",
      "#15357a",
      "rgba(25,200,205,0.6)",
      "#3f84b5",
      "#b5993f",
      "#fc6f6f",
      "tomato",
      "yellow",
      "techblue",
    ]
  );
};
export const getInitialDimensions = (uiSchemaData: any): DimensionType => {
  const dimensionInitial: DimensionType = _.cloneDeep({
    muliplier: 1,
    containerHeight: uiSchemaData.graphHeight || 460,
    graphHeight: uiSchemaData.graphHeight || 420,
    graphZoomHeight: uiSchemaData.graphZoomHeight,
    graphZoomWidth: uiSchemaData.graphZoomWidth,
    graphWidth: uiSchemaData.graphWidth || "inherit",
    orientation: uiSchemaData.orientation || "horizontal",
    width: uiSchemaData.width || 120,
    height: uiSchemaData.height || 60,
  });
  return dimensionInitial;
};
export default function getLinkComponent({
  linkType,
  orientation,
}: {
  layout: string;
  linkType: string;
  orientation: string;
}): any {
  let LinkComponent: any;
  if (orientation === "vertical") {
    if (linkType === "step") {
      LinkComponent = LinkVerticalStep;
    } else if (linkType === "curve") {
      LinkComponent = LinkVerticalCurve;
    } else if (linkType === "line") {
      LinkComponent = LinkVerticalLine;
    } else {
      LinkComponent = LinkVertical;
    }
  } else if (linkType === "step") {
    LinkComponent = LinkHorizontalStep;
  } else if (linkType === "curve") {
    LinkComponent = LinkHorizontalCurve;
  } else if (linkType === "line") {
    LinkComponent = LinkHorizontalLine;
  } else {
    LinkComponent = LinkHorizontal;
  }
  return LinkComponent;
}

const findAndRemoveNode = (tree, label) => {
  if (!tree.children) return null;

  for (let i = 0; i < tree.children.length; i++) {
    if (tree.children[i].id === label) {
      return tree.children.splice(i, 1)[0];
    } else {
      const result = findAndRemoveNode(tree.children[i], label);
      if (result) return result;
    }
  }
  return null;
};

const findAndAddNode = (tree, label, nodeToAdd) => {
  if (tree.id === label) {
    tree.children = tree.children || [];
    tree.children.push(nodeToAdd);
    return true;
  }

  if (!tree.children) return false;

  for (let i = 0; i < tree.children.length; i++) {
    if (findAndAddNode(tree.children[i], label, nodeToAdd)) {
      return true;
    }
  }
  return false;
};

export const moveNode = (tree, addInChildrenNode, removeNode) => {
  const newTree = _.cloneDeep(tree);
  const nodeToMove = findAndRemoveNode(newTree, removeNode);
  if (!nodeToMove) {
    return tree;
  }
  if (!findAndAddNode(newTree, addInChildrenNode, nodeToMove)) {
    return tree;
  }
  return newTree;
};
export function assignUniqueIds(data) {
  function recursiveAssignId(item) {
    item.id = uniqueId();
    if (item?.children && Array.isArray(item?.children)) {
      item?.children?.forEach((child) => recursiveAssignId(child));
    }
  }
  const dataWithId = { ...data, id: Math.random() * 100 };
  dataWithId?.children?.forEach((item) => recursiveAssignId(item));
  return data;
}
