'use strict';

var _extends = require('@babel/runtime/helpers/extends');
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var defaultsDeep = require('../../node_modules/lodash-es/defaultsDeep.js');
var isNil = require('../../node_modules/lodash-es/isNil.js');
var isEmpty = require('../../node_modules/lodash-es/isEmpty.js');
require('core-js/modules/es.symbol.js');
require('core-js/modules/es.array.concat.js');
require('core-js/modules/es.array.filter.js');
require('core-js/modules/es.array.includes.js');
require('core-js/modules/es.array.iterator.js');
require('core-js/modules/es.array.map.js');
require('core-js/modules/es.object.get-own-property-descriptor.js');
require('core-js/modules/es.object.get-own-property-descriptors.js');
require('core-js/modules/es.object.keys.js');
require('core-js/modules/es.object.to-string.js');
require('core-js/modules/es.set.js');
require('core-js/modules/es.string.includes.js');
require('core-js/modules/es.string.iterator.js');
require('core-js/modules/web.dom-collections.for-each.js');
require('core-js/modules/web.dom-collections.iterator.js');
var React = require('react');
var chartsReact = require('@carbon/charts-react');
var classnames = require('classnames');
var CardPropTypes = require('../../constants/CardPropTypes.js');
var LayoutConstants = require('../../constants/LayoutConstants.js');
var Card = require('../Card/Card.js');
var Settings = require('../../constants/Settings.js');
var cardUtilityFunctions = require('../../utils/cardUtilityFunctions.js');
var StatefulTable = require('../Table/StatefulTable.js');
var componentUtilityFunctions = require('../../utils/componentUtilityFunctions.js');
var dayjs = require('../../utils/dayjs.js');
var timeSeriesUtils = require('../TimeSeriesCard/timeSeriesUtils.js');
var barChartUtils = require('./barChartUtils.js');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var _extends__default = /*#__PURE__*/_interopDefault(_extends);
var _toConsumableArray__default = /*#__PURE__*/_interopDefault(_toConsumableArray);
var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
var _objectWithoutProperties__default = /*#__PURE__*/_interopDefault(_objectWithoutProperties);
var React__default = /*#__PURE__*/_interopDefault(React);
var classnames__default = /*#__PURE__*/_interopDefault(classnames);

var _excluded = ["title", "content", "children", "size", "values", "availableDimensions", "locale", "timeZone", "i18n", "isExpanded", "isLazyLoading", "isEditable", "isDashboardPreview", "isLoading", "isResizable", "interval", "className", "domainRange", "timeRange", "showTimeInGMT", "tooltipDateFormatPattern", "testID", "testId", "defaultDateFormatPattern"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty__default.default(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var iotPrefix = Settings.settings.iotPrefix;
var defaultProps = {
  size: LayoutConstants.CARD_SIZES.MEDIUMWIDE,
  i18n: {
    noDataLabel: 'No data',
    tooltipGroupLabel: 'Group',
    tooltipTotalLabel: 'Total',
    defaultFilterStringPlaceholdText: 'Filter'
  },
  domainRange: null,
  content: {
    type: LayoutConstants.BAR_CHART_TYPES.SIMPLE,
    layout: LayoutConstants.BAR_CHART_LAYOUTS.VERTICAL,
    legendPosition: 'bottom',
    truncation: {
      type: 'end_line',
      threshold: 20,
      numCharacter: 20
    },
    series: []
  },
  locale: 'en',
  timeZone: undefined,
  showTimeInGMT: false,
  tooltipDateFormatPattern: dayjs.DAYJS_INPUT_FORMATS.SECONDS,
  values: null,
  defaultDateFormatPattern: dayjs.DAYJS_INPUT_FORMATS.SECONDS
};
var BarChartCard = function BarChartCard(_ref) {
  var titleProp = _ref.title,
    content = _ref.content,
    children = _ref.children,
    sizeProp = _ref.size,
    initialValues = _ref.values,
    availableDimensions = _ref.availableDimensions,
    locale = _ref.locale,
    timeZone = _ref.timeZone,
    i18n = _ref.i18n,
    isExpanded = _ref.isExpanded,
    isLazyLoading = _ref.isLazyLoading,
    isEditable = _ref.isEditable,
    isDashboardPreview = _ref.isDashboardPreview,
    isLoading = _ref.isLoading,
    isResizable = _ref.isResizable,
    interval = _ref.interval,
    className = _ref.className,
    domainRange = _ref.domainRange,
    timeRange = _ref.timeRange,
    showTimeInGMT = _ref.showTimeInGMT,
    tooltipDateFormatPattern = _ref.tooltipDateFormatPattern,
    testID = _ref.testID,
    testId = _ref.testId,
    defaultDateFormatPattern = _ref.defaultDateFormatPattern,
    others = _objectWithoutProperties__default.default(_ref, _excluded);
  var effectiveTimezone = timeZone || dayjs.default.tz.guess();
  dayjs.default.tz.setDefault(effectiveTimezone);
  // need to deep merge the nested content default props as default props only uses a shallow merge natively
  var contentWithDefaults = React.useMemo(function () {
    return defaultsDeep({}, content, defaultProps.content);
  }, [content]);
  var mergedI18n = React.useMemo(function () {
    return _objectSpread(_objectSpread({}, defaultProps.i18n), i18n);
  }, [i18n]);
  var _handleCardVariables = cardUtilityFunctions.handleCardVariables(titleProp, contentWithDefaults, initialValues, others),
    title = _handleCardVariables.title,
    _handleCardVariables$ = _handleCardVariables.content,
    series = _handleCardVariables$.series,
    timeDataSourceId = _handleCardVariables$.timeDataSourceId,
    categoryDataSourceId = _handleCardVariables$.categoryDataSourceId,
    layout = _handleCardVariables$.layout,
    xLabel = _handleCardVariables$.xLabel,
    yLabel = _handleCardVariables$.yLabel,
    unit = _handleCardVariables$.unit,
    type = _handleCardVariables$.type,
    legendPosition = _handleCardVariables$.legendPosition,
    zoomBar = _handleCardVariables$.zoomBar,
    decimalPrecision = _handleCardVariables$.decimalPrecision,
    truncation = _handleCardVariables$.truncation,
    valuesProp = _handleCardVariables.values;
  var size = React.useMemo(function () {
    return cardUtilityFunctions.increaseSmallCardSize(sizeProp, 'BarChartCard');
  }, [sizeProp]);
  var resizeHandles = React.useMemo(function () {
    return isResizable ? cardUtilityFunctions.getResizeHandles(children) : [];
  }, [children, isResizable]);
  var memoizedGenerateSampleValues = React.useMemo(function () {
    return isEditable ? barChartUtils.generateSampleValues(series, timeDataSourceId, interval, timeRange, categoryDataSourceId) : [];
  },
  // eslint-disable-next-line react-hooks/exhaustive-deps
  [series, interval, timeRange, isEditable]);
  var memoizedGenerateSampleValuesForEditor = React.useMemo(function () {
    return isDashboardPreview ? barChartUtils.generateSampleValuesForEditor(series, timeDataSourceId, interval, timeRange, categoryDataSourceId, availableDimensions) : [];
  }, [isDashboardPreview, series, timeDataSourceId, categoryDataSourceId, interval, timeRange, availableDimensions]);

  // If editable, show sample presentation data
  // If there is no series defined, there is no datasets to make sample data from
  var values = React.useMemo(function () {
    return isDashboardPreview ? memoizedGenerateSampleValuesForEditor : isEditable && !isEmpty(series) ? memoizedGenerateSampleValues : valuesProp;
  }, [isDashboardPreview, isEditable, memoizedGenerateSampleValues, memoizedGenerateSampleValuesForEditor, series, valuesProp]);
  var chartData = React.useMemo(function () {
    return barChartUtils.formatChartData(series, values, categoryDataSourceId, timeDataSourceId, type, isDashboardPreview);
  }, [categoryDataSourceId, isDashboardPreview, series, timeDataSourceId, type, values]);
  var isAllValuesEmpty = React.useMemo(function () {
    return isEmpty(chartData);
  }, [chartData]);
  var ChartComponent = chartsReact.SimpleBarChart;
  if (type === LayoutConstants.BAR_CHART_TYPES.GROUPED) {
    ChartComponent = chartsReact.GroupedBarChart;
  } else if (type === LayoutConstants.BAR_CHART_TYPES.STACKED) {
    ChartComponent = chartsReact.StackedBarChart;
  }
  var scaleType = React.useMemo(function () {
    return timeDataSourceId ? 'time' : 'labels';
  }, [timeDataSourceId]);
  var axes = React.useMemo(function () {
    return barChartUtils.mapValuesToAxes(layout, categoryDataSourceId, timeDataSourceId, type);
  }, [categoryDataSourceId, layout, timeDataSourceId, type]);

  // Set the colors for each dataset
  var uniqueDatasets = React.useMemo(function () {
    return !isAllValuesEmpty ? _toConsumableArray__default.default(new Set(chartData.map(function (dataset) {
      return dataset.group;
    }))) : [];
  }, [chartData, isAllValuesEmpty]);
  var colors = React.useMemo(function () {
    return !isAllValuesEmpty ? barChartUtils.formatColors(series, uniqueDatasets, isDashboardPreview, type) : null;
  }, [isAllValuesEmpty, isDashboardPreview, series, type, uniqueDatasets]);
  var tableColumns = React.useMemo(function () {
    return isAllValuesEmpty ? [] : barChartUtils.generateTableColumns(timeDataSourceId, categoryDataSourceId, type, uniqueDatasets, mergedI18n.defaultFilterStringPlaceholdText).map(function (column) {
      return _objectSpread(_objectSpread({}, column), {}, {
        renderDataFunction: function renderDataFunction(_ref2) {
          var value = _ref2.value;
          if (typeof value === 'number' && !isNil(decimalPrecision)) {
            return cardUtilityFunctions.chartValueFormatter(value, size, unit, locale, decimalPrecision);
          }
          return value;
        }
      });
    });
  }, [categoryDataSourceId, decimalPrecision, mergedI18n.defaultFilterStringPlaceholdText, isAllValuesEmpty, locale, size, timeDataSourceId, type, uniqueDatasets, unit]);
  var tableData = React.useMemo(function () {
    return barChartUtils.formatTableData(timeDataSourceId, categoryDataSourceId, type, values, chartData, defaultDateFormatPattern);
  }, [categoryDataSourceId, chartData, defaultDateFormatPattern, timeDataSourceId, type, values]);
  var previousTick = React.useRef();
  dayjs.default.locale(locale);
  var maxTicksPerSize = React.useMemo(function () {
    return barChartUtils.getMaxTicksPerSize(sizeProp);
  }, [sizeProp]);
  var formatTick = React.useCallback(
  /** *
   * timestamp of current value
   * index of current value
   * ticks: array of current ticks
   */
  function (timestamp, index, ticks) {
    var previousTimestamp = previousTick.current;
    // store current in the previous tick
    previousTick.current = timestamp;
    return timeSeriesUtils.formatGraphTick(timestamp, index, ticks, interval, locale, previousTimestamp, showTimeInGMT);
  }, [interval, locale, showTimeInGMT]);
  var options = React.useMemo(function () {
    return _objectSpread(_objectSpread({
      animations: false,
      accessibility: true,
      axes: {
        bottom: _objectSpread(_objectSpread({
          title: "".concat(xLabel || '', " ").concat(layout === LayoutConstants.BAR_CHART_LAYOUTS.HORIZONTAL ? unit ? "(".concat(unit, ")") : '' : ''),
          scaleType: layout === LayoutConstants.BAR_CHART_LAYOUTS.VERTICAL ? scaleType : null,
          stacked: type === LayoutConstants.BAR_CHART_TYPES.STACKED && layout === LayoutConstants.BAR_CHART_LAYOUTS.HORIZONTAL && timeDataSourceId,
          mapsTo: axes.bottomAxesMapsTo
        }, domainRange && layout === LayoutConstants.BAR_CHART_LAYOUTS.VERTICAL ? {
          domain: domainRange
        } : {}), layout === LayoutConstants.BAR_CHART_LAYOUTS.HORIZONTAL && !isNil(decimalPrecision) ? {
          ticks: {
            formatter: function formatter(axisValue) {
              return cardUtilityFunctions.chartValueFormatter(axisValue, size, null, locale, decimalPrecision);
            }
          }
        } : scaleType === 'time' && axes.bottomAxesMapsTo === 'date' ? {
          ticks: {
            number: maxTicksPerSize,
            formatter: formatTick
          }
        } : {}),
        left: _objectSpread(_objectSpread({
          title: "".concat(yLabel || '', " ").concat(layout === LayoutConstants.BAR_CHART_LAYOUTS.VERTICAL ? unit ? "(".concat(unit, ")") : '' : '')
        }, layout === LayoutConstants.BAR_CHART_LAYOUTS.VERTICAL && !isNil(decimalPrecision) ? {
          ticks: {
            formatter: function formatter(axisValue) {
              return cardUtilityFunctions.chartValueFormatter(axisValue, size, null, locale, decimalPrecision);
            }
          }
        } : {}), {}, {
          scaleType: layout === LayoutConstants.BAR_CHART_LAYOUTS.HORIZONTAL ? scaleType : null,
          stacked: type === LayoutConstants.BAR_CHART_TYPES.STACKED && layout === LayoutConstants.BAR_CHART_LAYOUTS.VERTICAL,
          mapsTo: axes.leftAxesMapsTo
        }, domainRange && layout === LayoutConstants.BAR_CHART_LAYOUTS.HORIZONTAL && timeDataSourceId ? {
          domain: domainRange
        } : {})
      },
      legend: {
        position: legendPosition,
        enabled: chartData.length > 1,
        clickable: !isEditable,
        truncation: truncation
      },
      containerResizable: true,
      color: colors,
      tooltip: {
        valueFormatter: function valueFormatter(tooltipValue) {
          return cardUtilityFunctions.chartValueFormatter(tooltipValue, size, unit, locale, decimalPrecision);
        },
        customHTML: function customHTML() {
          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }
          return barChartUtils.handleTooltip.apply(void 0, args.concat([timeDataSourceId, showTimeInGMT, tooltipDateFormatPattern, locale, effectiveTimezone]));
        },
        groupLabel: mergedI18n.tooltipGroupLabel,
        totalLabel: mergedI18n.tooltipTotalLabel
      }
    }, zoomBar !== null && zoomBar !== void 0 && zoomBar.enabled && timeDataSourceId && (LayoutConstants.ZOOM_BAR_ENABLED_CARD_SIZES.includes(size) || isExpanded) ? {
      zoomBar: {
        // [zoomBar.axes]: {    TODO: the top axes is the only one supported at the moment so default to top
        top: {
          enabled: zoomBar.enabled,
          initialZoomDomain: zoomBar.initialZoomDomain,
          type: zoomBar.view || 'slider_view' // default to slider view
        }
      }
    } : {}), {}, {
      toolbar: {
        enabled: false
      }
    });
  }, [xLabel, layout, unit, scaleType, type, timeDataSourceId, axes.bottomAxesMapsTo, axes.leftAxesMapsTo, domainRange, decimalPrecision, maxTicksPerSize, formatTick, yLabel, legendPosition, chartData.length, isEditable, truncation, colors, mergedI18n.tooltipGroupLabel, mergedI18n.tooltipTotalLabel, zoomBar, size, isExpanded, locale, showTimeInGMT, tooltipDateFormatPattern, effectiveTimezone]);
  return /*#__PURE__*/React__default.default.createElement(Card.default, _extends__default.default({
    title: title,
    className: classnames__default.default(className, "".concat(iotPrefix, "--bar-chart-card")),
    size: size,
    i18n: mergedI18n,
    isExpanded: isExpanded,
    isEmpty: isAllValuesEmpty,
    isLazyLoading: isLazyLoading,
    isEditable: isEditable,
    isLoading: isLoading,
    isResizable: isResizable,
    resizeHandles: resizeHandles,
    timeRange: timeRange,
    locale: locale,
    timeZone: effectiveTimezone
    // TODO: remove deprecated testID in v3.
    ,
    testId: testID || testId
  }, others), !isAllValuesEmpty ? /*#__PURE__*/React__default.default.createElement("div", {
    className: classnames__default.default("".concat(iotPrefix, "--bar-chart-container"), _defineProperty__default.default(_defineProperty__default.default({}, "".concat(iotPrefix, "--bar-chart-container--expanded"), isExpanded), "".concat(iotPrefix, "--bar-chart-container--editable"), isEditable))
  }, /*#__PURE__*/React__default.default.createElement(ChartComponent
  // When showing the dashboard editor preview, we need to recalculate the chart scale
  // because the data is added and removed dynamically
  , {
    key: isDashboardPreview ? "bar-chart_preview_".concat(values.length, "_").concat(series.length) : 'bar-chart',
    data: chartData,
    options: options,
    width: "100%",
    height: "100%"
  }), isExpanded ? /*#__PURE__*/React__default.default.createElement(StatefulTable, {
    id: "BarChartCard-table",
    className: "".concat(iotPrefix, "--bar-chart-card--stateful-table"),
    columns: tableColumns,
    data: tableData,
    options: {
      hasPagination: true,
      hasSearch: true,
      hasFilter: true
    },
    actions: {
      toolbar: {
        onDownloadCSV: function onDownloadCSV(filteredData) {
          return componentUtilityFunctions.csvDownloadHandler(filteredData, title);
        }
      }
    },
    view: {
      pagination: {
        pageSize: 10,
        pageSizes: [10, 20, 30]
      },
      toolbar: {
        activeBar: null
      },
      filters: [],
      table: {
        sort: {
          columnId: timeDataSourceId,
          direction: 'DESC'
        },
        emptyState: {
          message: mergedI18n.noDataLabel
        }
      }
    },
    i18n: mergedI18n
  }) : null) : null);
};
BarChartCard.propTypes = _objectSpread(_objectSpread({}, CardPropTypes.CardPropTypes), CardPropTypes.BarChartCardPropTypes);
BarChartCard.defaultProps = defaultProps;
BarChartCard.__docgenInfo = {
  "description": "",
  "methods": [],
  "displayName": "BarChartCard",
  "props": {
    "size": {
      "defaultValue": {
        "value": "CARD_SIZES.MEDIUMWIDE",
        "computed": true
      },
      "required": false
    },
    "i18n": {
      "defaultValue": {
        "value": "{\n  noDataLabel: 'No data',\n  tooltipGroupLabel: 'Group',\n  tooltipTotalLabel: 'Total',\n  defaultFilterStringPlaceholdText: 'Filter',\n}",
        "computed": false
      },
      "required": false
    },
    "domainRange": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "required": false
    },
    "content": {
      "defaultValue": {
        "value": "{\n  type: BAR_CHART_TYPES.SIMPLE,\n  layout: BAR_CHART_LAYOUTS.VERTICAL,\n  legendPosition: 'bottom',\n  truncation: {\n    type: 'end_line',\n    threshold: 20,\n    numCharacter: 20,\n  },\n  series: [],\n}",
        "computed": false
      },
      "required": false
    },
    "locale": {
      "defaultValue": {
        "value": "'en'",
        "computed": false
      },
      "required": false
    },
    "timeZone": {
      "defaultValue": {
        "value": "undefined",
        "computed": true
      },
      "required": false
    },
    "showTimeInGMT": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "required": false
    },
    "tooltipDateFormatPattern": {
      "defaultValue": {
        "value": "DAYJS_INPUT_FORMATS.SECONDS",
        "computed": true
      },
      "required": false
    },
    "values": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "required": false
    },
    "defaultDateFormatPattern": {
      "defaultValue": {
        "value": "DAYJS_INPUT_FORMATS.SECONDS",
        "computed": true
      },
      "required": false
    }
  },
  "composes": ["../../constants/CardPropTypes"]
};
var BarChartCard$1 = BarChartCard;

module.exports = BarChartCard$1;
