import "core-js/modules/es6.object.keys";
import "core-js/modules/es6.object.assign";
import "core-js/modules/es7.symbol.async-iterator";
import "core-js/modules/es6.symbol";
import "core-js/modules/es6.reflect.get";
import "core-js/modules/es6.object.set-prototype-of";
import "core-js/modules/es6.array.iterator";
import "core-js/modules/web.dom.iterable";
import "core-js/modules/es6.number.constructor";

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }

function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

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; }

import React from 'react';
import PropTypes from 'prop-types';
import { AbstractSeries, Crosshair } from 'react-vis';
import { SCALE } from '../utils/chart_utils';
/**
 * The Crosshair used by the XYChart as main tooltip mechanism along X axis (vertical).
 */

export var EuiCrosshairX =
/*#__PURE__*/
function (_AbstractSeries) {
  _inherits(EuiCrosshairX, _AbstractSeries);

  function EuiCrosshairX() {
    var _getPrototypeOf2;

    var _this;

    _classCallCheck(this, EuiCrosshairX);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(EuiCrosshairX)).call.apply(_getPrototypeOf2, [this].concat(args)));

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", {
      values: []
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_formatXValue", function (x) {
      var xType = _this.props.xType;

      if (xType === SCALE.TIME || xType === SCALE.TIME_UTC) {
        return new Date(x).toISOString(); // TODO add a props for time formatting
      } else {
        return x;
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_titleFormat", function () {
      var dataPoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

      if (dataPoints.length > 0) {
        var _dataPoints = _slicedToArray(dataPoints, 1),
            firstDataPoint = _dataPoints[0];

        var originalValues = firstDataPoint.originalValues;
        var value = typeof originalValues.x0 === 'number' ? "".concat(_this._formatXValue(originalValues.x0), " to ").concat(_this._formatXValue(originalValues.x)) : _this._formatXValue(originalValues.x);
        return {
          title: 'X Value',
          value: value
        };
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_itemsFormat", function (dataPoints) {
      var seriesNames = _this.props.seriesNames;
      return dataPoints.map(function (d) {
        return {
          title: seriesNames[d.seriesIndex],
          value: d.y
        };
      });
    });

    return _this;
  }

  _createClass(EuiCrosshairX, [{
    key: "onParentMouseMove",
    value: function onParentMouseMove(event) {
      this._handleNearestX(event);
    }
  }, {
    key: "onParentMouseLeave",
    value: function onParentMouseLeave() {
      if (this.props.onCrosshairUpdate) {
        this.props.onCrosshairUpdate(null);
      }

      this.setState({
        values: []
      });
    }
  }, {
    key: "_handleNearestX",
    value: function _handleNearestX(event) {
      var cleanedDataSeries = this.props._allData.filter(function (dataSeries) {
        return dataSeries;
      });

      if (cleanedDataSeries.length === 0) {
        return;
      }

      var containerCoordiante = _get(_getPrototypeOf(EuiCrosshairX.prototype), "_getXYCoordinateInContainer", this).call(this, event);

      this._findNearestXData(cleanedDataSeries, containerCoordiante.x);
    }
    /**
     * _findNearestXData - Find the nearest set of data in all existing series.
     *
     * @param  {type} dataSeries an array of dataseries
     * @param  {type} mouseXContainerCoords the x coordinate of the mouse on the chart container
     * @protected
     */

  }, {
    key: "_findNearestXData",
    value: function _findNearestXData(dataSeries, mouseXContainerCoords) {
      var xScaleFn = _get(_getPrototypeOf(EuiCrosshairX.prototype), "_getAttributeFunctor", this).call(this, 'x'); // keeping a global min distance to filter only elements with the same distance


      var globalMinDistance = Number.POSITIVE_INFINITY;
      var nearestXData = dataSeries.map(function (data, seriesIndex) {
        var minDistance = Number.POSITIVE_INFINITY;
        var value = null; // TODO to increase the performance, it's better to use a search algorithm like bisect
        // starting from the assumption that we will always have the same length for
        // for each series and we can assume that the scale x index can reflect more or less
        // the position of the mouse inside the array.

        data.forEach(function (item) {
          var itemXCoords;
          var xCoord = xScaleFn(item); // check the right item coordinate if we use x0 and x value (e.g. on histograms)

          if (typeof item.x0 === 'number') {
            // we need to compute the scaled x0 using the xScale attribute functor
            // we don't have access of the x0 attribute functor
            var x0Coord = xScaleFn({
              x: item.x0
            });
            itemXCoords = (xCoord - x0Coord) / 2 + x0Coord;
          } else {
            itemXCoords = xCoord;
          }

          var newDistance = Math.abs(mouseXContainerCoords - itemXCoords);

          if (newDistance < minDistance) {
            minDistance = newDistance;
            value = item;
          }

          globalMinDistance = Math.min(globalMinDistance, minDistance);
        });

        if (!value) {
          return;
        }

        return {
          minDistance: minDistance,
          value: value,
          seriesIndex: seriesIndex
        };
      }).filter(function (d) {
        return d;
      }); // filter and map nearest X data per dataseries to get only the nearet onces

      var values = nearestXData.filter(function (value) {
        return value.minDistance === globalMinDistance;
      }).map(function (value) {
        // check if we are on histograms and we need to show the right x and y values
        var d = value.value;
        var x = typeof d.x0 === 'number' ? (d.x - d.x0) / 2 + d.x0 : d.x;
        var y = typeof d.y0 === 'number' ? d.y - d.y0 : d.y;
        return {
          x: x,
          y: y,
          originalValues: d,
          seriesIndex: value.seriesIndex
        };
      });
      var onCrosshairUpdate = this.props.onCrosshairUpdate;

      if (onCrosshairUpdate) {
        onCrosshairUpdate(values[0].x);
      }

      this.setState(function () {
        return {
          values: values
        };
      });
    }
  }, {
    key: "render",
    value: function render() {
      var values = this.state.values;
      return React.createElement(Crosshair, _extends({
        values: values,
        style: {
          line: {
            background: 'rgb(218, 218, 218)'
          }
        },
        itemsFormat: this._itemsFormat,
        titleFormat: this._titleFormat
      }, this.props));
    }
  }], [{
    key: "getDerivedStateFromProps",
    value: function getDerivedStateFromProps(props) {
      var crosshairValue = props.crosshairValue,
          _allData = props._allData;

      if (crosshairValue !== undefined) {
        return {
          values: EuiCrosshairX._computeDataFromXValue(_allData, crosshairValue)
        };
      }

      return null;
    }
  }, {
    key: "_computeDataFromXValue",
    value: function _computeDataFromXValue(dataSeries, crosshairValue) {
      var filteredAndFlattenDataByX = dataSeries.filter(function (series) {
        return series;
      }) // get only cleaned data series
      .map(function (series, seriesIndex) {
        return series.filter(function (dataPoint) {
          return dataPoint.x === crosshairValue;
        }).map(function (dataPoint) {
          return _objectSpread({}, dataPoint, {
            originalValues: _objectSpread({}, dataPoint),
            seriesIndex: seriesIndex
          });
        });
      }).reduce(function (acc, val) {
        return acc.concat(val);
      }, []);
      return filteredAndFlattenDataByX;
    }
  }, {
    key: "requiresSVG",
    get: function get() {
      return false;
    }
  }, {
    key: "isCanvas",
    get: function get() {
      return false;
    }
  }]);

  return EuiCrosshairX;
}(AbstractSeries);
EuiCrosshairX.displayName = 'EuiCrosshairX';
EuiCrosshairX.propTypes = {
  /**
   * The crosshair value used to display this crosshair (doesn't depend on mouse position)
   */
  crosshairValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

  /**
   * The ordered array of series names
   */
  seriesNames: PropTypes.arrayOf(PropTypes.string).isRequired
};
EuiCrosshairX.defaultProps = {};
EuiCrosshairX.__docgenInfo = {
  "description": "The Crosshair used by the XYChart as main tooltip mechanism along X axis (vertical).",
  "methods": [{
    "name": "requiresSVG",
    "docblock": null,
    "modifiers": ["static", "get"],
    "params": [],
    "returns": null
  }, {
    "name": "isCanvas",
    "docblock": null,
    "modifiers": ["static", "get"],
    "params": [],
    "returns": null
  }, {
    "name": "getDerivedStateFromProps",
    "docblock": null,
    "modifiers": ["static"],
    "params": [{
      "name": "props",
      "type": null
    }],
    "returns": null
  }, {
    "name": "_computeDataFromXValue",
    "docblock": null,
    "modifiers": ["static"],
    "params": [{
      "name": "dataSeries",
      "type": null
    }, {
      "name": "crosshairValue",
      "type": null
    }],
    "returns": null
  }, {
    "name": "onParentMouseMove",
    "docblock": null,
    "modifiers": [],
    "params": [{
      "name": "event",
      "type": null
    }],
    "returns": null
  }, {
    "name": "onParentMouseLeave",
    "docblock": null,
    "modifiers": [],
    "params": [],
    "returns": null
  }, {
    "name": "_formatXValue",
    "docblock": null,
    "modifiers": [],
    "params": [{
      "name": "x",
      "type": null
    }],
    "returns": null
  }, {
    "name": "_titleFormat",
    "docblock": null,
    "modifiers": [],
    "params": [{
      "name": "dataPoints",
      "type": null
    }],
    "returns": null
  }, {
    "name": "_itemsFormat",
    "docblock": null,
    "modifiers": [],
    "params": [{
      "name": "dataPoints",
      "type": null
    }],
    "returns": null
  }, {
    "name": "_handleNearestX",
    "docblock": null,
    "modifiers": [],
    "params": [{
      "name": "event",
      "type": null
    }],
    "returns": null
  }, {
    "name": "_findNearestXData",
    "docblock": "_findNearestXData - Find the nearest set of data in all existing series.\n\n@param  {type} dataSeries an array of dataseries\n@param  {type} mouseXContainerCoords the x coordinate of the mouse on the chart container\n@protected",
    "modifiers": [],
    "params": [{
      "name": "dataSeries",
      "description": "an array of dataseries",
      "type": {
        "name": "type"
      },
      "optional": false
    }, {
      "name": "mouseXContainerCoords",
      "description": "the x coordinate of the mouse on the chart container",
      "type": {
        "name": "type"
      },
      "optional": false
    }],
    "returns": null,
    "description": "_findNearestXData - Find the nearest set of data in all existing series."
  }],
  "displayName": "EuiCrosshairX",
  "props": {
    "crosshairValue": {
      "type": {
        "name": "union",
        "value": [{
          "name": "string"
        }, {
          "name": "number"
        }]
      },
      "required": false,
      "description": "The crosshair value used to display this crosshair (doesn't depend on mouse position)"
    },
    "seriesNames": {
      "type": {
        "name": "arrayOf",
        "value": {
          "name": "string"
        }
      },
      "required": true,
      "description": "The ordered array of series names"
    }
  }
};