import { getFlowById } from "@/api/device/register";

const loadNodeRedData = async (id) => {
  const data = await getFlowById(id);
  return Array.isArray(data?.nodes) ? data.nodes : [];
};

export const convertNodeRedToVueFlow = async (id) => {
  const source = await loadNodeRedData(id);
  const nodes = source.map((node) => {
    const isGroup = node.type === "group";
    const width = isGroup ? Number(node.w || 300) + 80 : 200;
    const height = isGroup ? Number(node.h || 180) + 80 : 100;
    const center = { x: Number(node.x || 0) * 2, y: Number(node.y || 0) * 2 };
    return {
      id: node.id,
      type: isGroup ? "runtime-group" : "runtime-node",
      position: { x: center.x - width / 2, y: center.y - height / 2 },
      width,
      height,
      draggable: false,
      selectable: true,
      connectable: false,
      deletable: false,
      zIndex: isGroup ? -1 : 1,
      data: {
        text: node.name || node.type,
        properties: { ...node, state: "unexecuted" },
        children: isGroup ? node.nodes || [] : [],
      },
    };
  });

  const edges = [];
  source.forEach((node) => {
    (node.wires || []).forEach((targets) => {
      (targets || []).forEach((targetId) => {
        edges.push({
          id: `edge-${node.id}-${targetId}`,
          source: node.id,
          target: targetId,
          sourceHandle: `${node.id}_1`,
          targetHandle: `${targetId}_3`,
          type: "bezier",
          animated: true,
          selectable: true,
          focusable: true,
          interactionWidth: 32,
          markerEnd: {
            type: "arrowclosed",
            color: "#2f80ed",
            width: 20,
            height: 20,
          },
          style: { stroke: "#2f80ed", strokeWidth: 2 },
        });
      });
    });
  });

  return { nodes, edges };
};

export const updateDerivedNodeStates = (nodes, getProperties, setProperties) => {
  const ignored = ["inject", "cmvrLoop", "startCamera", "getImage", "stopCamera", "startVideo", "stopVideo", "end"];
  nodes.filter((node) => !ignored.includes(node.data.properties.type)).forEach((current) => {
    nodes.forEach((target) => {
      if (current.data.properties.wires?.[0]?.includes(target.id) && getProperties(target.id).state !== "unexecuted") {
        setProperties(current.id, { state: "success" });
      }
      if (current.data.properties.wires?.[1]?.includes(target.id)) {
        setProperties(current.id, { state: getProperties(target.id).state === "failed" ? "failed" : "running" });
      }
    });
  });
};
