'use strict';

var types = require('../../util/types.js');
var log = require('../../util/log.js');
var util = require('../../../../../../zrender@6.0.0/node_modules/zrender/lib/core/util.js');
var model = require('../../util/model.js');
var dataValueHelper = require('../../data/helper/dataValueHelper.js');

var sampleLog = '';
if (process.env.NODE_ENV !== 'production') {
  sampleLog = ['Valid config is like:', '{ dimension: "age", order: "asc" }', 'or [{ dimension: "age", order: "asc"], { dimension: "date", order: "desc" }]'].join(' ');
}
var sortTransform = {
  type: 'echarts:sort',
  transform: function (params) {
    var upstream = params.upstream;
    var config = params.config;
    var errMsg = '';
    // Normalize
    // const orderExprList: OrderExpression[] = isArray(config[0])
    //     ? config as OrderExpression[]
    //     : [config as OrderExpression];
    var orderExprList = model.normalizeToArray(config);
    if (!orderExprList.length) {
      if (process.env.NODE_ENV !== 'production') {
        errMsg = 'Empty `config` in sort transform.';
      }
      log.throwError(errMsg);
    }
    var orderDefList = [];
    util.each(orderExprList, function (orderExpr) {
      var dimLoose = orderExpr.dimension;
      var order = orderExpr.order;
      var parserName = orderExpr.parser;
      var incomparable = orderExpr.incomparable;
      if (dimLoose == null) {
        if (process.env.NODE_ENV !== 'production') {
          errMsg = 'Sort transform config must has "dimension" specified.' + sampleLog;
        }
        log.throwError(errMsg);
      }
      if (order !== 'asc' && order !== 'desc') {
        if (process.env.NODE_ENV !== 'production') {
          errMsg = 'Sort transform config must has "order" specified.' + sampleLog;
        }
        log.throwError(errMsg);
      }
      if (incomparable && incomparable !== 'min' && incomparable !== 'max') {
        var errMsg_1 = '';
        if (process.env.NODE_ENV !== 'production') {
          errMsg_1 = 'incomparable must be "min" or "max" rather than "' + incomparable + '".';
        }
        log.throwError(errMsg_1);
      }
      if (order !== 'asc' && order !== 'desc') {
        var errMsg_2 = '';
        if (process.env.NODE_ENV !== 'production') {
          errMsg_2 = 'order must be "asc" or "desc" rather than "' + order + '".';
        }
        log.throwError(errMsg_2);
      }
      var dimInfo = upstream.getDimensionInfo(dimLoose);
      if (!dimInfo) {
        if (process.env.NODE_ENV !== 'production') {
          errMsg = log.makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal config:', orderExpr, '.\n');
        }
        log.throwError(errMsg);
      }
      var parser = parserName ? dataValueHelper.getRawValueParser(parserName) : null;
      if (parserName && !parser) {
        if (process.env.NODE_ENV !== 'production') {
          errMsg = log.makePrintable('Invalid parser name ' + parserName + '.\n', 'Illegal config:', orderExpr, '.\n');
        }
        log.throwError(errMsg);
      }
      orderDefList.push({
        dimIdx: dimInfo.index,
        parser: parser,
        comparator: new dataValueHelper.SortOrderComparator(order, incomparable)
      });
    });
    // TODO: support it?
    var sourceFormat = upstream.sourceFormat;
    if (sourceFormat !== types.SOURCE_FORMAT_ARRAY_ROWS && sourceFormat !== types.SOURCE_FORMAT_OBJECT_ROWS) {
      if (process.env.NODE_ENV !== 'production') {
        errMsg = 'sourceFormat "' + sourceFormat + '" is not supported yet';
      }
      log.throwError(errMsg);
    }
    // Other upstream format are all array.
    var resultData = [];
    for (var i = 0, len = upstream.count(); i < len; i++) {
      resultData.push(upstream.getRawDataItem(i));
    }
    resultData.sort(function (item0, item1) {
      for (var i = 0; i < orderDefList.length; i++) {
        var orderDef = orderDefList[i];
        var val0 = upstream.retrieveValueFromItem(item0, orderDef.dimIdx);
        var val1 = upstream.retrieveValueFromItem(item1, orderDef.dimIdx);
        if (orderDef.parser) {
          val0 = orderDef.parser(val0);
          val1 = orderDef.parser(val1);
        }
        var result = orderDef.comparator.evaluate(val0, val1);
        if (result !== 0) {
          return result;
        }
      }
      return 0;
    });
    return {
      data: resultData
    };
  }
};

exports.sortTransform = sortTransform;
