"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.DataLayers = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _charts = require("@elastic/charts");
var _react = _interopRequireDefault(require("react"));
var _utils = require("@kbn/visualizations-plugin/common/utils");
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.
 */

const DataLayers = ({
  titles = {},
  layers,
  endValue,
  timeZone,
  syncColors,
  valueLabels,
  fillOpacity,
  formatFactory,
  paletteService,
  fittingFunction,
  emphasizeFitting,
  yAxesConfiguration,
  xAxisConfiguration,
  shouldShowValueLabels,
  formattedDatatables,
  chartHasMoreThanOneBarSeries,
  defaultXScaleType,
  fieldFormats,
  uiState,
  singleTable,
  isDarkMode
}) => {
  // for singleTable mode we should use y accessors from all layers for creating correct series name and getting color
  const allYAccessors = layers.flatMap(layer => layer.accessors);
  const allColumnsToLabel = layers.reduce((acc, layer) => {
    if (layer.columnToLabel) {
      return {
        ...acc,
        ...JSON.parse(layer.columnToLabel)
      };
    }
    return acc;
  }, {});
  const allYTitles = Object.keys(titles).reduce((acc, key) => {
    if (titles[key].yTitles) {
      return {
        ...acc,
        ...titles[key].yTitles
      };
    }
    return acc;
  }, {});
  const colorAssignments = singleTable ? (0, _helpers.getColorAssignments)([{
    ...layers[0],
    layerId: 'commonLayerId',
    accessors: allYAccessors,
    columnToLabel: JSON.stringify(allColumnsToLabel)
  }], {
    commonLayerId: {
      ...titles,
      yTitles: allYTitles
    }
  }, {
    commonLayerId: fieldFormats[layers[0].layerId]
  }, {
    commonLayerId: formattedDatatables[layers[0].layerId]
  }) : (0, _helpers.getColorAssignments)(layers, titles, fieldFormats, formattedDatatables);
  const multipleLayersWithSplits = (0, _helpers.hasMultipleLayersWithSplits)(layers);
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, layers.flatMap(layer => {
    const yPercentileAccessors = [];
    const yAccessors = [];
    layer.accessors.forEach(accessor => {
      const columnId = (0, _utils.getAccessorByDimension)(accessor, layer.table.columns);
      if (columnId.includes('.')) {
        yPercentileAccessors.push(columnId);
      } else {
        yAccessors.push(columnId);
      }
    });
    return (yPercentileAccessors.length ? [...yAccessors, yPercentileAccessors] : [...yAccessors]).map((accessor, accessorIndex) => {
      const {
        seriesType,
        columnToLabel,
        layerId
      } = layer;
      const yColumnId = Array.isArray(accessor) ? accessor[0] : accessor;
      const columnToLabelMap = columnToLabel ? JSON.parse(columnToLabel) : {};

      // what if row values are not primitive? That is the case of, for instance, Ranges
      // remaps them to their serialized version with the formatHint metadata
      // In order to do it we need to make a copy of the table as the raw one is required for more features (filters, etc...) later on
      const formattedDatatableInfo = formattedDatatables[layerId];
      const yAxis = yAxesConfiguration.find(axisConfiguration => axisConfiguration.series.find(currentSeries => currentSeries.accessor === yColumnId));
      const isPercentage = yAxis !== null && yAxis !== void 0 && yAxis.mode ? (yAxis === null || yAxis === void 0 ? void 0 : yAxis.mode) === _constants.AxisModes.PERCENTAGE : layer.isPercentage;
      const seriesProps = (0, _helpers.getSeriesProps)({
        layer,
        titles: titles[layer.layerId],
        accessor,
        chartHasMoreThanOneBarSeries,
        colorAssignments,
        formatFactory,
        columnToLabelMap,
        paletteService,
        formattedDatatableInfo,
        syncColors,
        yAxis,
        xAxis: xAxisConfiguration,
        timeZone,
        emphasizeFitting,
        fillOpacity,
        defaultXScaleType,
        fieldFormats,
        uiState,
        allYAccessors,
        singleTable,
        multipleLayersWithSplits,
        isDarkMode
      });
      const index = `${layer.layerId}-${accessorIndex}`;
      const curve = layer.curveType ? _charts.CurveType[layer.curveType] : undefined;
      switch (seriesType) {
        case _constants.SeriesTypes.LINE:
          return /*#__PURE__*/_react.default.createElement(_charts.LineSeries, (0, _extends2.default)({
            key: index
          }, seriesProps, {
            fit: (0, _helpers.getFitOptions)(fittingFunction, endValue),
            curve: curve
          }));
        case _constants.SeriesTypes.BAR:
          const valueLabelsSettings = {
            displayValueSettings: {
              // This format double fixes two issues in elastic-chart
              // * when rotating the chart, the formatter is not correctly picked
              // * in some scenarios value labels are not strings, and this breaks the elastic-chart lib
              valueFormatter: d => {
                var _yAxis$formatter;
                return (yAxis === null || yAxis === void 0 ? void 0 : (_yAxis$formatter = yAxis.formatter) === null || _yAxis$formatter === void 0 ? void 0 : _yAxis$formatter.convert(d)) || '';
              },
              showValueLabel: shouldShowValueLabels && valueLabels !== _constants.ValueLabelModes.HIDE,
              isValueContainedInElement: false,
              isAlternatingValueLabel: false,
              overflowConstraints: [_charts.LabelOverflowConstraint.ChartEdges, _charts.LabelOverflowConstraint.BarGeometry]
            }
          };
          return /*#__PURE__*/_react.default.createElement(_charts.BarSeries, (0, _extends2.default)({
            key: index
          }, seriesProps, valueLabelsSettings));
        case _constants.SeriesTypes.AREA:
          return /*#__PURE__*/_react.default.createElement(_charts.AreaSeries, (0, _extends2.default)({
            key: index
          }, seriesProps, {
            fit: isPercentage ? 'zero' : (0, _helpers.getFitOptions)(fittingFunction, endValue),
            curve: curve
          }));
      }
    });
  }));
};
exports.DataLayers = DataLayers;