"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isRangeAnnotation = exports.getRangeAnnotations = exports.getAnnotationsGroupedByInterval = exports.OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION = exports.OUTSIDE_RECT_ANNOTATION_WIDTH = exports.Annotations = void 0;
require("./annotations.scss");
require("./reference_lines/reference_lines.scss");
var _react = _interopRequireWildcard(require("react"));
var _lodash = require("lodash");
var _charts = require("@elastic/charts");
var _moment = _interopRequireDefault(require("moment"));
var _eui = require("@elastic/eui");
var _eventAnnotationCommon = require("@kbn/event-annotation-common");
var _i18nReact = require("@kbn/i18n-react");
var _helpers = require("../helpers");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
 * 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 TooltipAnnotationDetails = ({
  row,
  extraFields
}) => {
  return extraFields.length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
    className: "xyAnnotationTooltip__extraFields"
  }, extraFields.map(field => /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
    gutterSize: "s"
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    className: "xyAnnotationTooltip__extraFieldsKey"
  }, field.name, ":"), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    className: "xyAnnotationTooltip__extraFieldsValue"
  }, field.formatter ? field.formatter.convert(row[field.key]) : row[field.key])))) : null;
};
const getExtraFields = (row, formatFactory, columns) => {
  return Object.keys(row).filter(key => key.startsWith('field:')).map(key => {
    var _columns$find, _columns$find$meta;
    const columnFormatter = columns === null || columns === void 0 ? void 0 : (_columns$find = columns.find(c => c.id === key)) === null || _columns$find === void 0 ? void 0 : (_columns$find$meta = _columns$find.meta) === null || _columns$find$meta === void 0 ? void 0 : _columns$find$meta.params;
    return {
      key,
      name: key.replace('field:', ''),
      formatter: columnFormatter && formatFactory(columnFormatter)
    };
  });
};
const DISPLAYED_COUNT_OF_ROWS = 5;
const createCustomTooltip = (rows, formatFactory, columns, timeFormat) => () => {
  const lastElement = rows[rows.length - 1];
  const skippedCountFromRequest = lastElement.skippedCount || 0;
  const displayedSkippedCount = rows.length > DISPLAYED_COUNT_OF_ROWS ? rows.length - DISPLAYED_COUNT_OF_ROWS : 0;
  const skippedCount = skippedCountFromRequest + displayedSkippedCount;
  return /*#__PURE__*/_react.default.createElement(_eui.EuiPanel, {
    color: "plain",
    hasShadow: false,
    hasBorder: false,
    paddingSize: "none",
    borderRadius: "none",
    className: "xyAnnotationTooltip"
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: "xyAnnotationTooltip__rows"
  }, rows.slice(0, DISPLAYED_COUNT_OF_ROWS).map((row, index) => {
    const extraFields = getExtraFields(row, formatFactory, columns);
    return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
      key: row.time
    }, index > 0 && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
      size: "xs"
    }), /*#__PURE__*/_react.default.createElement(_eui.EuiHorizontalRule, {
      margin: "none"
    }), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
      size: "xs"
    })), /*#__PURE__*/_react.default.createElement("div", {
      className: "xyAnnotationTooltip__row"
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
      gutterSize: "xs"
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false
    }, /*#__PURE__*/_react.default.createElement(_helpers.AnnotationIcon, {
      type: (0, _helpers.hasIcon)(row.icon) ? row.icon : 'empty',
      color: row.color
    })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiTitle, {
      size: "xxxs"
    }, /*#__PURE__*/_react.default.createElement("h6", null, row.label)), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, (0, _moment.default)(row.time).format(timeFormat)), /*#__PURE__*/_react.default.createElement(TooltipAnnotationDetails, {
      key: (0, _lodash.snakeCase)(row.time),
      row: row,
      extraFields: extraFields
    })))));
  })), skippedCount ? /*#__PURE__*/_react.default.createElement("div", {
    className: "xyAnnotationTooltip__skippedCount"
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
    size: "xs"
  }), /*#__PURE__*/_react.default.createElement(_eui.EuiHorizontalRule, {
    margin: "none"
  }), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
    size: "xs"
  }), /*#__PURE__*/_react.default.createElement("div", {
    className: "xyAnnotationTooltip__row "
  }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
    id: "expressionXY.annotations.skippedCount",
    defaultMessage: "+{value} more\u2026",
    values: {
      value: skippedCount
    }
  }))) : null);
};
function getCommonProperty(configArr, propertyName, fallbackValue) {
  const firstStyle = configArr[0][propertyName];
  if (configArr.every(config => firstStyle === config[propertyName])) {
    return firstStyle;
  }
  return fallbackValue;
}
const getCommonStyles = configArr => {
  return {
    color: getCommonProperty(configArr, 'color', _eventAnnotationCommon.defaultAnnotationColor),
    lineWidth: getCommonProperty(configArr, 'lineWidth', 1),
    lineStyle: getCommonProperty(configArr, 'lineStyle', 'solid'),
    textVisibility: getCommonProperty(configArr, 'textVisibility', false)
  };
};
const isRangeAnnotation = row => 'type' in row && row.type === 'range';
exports.isRangeAnnotation = isRangeAnnotation;
const getRangeAnnotations = datatable => datatable.rows.filter(row => 'type' in row && row.type === 'range');
exports.getRangeAnnotations = getRangeAnnotations;
const OUTSIDE_RECT_ANNOTATION_WIDTH = 8;
exports.OUTSIDE_RECT_ANNOTATION_WIDTH = OUTSIDE_RECT_ANNOTATION_WIDTH;
const OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION = 2;
exports.OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION = OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION;
const getAnnotationsGroupedByInterval = (annotations, configs, columns, formatFactory, timeFormat) => {
  const visibleGroupedConfigs = annotations.reduce((acc, current) => {
    const timebucket = (0, _moment.default)(current.timebucket).valueOf();
    return {
      ...acc,
      [timebucket]: acc[timebucket] ? [...acc[timebucket], current] : [current]
    };
  }, {});
  return Object.entries(visibleGroupedConfigs).map(([timebucket, rowsPerBucket]) => {
    var _columns$find2, _columns$find2$meta;
    const firstRow = rowsPerBucket[0];
    const config = configs === null || configs === void 0 ? void 0 : configs.find(c => c.id === firstRow.id);
    const textField = config && 'textField' in config && (config === null || config === void 0 ? void 0 : config.textField);
    const columnFormatter = columns === null || columns === void 0 ? void 0 : (_columns$find2 = columns.find(c => c.id === `field:${textField}`)) === null || _columns$find2 === void 0 ? void 0 : (_columns$find2$meta = _columns$find2.meta) === null || _columns$find2$meta === void 0 ? void 0 : _columns$find2$meta.params;
    const formatter = columnFormatter && formatFactory(columnFormatter);
    const label = textField && formatter && `field:${textField}` in firstRow ? formatter.convert(firstRow[`field:${textField}`]) : firstRow.label;
    const mergedAnnotation = {
      ...firstRow,
      label,
      icon: firstRow.icon || 'triangle',
      timebucket: Number(timebucket),
      position: 'bottom',
      customTooltip: createCustomTooltip(rowsPerBucket, formatFactory, columns, timeFormat),
      isGrouped: false
    };
    if (rowsPerBucket.length > 1) {
      const commonStyles = getCommonStyles(rowsPerBucket);
      return {
        ...mergedAnnotation,
        ...commonStyles,
        label: '',
        isGrouped: true,
        icon: String(rowsPerBucket.length)
      };
    }
    return mergedAnnotation;
  });
};

// todo: remove when closed https://github.com/elastic/elastic-charts/issues/1647
exports.getAnnotationsGroupedByInterval = getAnnotationsGroupedByInterval;
_charts.RectAnnotation.displayName = 'RectAnnotation';
const Annotations = ({
  groupedLineAnnotations,
  rangeAnnotations,
  formatter,
  isHorizontal,
  paddingMap,
  simpleView,
  minInterval,
  isBarChart,
  outsideDimension
}) => {
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, groupedLineAnnotations.map(annotation => {
    const markerPositionVertical = _charts.Position.Top;
    const hasReducedPadding = paddingMap[markerPositionVertical] === _helpers.LINES_MARKER_SIZE;
    const {
      timebucket,
      time,
      isGrouped,
      id: configId
    } = annotation;
    const strokeWidth = simpleView ? 1 : annotation.lineWidth || 1;
    const id = (0, _lodash.snakeCase)(`${configId}-${time}`);
    return /*#__PURE__*/_react.default.createElement(_charts.LineAnnotation, {
      id: id,
      key: id,
      domainType: _charts.AnnotationDomainType.XDomain,
      marker: !simpleView ? /*#__PURE__*/_react.default.createElement(_helpers.Marker, {
        config: annotation,
        isHorizontal: !isHorizontal,
        hasReducedPadding,
        label: !isGrouped ? annotation.label : undefined,
        rotateClassName: isHorizontal ? 'xyAnnotationIcon_rotate90' : undefined
      }) : undefined,
      markerBody: !simpleView ? /*#__PURE__*/_react.default.createElement(_helpers.MarkerBody, {
        label: !isGrouped && annotation.textVisibility && !hasReducedPadding ? annotation.label : undefined,
        isHorizontal: !isHorizontal
      }) : undefined,
      markerPosition: isHorizontal ? (0, _helpers.mapVerticalToHorizontalPlacement)(markerPositionVertical) : markerPositionVertical,
      dataValues: [{
        dataValue: isGrouped ? (0, _moment.default)(isBarChart && minInterval ? timebucket + minInterval / 2 : timebucket).valueOf() : (0, _moment.default)(time).valueOf(),
        details: annotation.label
      }],
      customTooltip: annotation.customTooltip,
      placement: "bottom",
      style: {
        line: {
          strokeWidth,
          stroke: annotation.color || _eventAnnotationCommon.defaultAnnotationColor,
          dash: annotation.lineStyle === 'dashed' ? [strokeWidth * 3, strokeWidth] : annotation.lineStyle === 'dotted' ? [strokeWidth, strokeWidth] : undefined,
          opacity: 1
        }
      }
    });
  }), rangeAnnotations.map(({
    id,
    label,
    time,
    color,
    endTime,
    outside
  }) => {
    return /*#__PURE__*/_react.default.createElement(_charts.RectAnnotation, {
      id: id,
      key: id,
      customTooltip: () => /*#__PURE__*/_react.default.createElement("div", {
        className: "echTooltip xyAnnotationTooltip"
      }, /*#__PURE__*/_react.default.createElement("div", {
        className: "echTooltip__header"
      }, /*#__PURE__*/_react.default.createElement(_eui.EuiText, {
        size: "xs"
      }, /*#__PURE__*/_react.default.createElement("h4", null, formatter ? `${formatter.convert(time)} — ${formatter === null || formatter === void 0 ? void 0 : formatter.convert(endTime)}` : `${(0, _moment.default)(time).toISOString()} — ${(0, _moment.default)(endTime).toISOString()}`))), /*#__PURE__*/_react.default.createElement("div", {
        className: "xyAnnotationTooltipDetail"
      }, label)),
      dataValues: [{
        coordinates: {
          x0: (0, _moment.default)(time).valueOf(),
          x1: (0, _moment.default)(endTime).valueOf()
        },
        details: label
      }],
      style: {
        fill: color || _eventAnnotationCommon.defaultAnnotationRangeColor,
        opacity: 1
      },
      outside: Boolean(outside),
      outsideDimension: outsideDimension
    });
  }));
};
exports.Annotations = Annotations;