// 数据转化
export const DagToData = (graph: any, dagId: any, requirements: any) => {
  const dagData = graph.toJSON();
  const { edges, nodes } = getEdgesAndNodes(graph);
  // const { script_nodes, script_edges } = getScriptEdgesAndNodes(graph);
  return {
    dag_id: dagId,
    requirements,
    user_name: 'XXX',
    user_id: 1,
    nodes_task_name: 'dfs',
    nodes_task_id: 123,
    itermidate_data: ['hdfs://host:port/uri'],
    nodes,
    edges,
    // dag_script: {
    //   sub_nodes: script_nodes,
    //   edges: script_edges
    // },
    graph: dagData
  };
};

// 获取所有Edge和Nodes
const getEdgesAndNodes = (graph: any) => {
  const dagData = graph.toJSON();
  const edges: any = [];
  const nodes: any = [];
  dagData.cells.forEach((item: any) => {
    if (item?.shape === 'dag-edge') {
      const sourceNodeId = graph.getCellById(item.source.cell).data.nodeId;
      const targetNodeId = graph.getCellById(item.target.cell).data.nodeId;
      edges.push({
        source: sourceNodeId,
        target: targetNodeId
      });
    } else {
      switch (item.data?.type) {
        case 'datasource':
          nodes.push({
            id: item.data.nodeId,
            name: item.data.nodeName,
            tablePath: item.data.tablePath,
            op: 'datasource',
            data: {
              input_source: item.data.inputSource,
              input_table: item.data.dataTableId
            }
          });
          break;
        case 'outputsource':
          nodes.push({
            id: item.data.nodeId,
            name: item.data.nodeName,
            op: 'outputsource',
            data: {
              inputs: generateInputs(graph, item.id),
              output_source: item.data.outputSource
            }
          });
          break;
        default:
          nodes.push({
            id: item.data.nodeId,
            name: item.data.nodeName,
            op: item.data.label,
            data: {
              inputs: generateInputs(graph, item.id),
              input_number: item.data.inputNumber,
              output: item.data.outputData,
              script: item.data.scriptText,
              param: item.data.paramText,
              package: item.data.packageData
            }
          });
          break;
      }
    }
  });
  return { edges, nodes };
};

// 获取所有脚本Edge和Nodes
const getScriptEdgesAndNodes = (graph: any) => {
  const dagData = graph.toJSON();
  const script_nodes: any = [];
  let script_edges: any = [];
  dagData.cells.forEach((item: any) => {
    if (item?.shape === 'dag-edge') {
      const sourceNodeId = graph.getCellById(item.source.cell).data.nodeId;
      const targetNodeId = graph.getCellById(item.target.cell).data.nodeId;
      script_edges.push([sourceNodeId, targetNodeId]);
    } else {
      switch (item.data?.type) {
        case 'datasource':
          script_nodes.push({
            id: item.data.nodeId,
            name: item.data.nodeName,
            op: 'sql',
            script: datasourceToSql(item.data)
          });
          break;
        case 'outputsource':
          script_edges = script_edges.filter(
            (val: any) => !val.includes(item.data.nodeId)
          );
          // script_nodes.push({
          //   id: item.data.nodeId,
          //   name: item.data.nodeName,
          //   op: 'pyspark',
          //   inputs: generateInputs(graph, item.id),
          //   script: outputsourceToSpark()
          // });
          break;
        default:
          script_nodes.push({
            id: item.data.nodeId,
            name: item.data.nodeName,
            op: item.data.label,
            inputs: generateInputs(graph, item.id),
            script:
              item.data.label === 'sql'
                ? item.data.scriptText.replace(/\r?\n|\r/g, '')
                : item.data.scriptText
          });
          break;
      }
    }
  });
  return { script_nodes, script_edges };
};

const datasourceToSql = (nodeData: any) => {
  const { inputSource, dataTableName } = nodeData;
  console.log(nodeData, dataTableName);
  if (inputSource?.length > 0 && dataTableName) {
    const params = inputSource
      .reduce((pre: any, item: any) => {
        return item.dataSelect ? pre.concat(item.dataField) : pre;
      }, [])
      .join(', ');
    const table_params = dataTableName.split('.');
    return params
      ? `select ${params} from \`${table_params[0]}\`.\`${table_params[1]}\``
      : '';
  }
  return '';
};

// const outputsourceToSpark = () => {
//   return `
//   def main_func (input0, spark,sc):
//       input0.write.mode("overwrite").saveAsTable('{{tabelName}}')
//   `;
// };

/* const datasourceFields = (nodeData: any) => {
  const { inputSource, dataTableName } = nodeData
  if (inputSource?.length > 0 && dataTableName) {
    return inputSource.filter((item: any) => item.dataSelect)
  }
  return []
} */

const generateInputs = (graph: any, id: any) => {
  const inputsResult: any = {};
  const edges = graph.getIncomingEdges(id);
  if (edges?.length > 0) {
    edges.forEach((item: any, index: any) => {
      const sourceNode = item.getSourceNode();
      const sourcePortID = item.getSourcePortId();
      const sourcePorts = sourceNode.getPortsByGroup('bottom');
      const sourceId = sourceNode.data.nodeId;
      const portNumber =
        sourceNode.data?.type === 'datasource'
          ? 0
          : sourcePorts.indexOf(
              sourcePorts.find((item: any) => item.id === sourcePortID)
            );
      inputsResult[`input${index}`] = [sourceId, portNumber];
    });
  }
  return inputsResult;
};

// 标记跳过节点
export const signNodesSkip = (graph: any, node: any, action: any) => {
  const skipNodes = getSkipNodes(graph, node, action) as any;
  const { script_nodes, script_edges } = getScriptEdgesAndNodes(graph);
  script_nodes.forEach((item: any) => {
    item.skip = skipNodes[item.id];
  });
  return { script_nodes, script_edges };
};

// 获取跳过节点
const getSkipNodes = (graph: any, node: any, action: any) => {
  // 结果 {nodeId, skip}
  const result = {} as any;
  // 设置默认true
  const { nodes } = getEdgesAndNodes(graph);
  // 获取标记了前置后置的节点
  const preEndNodes = getNodesSourceAndTarget(graph);
  nodes.forEach((item: any) => {
    result[item.id] = true;
  });
  switch (action) {
    // 执行到此处
    case 'handle_run':
      result[node.data.nodeId] = false;
      break;
    // 执行到此处
    case 'handle_run_end':
      traverseNodes(result, node.data.nodeId, preEndNodes, 'sourceNodes');
      break;
    // 从此处开始执行
    case 'handle_run_begin':
      traverseNodes(result, node.data.nodeId, preEndNodes, 'targetNodes');
      // result[node.data.nodeId] = true;
      break;
    case 'run_all':
      nodes.forEach((item: any) => {
        result[item.id] = false;
      });
      break;
    default:
      break;
  }

  return result;
};

// 遍历前后继
const traverseNodes = (
  result: any,
  nodeId: any,
  preEndNodes: any,
  nodes: any
) => {
  result[nodeId] = false;
  const sourceNodes = preEndNodes[nodeId][nodes];
  sourceNodes.forEach((item: any) => {
    traverseNodes(result, item, preEndNodes, nodes);
  });
};

// 获取前置后置
export const getNodesSourceAndTarget = (graph: any) => {
  const { nodes, edges } = getEdgesAndNodes(graph);
  const resultNodes = {} as any;
  nodes.forEach((item: any) => {
    resultNodes[item.id] = {} as any;
    resultNodes[item.id]['sourceNodes'] = [];
    resultNodes[item.id]['targetNodes'] = [];
  });
  edges.forEach((item: any) => {
    const sourceNodeId = item.source;
    const targetNodeId = item.target;
    resultNodes[sourceNodeId]['targetNodes'].push(targetNodeId);
    resultNodes[targetNodeId]['sourceNodes'].push(sourceNodeId);
  });
  return resultNodes;
};

//初始化模板
export const getEditorTemplate = (params: any) => {
  const { inputNumber, outputNumber, type } = params;
  console.log('inputNumber:', inputNumber);
  const pyTemplate = `def main_func(${Array.from(
    { length: inputNumber },
    (_, i) => 'input' + i
  ).join(', ')}, spark, sc):
${Array.from(
  { length: inputNumber },
  (_, i) => '    input' + i + '.show()'
).join('\n')}
${Array.from(
  { length: inputNumber },
  (_, i) => '    r' + i + ' = input' + i
).join('\n')}
    return [${Array.from({ length: outputNumber }, (_, i) => 'r' + i).join(
      ', '
    )}]
`;
  const sqlTemplate = `${Array.from(
    { length: inputNumber },
    (_, i) => 'select * from input' + i
  ).join('\n')}`;
  return type === 'sql' ? sqlTemplate : pyTemplate;
};
