/**
 * @fileOverview 度量的控制器
 * @author dxq613@gmail.com
 */
var Scale = require('@antv/scale/lib');

var Util = require('../../util');

var dateRegex = /^(?:(?!0000)[0-9]{4}([-/.]+)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]+)0?2\2(?:29))(\s+([01]|([01][0-9]|2[0-3])):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9]))?$/;
var TYPES = {
  LINEAR: 'linear',
  CAT: 'cat',
  TIME: 'time'
};

var ScaleController = /*#__PURE__*/function () {
  function ScaleController(cfg) {
    // defs 列定义
    this.defs = {};
    this.viewTheme = {
      scales: {}
    }; // filtered fields

    this.filters = {};
    Util.assign(this, cfg);
  }

  var _proto = ScaleController.prototype;

  _proto._getDef = function _getDef(field) {
    var defs = this.defs;
    var viewTheme = this.viewTheme;
    var def = null;

    if (viewTheme.scales[field] || defs[field]) {
      def = Util.mix({}, viewTheme.scales[field]); // 处理覆盖属性的问题

      Util.each(defs[field], function (v, k) {
        if (Util.isNil(v)) {
          delete def[k];
        } else {
          def[k] = v;
        }
      });

      if (this.filters[field]) {
        delete def.min;
        delete def.max;
      }
    }

    return def;
  };

  _proto._getDefaultType = function _getDefaultType(field, data) {
    var type = TYPES.LINEAR;
    var value = Util.Array.firstValue(data, field);

    if (Util.isArray(value)) {
      value = value[0];
    }

    if (dateRegex.test(value)) {
      type = TYPES.TIME;
    } else if (Util.isString(value)) {
      type = TYPES.CAT;
    }

    return type;
  };

  _proto._getScaleCfg = function _getScaleCfg(type, field, data) {
    var cfg = {
      field: field
    };
    var values = Util.Array.values(data, field);
    cfg.values = values;

    if (!Scale.isCategory(type) && type !== 'time') {
      var range = Util.Array.getRange(values);
      cfg.min = range.min;
      cfg.max = range.max;
      cfg.nice = true;
    }

    if (type === 'time') {
      cfg.nice = false;
    }

    return cfg;
  };

  _proto.createScale = function createScale(field, data) {
    var self = this;

    var def = self._getDef(field);

    var scale;
    var validData = data || [];
    var firstValue = Util.Array.firstValue(validData, field);

    if (Util.isNumber(field) || Util.isNil(firstValue) && !def) {
      scale = Scale.identity({
        value: field,
        field: field.toString(),
        values: [field]
      });
    } else {
      // 如果已经定义过这个度量
      var type;

      if (def) {
        type = def.type;
      }

      type = type || self._getDefaultType(field, validData);

      var cfg = self._getScaleCfg(type, field, validData);

      if (def) {
        Util.mix(cfg, def);
      }

      scale = Scale[type](cfg);
    }

    return scale;
  };

  return ScaleController;
}();

module.exports = ScaleController;