"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.computeChartMargins = void 0;
exports.getAxisGroupForReferenceLine = getAxisGroupForReferenceLine;
exports.getBaseIconPlacement = getBaseIconPlacement;
exports.getNextValuesForReferenceLines = exports.getLineAnnotationProps = exports.getHorizontalRect = exports.getBottomRect = void 0;
exports.getReferenceLinesFormattersMap = getReferenceLinesFormattersMap;
exports.getSharedStyle = void 0;
var _react = _interopRequireDefault(require("react"));
var _charts = require("@elastic/charts");
var _uiTheme = require("@kbn/ui-theme");
var _lodash = require("lodash");
var _constants = require("../../../common/constants");
var _helpers = require("../../helpers");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

// if there's just one axis, put it on the other one
// otherwise use the same axis
// this function assume the chart is vertical
function getBaseIconPlacement(iconPosition, axesMap, position) {
  if (iconPosition === 'auto') {
    if (position === _charts.Position.Bottom) {
      return _charts.Position.Top;
    }
    if (axesMap) {
      if (position === _charts.Position.Left) {
        return axesMap.right ? _charts.Position.Left : _charts.Position.Right;
      }
      return axesMap.left ? _charts.Position.Right : _charts.Position.Left;
    }
  }
  if (iconPosition === 'left') {
    return _charts.Position.Left;
  }
  if (iconPosition === 'right') {
    return _charts.Position.Right;
  }
  if (iconPosition === 'below') {
    return _charts.Position.Bottom;
  }
  return _charts.Position.Top;
}
const getSharedStyle = config => ({
  strokeWidth: config.lineWidth || 1,
  stroke: config.color || _uiTheme.euiLightVars.euiColorDarkShade,
  dash: config.lineStyle === 'dashed' ? [(config.lineWidth || 1) * 3, config.lineWidth || 1] : config.lineStyle === 'dotted' ? [config.lineWidth || 1, config.lineWidth || 1] : config.lineStyle === 'dot-dashed' ? [(config.lineWidth || 1) * 5, config.lineWidth || 1, config.lineWidth || 1, config.lineWidth || 1] : undefined
});
exports.getSharedStyle = getSharedStyle;
const getLineAnnotationProps = (config, label, axesMap, isHorizontal, isTextOnlyMarker) => {
  var _config$axisGroup$pos, _config$axisGroup, _config$axisGroup2;
  // get the position for vertical chart
  const markerPositionVertical = getBaseIconPlacement(config.iconPosition, axesMap, (0, _helpers.getOriginalAxisPosition)((_config$axisGroup$pos = (_config$axisGroup = config.axisGroup) === null || _config$axisGroup === void 0 ? void 0 : _config$axisGroup.position) !== null && _config$axisGroup$pos !== void 0 ? _config$axisGroup$pos : _charts.Position.Bottom, isHorizontal));
  const markerPosition = isHorizontal ? (0, _helpers.mapVerticalToHorizontalPlacement)(markerPositionVertical) : markerPositionVertical;
  const isMarkerLabelHorizontal = markerPosition === _charts.Position.Bottom || markerPosition === _charts.Position.Top;
  return {
    groupId: ((_config$axisGroup2 = config.axisGroup) === null || _config$axisGroup2 === void 0 ? void 0 : _config$axisGroup2.groupId) || 'bottom',
    marker: /*#__PURE__*/_react.default.createElement(_helpers.Marker, {
      config: config,
      label: label,
      isHorizontal: isMarkerLabelHorizontal,
      hasReducedPadding: isTextOnlyMarker
    }),
    markerBody: /*#__PURE__*/_react.default.createElement(_helpers.MarkerBody, {
      label: config.textVisibility && !isTextOnlyMarker ? label : undefined,
      isHorizontal: isMarkerLabelHorizontal
    }),
    // rotate the position if required
    markerPosition
  };
};
exports.getLineAnnotationProps = getLineAnnotationProps;
const getBottomRect = (headerLabel, isFillAbove, formatter, currentValue, nextValue) => ({
  coordinates: {
    x0: isFillAbove ? currentValue : nextValue,
    y0: undefined,
    x1: isFillAbove ? nextValue : currentValue,
    y1: undefined
  },
  header: headerLabel,
  details: (formatter === null || formatter === void 0 ? void 0 : formatter.convert(currentValue)) || (currentValue === null || currentValue === void 0 ? void 0 : currentValue.toString())
});
exports.getBottomRect = getBottomRect;
const getHorizontalRect = (headerLabel, isFillAbove, formatter, currentValue, nextValue) => ({
  coordinates: {
    x0: undefined,
    y0: isFillAbove ? currentValue : nextValue,
    x1: undefined,
    y1: isFillAbove ? nextValue : currentValue
  },
  header: headerLabel,
  details: (formatter === null || formatter === void 0 ? void 0 : formatter.convert(currentValue)) || (currentValue === null || currentValue === void 0 ? void 0 : currentValue.toString())
});
exports.getHorizontalRect = getHorizontalRect;
const sortReferenceLinesByGroup = (referenceLines, group) => {
  if (group === _constants.FillStyles.ABOVE || group === _constants.FillStyles.BELOW) {
    const order = group === _constants.FillStyles.ABOVE ? 'asc' : 'desc';
    return (0, _lodash.orderBy)(referenceLines, ({
      decorations: [{
        value
      }]
    }) => value, [order]);
  }
  return referenceLines;
};
const getNextValuesForReferenceLines = referenceLines => {
  const grouppedReferenceLines = (0, _lodash.groupBy)(referenceLines, ({
    decorations: [decorationConfig]
  }) => decorationConfig.fill);
  const groups = Object.keys(grouppedReferenceLines);
  return groups.reduce((nextValueByDirection, group) => {
    const sordedReferenceLines = sortReferenceLinesByGroup(grouppedReferenceLines[group], group);
    const nv = sordedReferenceLines.reduce((nextValues, referenceLine, index, lines) => {
      let nextValue;
      if (index < lines.length - 1) {
        const [decorationConfig] = lines[index + 1].decorations;
        nextValue = decorationConfig.value;
      }
      return {
        ...nextValues,
        [referenceLine.layerId]: nextValue
      };
    }, {});
    return {
      ...nextValueByDirection,
      [group]: nv
    };
  }, {});
};
exports.getNextValuesForReferenceLines = getNextValuesForReferenceLines;
const computeChartMargins = (referenceLinePaddings, labelVisibility, titleVisibility, axesMap, isHorizontal) => {
  const result = {};
  if (!(labelVisibility !== null && labelVisibility !== void 0 && labelVisibility.x) && !(titleVisibility !== null && titleVisibility !== void 0 && titleVisibility.x) && referenceLinePaddings.bottom) {
    const placement = isHorizontal ? (0, _helpers.mapVerticalToHorizontalPlacement)('bottom') : 'bottom';
    result[placement] = referenceLinePaddings.bottom;
  }
  if (referenceLinePaddings.left && (isHorizontal || !axesMap.left || !(labelVisibility !== null && labelVisibility !== void 0 && labelVisibility.yLeft) && !(titleVisibility !== null && titleVisibility !== void 0 && titleVisibility.yLeft))) {
    const placement = isHorizontal ? (0, _helpers.mapVerticalToHorizontalPlacement)('left') : 'left';
    result[placement] = referenceLinePaddings.left;
  }
  if (referenceLinePaddings.right && (isHorizontal || !axesMap.right || !(labelVisibility !== null && labelVisibility !== void 0 && labelVisibility.yRight) && !(titleVisibility !== null && titleVisibility !== void 0 && titleVisibility.yRight))) {
    const placement = isHorizontal ? (0, _helpers.mapVerticalToHorizontalPlacement)('right') : 'right';
    result[placement] = referenceLinePaddings.right;
  }
  // there's no top axis, so just check if a margin has been computed
  if (referenceLinePaddings.top) {
    const placement = isHorizontal ? (0, _helpers.mapVerticalToHorizontalPlacement)('top') : 'top';
    result[placement] = referenceLinePaddings.top;
  }
  return result;
};
exports.computeChartMargins = computeChartMargins;
function getAxisGroupForReferenceLine(axesConfiguration, decorationConfig, shouldRotate) {
  return axesConfiguration.find(axis => {
    var _decorationConfig$pos;
    return decorationConfig.axisId && axis.groupId.includes(decorationConfig.axisId) || (0, _helpers.getAxisPosition)((_decorationConfig$pos = decorationConfig.position) !== null && _decorationConfig$pos !== void 0 ? _decorationConfig$pos : _charts.Position.Left, shouldRotate) === axis.position;
  });
}
function getReferenceLinesFormattersMap(referenceLinesLayers, formatFactory) {
  const formattersMap = {};
  for (const layer of referenceLinesLayers) {
    if ((0, _helpers.isReferenceLine)(layer)) {
      for (const {
        valueMeta,
        forAccessor
      } of layer.decorations) {
        var _valueMeta$params, _valueMeta$params$par;
        if (valueMeta !== null && valueMeta !== void 0 && (_valueMeta$params = valueMeta.params) !== null && _valueMeta$params !== void 0 && (_valueMeta$params$par = _valueMeta$params.params) !== null && _valueMeta$params$par !== void 0 && _valueMeta$params$par.formatOverride) {
          formattersMap[forAccessor] = formatFactory(valueMeta.params);
        }
      }
    } else {
      for (const {
        forAccessor
      } of layer.decorations || []) {
        var _layer$table$columns$, _columnFormat$params;
        const columnFormat = (_layer$table$columns$ = layer.table.columns.find(({
          id
        }) => id === forAccessor)) === null || _layer$table$columns$ === void 0 ? void 0 : _layer$table$columns$.meta.params;
        if (columnFormat !== null && columnFormat !== void 0 && (_columnFormat$params = columnFormat.params) !== null && _columnFormat$params !== void 0 && _columnFormat$params.formatOverride) {
          formattersMap[forAccessor] = formatFactory(columnFormat);
        }
      }
    }
  }
  return formattersMap;
}