'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _extends = require('@babel/runtime/helpers/extends');
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var isEqual = require('../../node_modules/lodash-es/isEqual.js');
var omit = require('../../node_modules/lodash-es/omit.js');
var isNil = require('../../node_modules/lodash-es/isNil.js');
var isEmpty = require('../../node_modules/lodash-es/isEmpty.js');
var merge = require('../../node_modules/lodash-es/merge.js');
require('core-js/modules/es.symbol.js');
require('core-js/modules/es.array.filter.js');
require('core-js/modules/es.array.iterator.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/web.dom-collections.for-each.js');
require('core-js/modules/web.dom-collections.iterator.js');
var _regeneratorRuntime = require('@babel/runtime/regenerator');
var React = require('react');
var PropTypes = require('prop-types');
var warning = require('warning');
var ValueCard = require('../ValueCard/ValueCard.js');
var ImageCard = require('../ImageCard/ImageCard.js');
var TableCard = require('../TableCard/TableCard.js');
var BarChartCard = require('../BarChartCard/BarChartCard.js');
var TimeSeriesCard = require('../TimeSeriesCard/TimeSeriesCard.js');
var ListCard = require('../ListCard/ListCard.js');
var GaugeCard = require('../GaugeCard/GaugeCard.js');
var Card = require('../Card/Card.js');
var LayoutConstants = require('../../constants/LayoutConstants.js');
var cardUtilityFunctions = require('../../utils/cardUtilityFunctions.js');
var usePrevious = require('../../hooks/usePrevious.js');

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

var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
var _asyncToGenerator__default = /*#__PURE__*/_interopDefault(_asyncToGenerator);
var _extends__default = /*#__PURE__*/_interopDefault(_extends);
var _slicedToArray__default = /*#__PURE__*/_interopDefault(_slicedToArray);
var _objectWithoutProperties__default = /*#__PURE__*/_interopDefault(_objectWithoutProperties);
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
var React__default = /*#__PURE__*/_interopDefault(React);
var PropTypes__default = /*#__PURE__*/_interopDefault(PropTypes);
var warning__default = /*#__PURE__*/_interopDefault(warning);

var _excluded = ["style"],
  _excluded2 = ["onCardAction", "i18n", "isLoading", "isEditable", "breakpoint", "onFetchData", "onSetupCard", "renderIconByName", "timeGrain"];
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; }

/**
 *
 * This component is needed to cache the style object for performance reasons because unfortunately, the style object changes with every render from React Grid Layout
 */
var CachedCardRenderer = function CachedCardRenderer(_ref) {
  var style = _ref.style,
    others = _objectWithoutProperties__default.default(_ref, _excluded);
  var _useState = React.useState(style),
    _useState2 = _slicedToArray__default.default(_useState, 2),
    cachedStyle = _useState2[0],
    setCachedStyle = _useState2[1];
  var previousStyle = usePrevious.usePrevious(style);
  React.useEffect(function () {
    if (!isEqual(style, previousStyle)) {
      setCachedStyle(style);
    }
  }, [previousStyle, style]);
  return /*#__PURE__*/React__default.default.createElement(CardRenderer, _extends__default.default({}, others, {
    style: cachedStyle
  }));
};

/** Asynchronous reusable function to load Card Data */
var loadCardData = /*#__PURE__*/function () {
  var _ref2 = _asyncToGenerator__default.default(/*#__PURE__*/_regeneratorRuntime__default.default.mark(function _callee(card, setCard, onFetchData, timeGrain) {
    var cardWithData;
    return _regeneratorRuntime__default.default.wrap(function _callee$(_context) {
      while (1) switch (_context.prev = _context.next) {
        case 0:
          if (!card.dataSource) {
            _context.next = 6;
            break;
          }
          // Set state to loading
          setCard(_objectSpread(_objectSpread({}, card), {}, {
            isLoading: true
          }));
          _context.next = 4;
          return onFetchData(card, card.type !== LayoutConstants.CARD_TYPES.IMAGE && card.type !== LayoutConstants.CARD_TYPES.VALUE);
        case 4:
          cardWithData = _context.sent;
          setCard(_objectSpread(_objectSpread({}, cardWithData), {}, {
            timeGrain: cardUtilityFunctions.compareGrains(timeGrain, card.timeGrain) < 1 ? card.timeGrain : timeGrain,
            isLoading: false
          }));
        case 6:
        case "end":
          return _context.stop();
      }
    }, _callee);
  }));
  return function loadCardData(_x, _x2, _x3, _x4) {
    return _ref2.apply(this, arguments);
  };
}();

/**
 * This component decides which card component to render when passed a certain card type.
 * It keeps the local state of the card (which determines which range selection is being shown, etc)
 * It also caches some properties between renders to speed performance
 *
 * It watches the isLoading bit to see if the card needs to trigger a data reload.  If the isLoading bit changes to true
 * it will trigger the dashboard's onSetupCard function and then it's onFetchData function to retrieve the updated card properties
 * for each card.
 */
var CardRenderer = /*#__PURE__*/React__default.default.memo(function (_ref3) {
  _ref3.onCardAction;
    var i18n = _ref3.i18n,
    isLoading = _ref3.isLoading,
    isEditable = _ref3.isEditable,
    breakpoint = _ref3.breakpoint,
    onFetchData = _ref3.onFetchData,
    onSetupCard = _ref3.onSetupCard,
    renderIconByName = _ref3.renderIconByName,
    timeGrain = _ref3.timeGrain,
    cardProp = _objectWithoutProperties__default.default(_ref3, _excluded2);
  // pass through the card props
  /* eslint-enable react/prop-types */
  {
    warning__default.default(false, 'CardRenderer component has been deprecated and will be removed in the next release of `carbon-addons-iot-react`.') ;
  }
  var dataSource = cardProp.dataSource,
    availableActions = cardProp.availableActions,
    type = cardProp.type;

  /**
   * Local state for the card, keeps track of whether it is loading or not, and the current state of the Range Selector
   * And which data range is being requested.
   */
  var _useState3 = React.useState(cardProp),
    _useState4 = _slicedToArray__default.default(_useState3, 2),
    card = _useState4[0],
    setCard = _useState4[1];
  // Keep track of the original datasource setting
  var _useState5 = React.useState(dataSource),
    _useState6 = _slicedToArray__default.default(_useState5, 1),
    originalDataSource = _useState6[0];
  // keep track of the expanded card id
  var _useState7 = React.useState(),
    _useState8 = _slicedToArray__default.default(_useState7, 2),
    isExpanded = _useState8[0],
    setIsExpanded = _useState8[1];

  // Allow the i18n to change between renders
  var cachedI18N = React.useMemo(function () {
    return _objectSpread(_objectSpread({}, i18n), card.i18n);
  }, [i18n, card.i18n]);

  // If the dashboard has triggered a bulk load, refetch the data
  React.useEffect(function () {
    var setupAndLoadCard = /*#__PURE__*/function () {
      var _ref4 = _asyncToGenerator__default.default(/*#__PURE__*/_regeneratorRuntime__default.default.mark(function _callee2() {
        var updatedCard;
        return _regeneratorRuntime__default.default.wrap(function _callee2$(_context2) {
          while (1) switch (_context2.prev = _context2.next) {
            case 0:
              updatedCard = card; // Image cards require extra setup before loading data
              if (!(onSetupCard && card.type === LayoutConstants.CARD_TYPES.IMAGE && !card.content.src)) {
                _context2.next = 6;
                break;
              }
              _context2.next = 4;
              return onSetupCard(card);
            case 4:
              updatedCard = _context2.sent;
              setCard(updatedCard);
            case 6:
              loadCardData(updatedCard, setCard, onFetchData, timeGrain);
            case 7:
            case "end":
              return _context2.stop();
          }
        }, _callee2);
      }));
      return function setupAndLoadCard() {
        return _ref4.apply(this, arguments);
      };
    }();
    if (isLoading) {
      setupAndLoadCard();
    }
  }, [isLoading, card.content.src] // eslint-disable-line react-hooks/exhaustive-deps
  );

  // Speed up performance by caching the available actions
  var cachedActions = React.useMemo(function () {
    return merge({
      range: !isEmpty(dataSource),
      // all cards should have the range picker
      expand: type === LayoutConstants.CARD_TYPES.IMAGE || type === LayoutConstants.CARD_TYPES.TIMESERIES || type === LayoutConstants.CARD_TYPES.TABLE || type === LayoutConstants.CARD_TYPES.BAR || (availableActions === null || availableActions === void 0 ? void 0 : availableActions.expand) // image and line chart cards should have expand
    }, availableActions || {});
  }, [availableActions, dataSource, type]);

  /**
   * Listen to the card's range action to decide whether to trigger a data refetch
   */
  var cachedOnCardAction = React.useCallback(/*#__PURE__*/function () {
    var _ref5 = _asyncToGenerator__default.default(/*#__PURE__*/_regeneratorRuntime__default.default.mark(function _callee3(id, actionType, payload) {
      var range, cardWithUpdatedRange;
      return _regeneratorRuntime__default.default.wrap(function _callee3$(_context3) {
        while (1) switch (_context3.prev = _context3.next) {
          case 0:
            // callback time grain change from parent
            if (actionType === LayoutConstants.CARD_ACTIONS.CHANGE_TIME_RANGE) {
              // First update the range
              range = payload && payload.range !== 'default' ? cardUtilityFunctions.determineCardRange(payload.range) : originalDataSource.range; // If default, then reset the card range
              cardWithUpdatedRange = _objectSpread(_objectSpread({}, card), {}, {
                // expand the current card state
                isLoading: true,
                // set loading
                dataSource: _objectSpread(_objectSpread({}, cardProp.dataSource), {}, {
                  range: _objectSpread(_objectSpread({}, range), omit(range, 'timeGrain')),
                  // Use the maximum selected grain betweeen the dashboard and the current range
                  timeGrain: cardUtilityFunctions.compareGrains(timeGrain, range.timeGrain) < 1 ? range.timeGrain : timeGrain
                })
              }); // Then trigger a load of the card data
              loadCardData(cardWithUpdatedRange, setCard, onFetchData, timeGrain);
            } else if (actionType === LayoutConstants.CARD_ACTIONS.OPEN_EXPANDED_CARD) {
              setIsExpanded(true);
            } else if (actionType === LayoutConstants.CARD_ACTIONS.UPDATE_DATA) {
              // New action type where we pass the updated values data
              setCard(function (currentCardState) {
                return _objectSpread(_objectSpread({}, currentCardState), {}, {
                  values: payload === null || payload === void 0 ? void 0 : payload.values
                });
              });
            }

            // close expanded card
            if (actionType === LayoutConstants.CARD_ACTIONS.CLOSE_EXPANDED_CARD) {
              setIsExpanded(false);
            }
          case 2:
          case "end":
            return _context3.stop();
        }
      }, _callee3);
    }));
    return function (_x5, _x6, _x7) {
      return _ref5.apply(this, arguments);
    };
  }(), /* eslint-disable react-hooks/exhaustive-deps */
  [card, onFetchData, originalDataSource && originalDataSource.range, timeGrain]
  /* eslint-enable react-hooks/exhaustive-deps */);
  var commonCardProps = _objectSpread(_objectSpread(_objectSpread({}, card), card.type === 'CUSTOM' && cardProp.content ? {
    content: cardProp.content
  } : {}), {}, {
    // the card content function cannot be cached for custom cards
    style: cardProp.style,
    // these come from grid layout and not state
    className: cardProp.className,
    // these come from grid layout and not state
    key: cardProp.id,
    availableActions: cachedActions,
    isExpanded: isExpanded,
    i18n: cachedI18N,
    isEditable: isEditable,
    onCardAction: cachedOnCardAction,
    renderIconByName: renderIconByName,
    breakpoint: breakpoint
  });
  return type === LayoutConstants.CARD_TYPES.VALUE ? /*#__PURE__*/React__default.default.createElement(ValueCard, commonCardProps) : type === LayoutConstants.CARD_TYPES.IMAGE ? /*#__PURE__*/React__default.default.createElement(ImageCard, _extends__default.default({}, commonCardProps, {
    error: card.setupError || card.error
  })) : type === LayoutConstants.CARD_TYPES.TIMESERIES ? /*#__PURE__*/React__default.default.createElement(TimeSeriesCard, commonCardProps) : type === LayoutConstants.CARD_TYPES.TABLE ? /*#__PURE__*/React__default.default.createElement(TableCard, commonCardProps) : type === LayoutConstants.CARD_TYPES.BAR ? /*#__PURE__*/React__default.default.createElement(BarChartCard, commonCardProps) : type === LayoutConstants.CARD_TYPES.LIST ? /*#__PURE__*/React__default.default.createElement(ListCard, _extends__default.default({}, commonCardProps, {
    data: card.content.data,
    loadData: card.content.loadData
  })) : type === LayoutConstants.CARD_TYPES.GAUGE ? /*#__PURE__*/React__default.default.createElement(GaugeCard.default, commonCardProps) : type === LayoutConstants.CARD_TYPES.CUSTOM ? /*#__PURE__*/React__default.default.createElement(Card.default, _extends__default.default({
    hideHeader: isNil(card.title)
  }, omit(commonCardProps, 'content')), card.content) : null;
});
CachedCardRenderer.propTypes = {
  style: PropTypes__default.default.objectOf(PropTypes__default.default.string)
};
CachedCardRenderer.defaultProps = {
  style: {}
};
CachedCardRenderer.__docgenInfo = {
  "description": "This component is needed to cache the style object for performance reasons because unfortunately, the style object changes with every render from React Grid Layout",
  "methods": [],
  "displayName": "CachedCardRenderer",
  "props": {
    "style": {
      "defaultValue": {
        "value": "{}",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "objectOf",
        "value": {
          "name": "string"
        }
      },
      "required": false
    }
  }
};
var CardRenderer$1 = CachedCardRenderer;

exports.default = CardRenderer$1;
exports.loadCardData = loadCardData;
