"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = useInit;

var _react = require("react");

var _util = require("@antv/util");

var _createNode = _interopRequireDefault(require("../util/createNode"));

var _util2 = require("../util");

var _excluded = ["data", "value", "percent"],
    _excluded2 = ["data", "value", "percent"];

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

function useInit(ChartClass, config) {
  var chart = (0, _react.useRef)();
  var chartOptions = (0, _react.useRef)();
  var container = (0, _react.useRef)(null);
  var onReady = config.onReady,
      onEvent = config.onEvent;
  /**
     * Get data base64
     * @param {string} type A DOMString indicating the image format. The default format type is image/png.
     * @param {number} encoderOptions A Number between 0 and 1 indicating the image quality
     */

  var toDataURL = function toDataURL() {
    var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "image/png";
    var encoderOptions = arguments.length > 1 ? arguments[1] : undefined;
    return chart.current && chart.current.chart.canvas.cfg.el.toDataURL(type, encoderOptions);
  };
  /**
     * Download Iamge
     * @param {string} name A name of image
     * @param {string} type A DOMString indicating the image format. The default format type is image/png.
     * @param {number} encoderOptions A Number between 0 and 1 indicating the image quality
     */


  var downloadImage = function downloadImage() {
    var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "download";
    var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "image/png";
    var encoderOptions = arguments.length > 2 ? arguments[2] : undefined;
    var imageName = name;

    if (name.indexOf(".") === -1) {
      imageName = "".concat(name, ".").concat(type.split("/")[1]);
    }

    var base64 = chart.current && chart.current.chart.canvas.cfg.el.toDataURL(type, encoderOptions);
    var a = document.createElement("a");
    a.href = base64;
    a.download = imageName;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    a = null;
    return imageName;
  };

  var reactDomToString = function reactDomToString(source, path, type) {
    var statisticCustomHtml = (0, _util2.hasPath)(source, path);
    (0, _util2.setPath)(source, path, function () {
      var statisticDom = (0, _util2.isType)(statisticCustomHtml, "Function") ? statisticCustomHtml.apply(void 0, arguments) : statisticCustomHtml;

      if ((0, _util2.isType)(statisticDom, "String") || (0, _util2.isType)(statisticDom, "Number") || (0, _util2.isType)(statisticDom, "HTMLDivElement")) {
        return statisticDom;
      }

      return (0, _createNode["default"])(statisticDom, type);
    });
  };

  var processConfig = function processConfig() {
    // statistic
    if ((0, _util2.hasPath)(config, ["statistic", "content", "customHtml"])) {
      reactDomToString(config, ["statistic", "content", "customHtml"]);
    }

    if ((0, _util2.hasPath)(config, ["statistic", "title", "customHtml"])) {
      reactDomToString(config, ["statistic", "title", "customHtml"]);
    } // tooltip


    if (_typeof(config.tooltip) === "object") {
      if ((0, _util2.hasPath)(config, ["tooltip", "container"])) {
        reactDomToString(config, ["tooltip", "container"], "tooltip");
      }

      if ((0, _util2.hasPath)(config, ["tooltip", "customContent"])) {
        reactDomToString(config, ["tooltip", "customContent"], "tooltip");
      }
    }
  };

  (0, _react.useEffect)(function () {
    if (chart.current && !(0, _util.isEqual)(chartOptions.current, config)) {
      var changeData = false;

      if (chartOptions.current) {
        // 从 options 里面取出 data 、value 、 percent 进行比对，判断是否仅数值发生改变
        var _chartOptions$current = chartOptions.current,
            currentData = _chartOptions$current.data,
            currentValue = _chartOptions$current.value,
            currentPercent = _chartOptions$current.percent,
            currentConfig = _objectWithoutProperties(_chartOptions$current, _excluded);

        var inputData = config.data,
            inputValue = config.value,
            inputPercent = config.percent,
            inputConfig = _objectWithoutProperties(config, _excluded2);

        changeData = (0, _util.isEqual)(currentConfig, inputConfig);
      }

      if (changeData) {
        var changeType = "data";
        var typeMaps = ["percent"]; // 特殊类型的图表 data 字段，例如 RingProgress

        var currentKeys = Object.keys(config);
        typeMaps.forEach(function (type) {
          if (currentKeys.includes(type)) {
            changeType = type;
          }
        });
        chart.current.changeData(config && config[changeType] || []);
      } else {
        processConfig();
        chart.current.update(config);
      }

      chartOptions.current = (0, _util2.deepClone)(config);
    }
  }, [config]);
  (0, _react.useEffect)(function () {
    if (!container.current) {
      return function () {
        return null;
      };
    }

    processConfig();
    var chartInstance = new ChartClass(container.current, _objectSpread({}, config));

    ChartClass.prototype.toDataURL = function (type, encoderOptions) {
      return toDataURL(type, encoderOptions);
    };

    ChartClass.prototype.downloadImage = function (name, type, encoderOptions) {
      return downloadImage(name, type, encoderOptions);
    };

    chartInstance.render();

    if (!chartOptions.current) {
      chartOptions.current = (0, _util2.deepClone)(config);
    }

    chart.current = (0, _util2.clone)(chartInstance);

    if (onReady) {
      onReady(chartInstance);
    }

    var handler = function handler(event) {
      if (onEvent) {
        onEvent(chartInstance, event);
      }
    };

    chartInstance.on("*", handler); // 组件销毁时销毁图表

    return function () {
      if (chart.current) {
        chart.current.destroy();
        chart.current.off("*", handler);
        chart.current = undefined;
      }
    };
  }, []);
  return {
    chart: chart,
    container: container
  };
}