import { retrieve, indexOf } from '../../../../../../zrender@6.0.0/node_modules/zrender/lib/core/util.mjs';
import SeriesData from '../../data/SeriesData.mjs';
import Graph from '../../data/Graph.mjs';
import linkSeriesData from '../../data/helper/linkSeriesData.mjs';
import prepareSeriesDataSchema from '../../data/helper/createDimensions.mjs';
import CoordinateSystemManager from '../../core/CoordinateSystem.mjs';
import createSeriesData from './createSeriesData.mjs';
import { convertOptionIdName } from '../../util/model.mjs';

function createGraphFromNodeEdge(nodes, edges, seriesModel, directed, beforeLink) {
  // ??? TODO
  // support dataset?
  var graph = new Graph(directed);
  for (var i = 0; i < nodes.length; i++) {
    graph.addNode(retrieve(
    // Id, name, dataIndex
    nodes[i].id, nodes[i].name, i), i);
  }
  var linkNameList = [];
  var validEdges = [];
  var linkCount = 0;
  for (var i = 0; i < edges.length; i++) {
    var link = edges[i];
    var source = link.source;
    var target = link.target;
    // addEdge may fail when source or target not exists
    if (graph.addEdge(source, target, linkCount)) {
      validEdges.push(link);
      linkNameList.push(retrieve(convertOptionIdName(link.id, null), source + ' > ' + target));
      linkCount++;
    }
  }
  var coordSys = seriesModel.get('coordinateSystem');
  var nodeData;
  if (coordSys === 'cartesian2d' || coordSys === 'polar' || coordSys === 'matrix') {
    nodeData = createSeriesData(nodes, seriesModel);
  } else {
    var coordSysCtor = CoordinateSystemManager.get(coordSys);
    var coordDimensions = coordSysCtor ? coordSysCtor.dimensions || [] : [];
    // FIXME: Some geo do not need `value` dimenson, whereas `calendar` needs
    // `value` dimension, but graph need `value` dimension. It's better to
    // uniform this behavior.
    if (indexOf(coordDimensions, 'value') < 0) {
      coordDimensions.concat(['value']);
    }
    var dimensions = prepareSeriesDataSchema(nodes, {
      coordDimensions: coordDimensions,
      encodeDefine: seriesModel.getEncode()
    }).dimensions;
    nodeData = new SeriesData(dimensions, seriesModel);
    nodeData.initData(nodes);
  }
  var edgeData = new SeriesData(['value'], seriesModel);
  edgeData.initData(validEdges, linkNameList);
  beforeLink && beforeLink(nodeData, edgeData);
  linkSeriesData({
    mainData: nodeData,
    struct: graph,
    structAttr: 'graph',
    datas: {
      node: nodeData,
      edge: edgeData
    },
    datasAttr: {
      node: 'data',
      edge: 'edgeData'
    }
  });
  // Update dataIndex of nodes and edges because invalid edge may be removed
  graph.update();
  return graph;
}

export { createGraphFromNodeEdge as default };
