"use strict";

exports.__esModule = true;
exports.default = void 0;

var _react = _interopRequireWildcard(require("react"));

var _clsx = _interopRequireDefault(require("clsx"));

var _ConfigProviderContext = _interopRequireDefault(require("../config-provider/ConfigProviderContext"));

var _actionBar = _interopRequireDefault(require("../action-bar"));

var _image = require("../image");

var _hooks = require("../hooks");

var _constant = require("../utils/constant");

var _imagePreview = _interopRequireDefault(require("../image-preview"));

var _popup = require("../popup");

var _utils = require("./utils");

var _constants = require("./constants");

var _SkuRow = _interopRequireDefault(require("./components/SkuRow"));

var _SkuRowItem = _interopRequireDefault(require("./components/SkuRowItem"));

var _SkuRowPropItem = _interopRequireDefault(require("./components/SkuRowPropItem"));

var _SkuStepper = _interopRequireDefault(require("./components/SkuStepper"));

var _toast = _interopRequireDefault(require("../toast"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(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; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

var QUOTA_LIMIT = _constants.LIMIT_TYPE.QUOTA_LIMIT;
var Sku = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
  var _props$goods, _props$popupProps;

  var _useContext = (0, _react.useContext)(_ConfigProviderContext.default),
      prefixCls = _useContext.prefixCls,
      createNamespace = _useContext.createNamespace;

  var _createNamespace = createNamespace('sku', prefixCls),
      bem = _createNamespace[0];

  var stepperError = (0, _react.useRef)(false);

  var _useState = (0, _react.useState)(false),
      visible = _useState[0],
      setVisible = _useState[1];

  var _useSetState = (0, _hooks.useSetState)({
    selectedSku: {},
    selectedProp: {},
    selectedNum: props.startSaleNum
  }),
      state = _useSetState[0],
      updateState = _useSetState[1];

  var sku = props.sku,
      _props$properties = props.properties,
      properties = _props$properties === void 0 ? [] : _props$properties;
  var _sku$tree = sku.tree,
      tree = _sku$tree === void 0 ? [] : _sku$tree;
  var bodyStyle = (0, _react.useMemo)(function () {
    var maxHeight = window.innerHeight - props.bodyOffsetTop;
    return {
      maxHeight: maxHeight + "px"
    };
  }, [props.bodyOffsetTop]);
  var imageList = (0, _react.useMemo)(function () {
    var goods = props.goods;
    var rs = [goods == null ? void 0 : goods.picture];

    if (sku.tree.length > 0) {
      sku.tree.forEach(function (treeItem) {
        if (!treeItem.v) return;
        treeItem.v.forEach(function (vItem) {
          var img = vItem.previewImgUrl || vItem.imgUrl || vItem.img_url;

          if (img && rs.indexOf(img) === -1) {
            rs.push(img);
          }
        });
      });
    }

    return rs;
  }, [(_props$goods = props.goods) == null ? void 0 : _props$goods.picture, sku.tree]);
  var hasSku = (0, _react.useMemo)(function () {
    return !sku.none_sku;
  }, [sku.none_sku]);
  var hasSkuOrAttr = (0, _react.useMemo)(function () {
    return hasSku || properties.length > 0;
  }, [hasSku, properties]);
  var isSkuCombSelected = (0, _react.useMemo)(function () {
    // SKU 未选完
    if (hasSku && !(0, _utils.isAllSelected)(tree, state.selectedSku)) {
      return false;
    } // 属性未全选


    return !properties.filter(function (i) {
      return i.is_necessary !== false;
    }).some(function (i) {
      return (state.selectedProp[i.k_id] || []).length === 0;
    });
  }, [hasSku, state]);
  var selectedSkuValues = (0, _react.useMemo)(function () {
    return (0, _utils.getSelectedSkuValues)(tree, state.selectedSku);
  }, [tree, state.selectedSku]);
  var selectedPropValues = (0, _react.useMemo)(function () {
    return (0, _utils.getSelectedPropValues)(properties, state.selectedProp);
  }, [properties, state.selectedProp]);
  var selectedSkuComb = (0, _react.useMemo)(function () {
    var skuComb = null;

    if (isSkuCombSelected) {
      if (hasSku) {
        skuComb = (0, _utils.getSkuComb)(sku.list, state.selectedSku);
      } else {
        skuComb = {
          id: sku.collection_id,
          price: Math.round(+sku.price * 100),
          stock_num: sku.stock_num
        };
      }

      if (skuComb) {
        skuComb.properties = (0, _utils.getSelectedProperties)(properties, state.selectedProp);
        skuComb.property_price = selectedPropValues.reduce(function (acc, cur) {
          return acc + (cur.price || 0);
        }, 0);
      }
    }

    return skuComb;
  }, [isSkuCombSelected, hasSku, JSON.stringify(sku), JSON.stringify(state), properties, selectedPropValues]);
  var unselectedSku = (0, _react.useMemo)(function () {
    return tree.filter(function (item) {
      return !state.selectedSku[item.k_s];
    }).map(function (item) {
      return item.k;
    });
  }, [tree, state.selectedSku]);
  var getUnselectedProp = (0, _react.useCallback)(function (isNecessary) {
    return properties.filter(function (item) {
      return isNecessary ? item.is_necessary !== false : true;
    }).filter(function (item) {
      return (state.selectedProp[item.k_id] || []).length < 1;
    }).map(function (item) {
      return item.k;
    });
  }, [properties, state.selectedProp]);
  var selectedText = (0, _react.useMemo)(function () {
    if (selectedSkuComb) {
      var values = selectedSkuValues.concat(selectedPropValues);
      return "\u5DF2\u9009 " + values.map(function (item) {
        return item.name;
      }).join(' ');
    }

    return "\u8BF7\u9009\u62E9 " + unselectedSku.concat(getUnselectedProp()).join(' ');
  }, [unselectedSku, getUnselectedProp, selectedSkuComb, selectedSkuValues, selectedPropValues]);
  var price = (0, _react.useMemo)(function () {
    if (selectedSkuComb) {
      return ((selectedSkuComb.price + selectedSkuComb.property_price) / 100).toFixed(2);
    } // sku.price是一个格式化好的价格区间


    return sku.price;
  }, [JSON.stringify(selectedSkuComb), sku.price]);
  var stock = (0, _react.useMemo)(function () {
    var stockNum = props.customStepperConfig.stockNum;

    if (stockNum !== undefined) {
      return stockNum;
    }

    if (selectedSkuComb) {
      return selectedSkuComb.stock_num;
    }

    return sku.stock_num;
  }, [sku.stock_num, JSON.stringify(selectedSkuComb)]);
  var stockContent = (0, _react.useMemo)(function () {
    if (props.stockRender) {
      return props.stockRender(stock);
    }

    return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "\u5269\u4F59", /*#__PURE__*/_react.default.createElement("span", {
      className: (0, _clsx.default)(bem('stock-num', {
        highlight: stock < props.stockThreshold
      }))
    }, stock), "\u4EF6");
  }, [stock]);

  var onSelect = function onSelect(skuValue) {
    var _extends2, _extends3;

    // 点击已选中的sku时则取消选中
    var selectedSku = state.selectedSku[skuValue.skuKeyStr] === skuValue.id ? _extends({}, state.selectedSku, (_extends2 = {}, _extends2[skuValue.skuKeyStr] = _constants.UNSELECTED_SKU_VALUE_ID, _extends2)) : _extends({}, state.selectedSku, (_extends3 = {}, _extends3[skuValue.skuKeyStr] = skuValue.id, _extends3));
    updateState({
      selectedSku: selectedSku
    });

    if (props.onSkuSelected) {
      props.onSkuSelected({
        skuValue: skuValue,
        selectedSku: state.selectedSku,
        selectedSkuComb: selectedSkuComb
      });
    }
  };

  var onPropSelect = function onPropSelect(propValue) {
    var _extends4;

    var arr = state.selectedProp[propValue.skuKeyStr] || [];
    var pos = arr.indexOf(propValue.id);

    if (pos > -1) {
      arr.splice(pos, 1);
    } else if (propValue.multiple) {
      arr.push(propValue.id);
    } else {
      arr.splice(0, 1, propValue.id);
    }

    var selectedProp = _extends({}, state.selectedProp, (_extends4 = {}, _extends4[propValue.skuKeyStr] = arr, _extends4));

    updateState({
      selectedProp: selectedProp
    });

    if (props.onSkuPropSelected) {
      props.onSkuPropSelected({
        propValue: propValue,
        selectedProp: state.selectedProp,
        selectedSkuComb: selectedSkuComb
      });
    }
  };

  var onOverLimit = function onOverLimit(data) {
    var action = data.action,
        limitType = data.limitType,
        quota = data.quota,
        quotaUsed = data.quotaUsed;
    var handleOverLimit = props.customStepperConfig.handleOverLimit;

    if (handleOverLimit) {
      handleOverLimit(data);
      return;
    }

    if (action === 'minus') {
      if (props.startSaleNum > 1) {
        (0, _toast.default)(props.startSaleNum + "\u4EF6\u8D77\u552E");
      } else {
        (0, _toast.default)('至少选择一件');
      }
    } else if (action === 'plus') {
      if (limitType === QUOTA_LIMIT) {
        if (quotaUsed > 0) {
          (0, _toast.default)("\u6BCF\u4EBA\u9650\u8D2D" + quota + "\u4EF6\uFF0C\u4F60\u5DF2\u8D2D\u4E70" + quotaUsed + "\u4EF6");
        } else {
          (0, _toast.default)("\u6BCF\u4EBA\u9650\u8D2D" + quota + "\u4EF6");
        }
      } else {
        (0, _toast.default)('库存不足');
      }
    }
  };

  var onStepperState = function onStepperState(data) {
    stepperError.current = data.valid ? null : _extends({}, data, {
      action: 'plus'
    });
  };

  var validateSku = function validateSku() {
    if (state.selectedNum === 0) {
      return '商品已经无法购买啦';
    }

    if (isSkuCombSelected) {
      return '';
    }

    return "\u8BF7\u9009\u62E9 " + unselectedSku.concat(getUnselectedProp(true)).join(' ');
  };

  var getSkuData = function getSkuData() {
    return {
      goodsId: props.goodsId,
      selectedNum: state.selectedNum,
      selectedSkuComb: selectedSkuComb
    };
  };

  var onAddCart = function onAddCart(data) {
    props.onAddCart == null ? void 0 : props.onAddCart(data);
  };

  var onBuyClicked = function onBuyClicked(data) {
    props.onBuyClicked == null ? void 0 : props.onBuyClicked(data);
  };

  var onBuyOrAddCart = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(type) {
      var error, data;
      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!stepperError.current) {
                _context.next = 3;
                break;
              }

              onOverLimit(stepperError.current);
              return _context.abrupt("return");

            case 3:
              if (!props.customSkuValidator) {
                _context.next = 10;
                break;
              }

              _context.next = 6;
              return props.customSkuValidator(type, _extends({}, state.selectedSku, state.selectedProp));

            case 6:
              if (_context.sent) {
                _context.next = 8;
                break;
              }

              return _context.abrupt("return");

            case 8:
              _context.next = 14;
              break;

            case 10:
              error = validateSku();

              if (!error) {
                _context.next = 14;
                break;
              }

              (0, _toast.default)(error);
              return _context.abrupt("return");

            case 14:
              data = getSkuData();

              if (type === 'add-cart') {
                onAddCart(data);
              } else {
                onBuyClicked(data);
              }

            case 16:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));

    return function onBuyOrAddCart(_x) {
      return _ref.apply(this, arguments);
    };
  }();

  var show = function show(initialValue) {
    setVisible(true);

    if (initialValue) {
      updateState(initialValue);
    }
  };

  var reset = function reset() {
    updateState({
      selectedSku: {},
      selectedProp: {},
      selectedNum: props.startSaleNum
    });
  };

  var onPopupClose = function onPopupClose() {
    setVisible(false);
    if (props.popupProps && props.popupProps.onClose) props.popupProps.onClose();
  };

  var onPopupClosed = function onPopupClosed() {
    if (props.resetOnHide) {
      reset();
    }

    if (props.popupProps && props.popupProps.onClosed) props.popupProps.onClosed();
  };

  var onPreviewImage = function onPreviewImage(selectedValue) {
    var index = 0;
    var indexImage = imageList[0];

    if (selectedValue && selectedValue.imgUrl) {
      imageList.some(function (image, pos) {
        if (image === selectedValue.imgUrl) {
          index = pos;
          return true;
        }

        return false;
      });
      indexImage = selectedValue.imgUrl;
    }

    var params = _extends({}, selectedValue, {
      index: index,
      imageList: imageList,
      indexImage: indexImage
    });

    if (!props.previewOnClickImage) return;

    _imagePreview.default.open({
      images: imageList,
      startPosition: index,
      onClose: function onClose() {
        if (props.onClosePreview) props.onClosePreview(params);
      }
    });

    if (props.onOpenPreview) {
      props.onOpenPreview(params);
    }
  };

  var renderHeaderInfo = function renderHeaderInfo() {
    return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (props.skuHeaderPriceRender == null ? void 0 : props.skuHeaderPriceRender(price)) || /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('goods-price'))
    }, /*#__PURE__*/_react.default.createElement("span", {
      className: (0, _clsx.default)(bem('price-symbol'))
    }, "\uFFE5"), /*#__PURE__*/_react.default.createElement("span", {
      className: (0, _clsx.default)(bem('price-num'))
    }, price), props.priceTag && /*#__PURE__*/_react.default.createElement("span", {
      className: (0, _clsx.default)(bem('price-tag'))
    }, props.priceTag)), props.skuHeaderOriginPrice && /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('header-item'))
    }, props.skuHeaderOriginPrice), !props.hideStock && /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('header-item'))
    }, /*#__PURE__*/_react.default.createElement("span", {
      className: (0, _clsx.default)(bem('stock'))
    }, stockContent)), !props.hideSelectedText && /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('header-item'))
    }, selectedText));
  };

  var renderHeader = function renderHeader() {
    if (props.skuHeader) return props.skuHeader;
    var selectedValue = (0, _utils.getSkuImgValue)(sku, state.selectedSku);
    var imgUrl = selectedValue ? selectedValue.imgUrl : props.goods.picture;
    return /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('header'), _constant.BORDER_BOTTOM)
    }, props.showHeaderImage && /*#__PURE__*/_react.default.createElement(_image.Image, {
      fit: "cover",
      src: imgUrl,
      className: (0, _clsx.default)(bem('header__img-wrap')),
      onClick: function onClick() {
        return onPreviewImage(selectedValue);
      }
    }, props.skuHeaderImageExtra), /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('header__goods-info'))
    }, renderHeaderInfo(), props.skuHeaderExtra));
  };

  var renderGroup = function renderGroup() {
    return props.skuGroup || hasSkuOrAttr && /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('group-container', {
        'hide-soldout': !props.showSoldoutSku
      }))
    }, tree.map(function (skuTreeItem, i) {
      return /*#__PURE__*/_react.default.createElement(_SkuRow.default, {
        key: i,
        skuRow: skuTreeItem
      }, skuTreeItem.v.map(function (skuValue, idx) {
        return /*#__PURE__*/_react.default.createElement(_SkuRowItem.default, {
          key: idx,
          skuList: sku.list,
          skuValue: skuValue,
          skuKeyStr: "" + skuTreeItem.k_s,
          selectedSku: state.selectedSku,
          disableSoldoutSku: props.disableSoldoutSku,
          largeImageMode: skuTreeItem.largeImageMode,
          previewIcon: props.previewIcon,
          onSkuSelected: onSelect,
          onSkuPreviewImage: function onSkuPreviewImage(selectedValue) {
            return onPreviewImage(selectedValue);
          }
        });
      }));
    }), properties.map(function (skuTreeItem, i) {
      return /*#__PURE__*/_react.default.createElement(_SkuRow.default, {
        key: i,
        skuRow: skuTreeItem
      }, skuTreeItem.v.map(function (skuValue, idx) {
        return /*#__PURE__*/_react.default.createElement(_SkuRowPropItem.default, {
          key: idx,
          skuValue: skuValue,
          skuKeyStr: "" + skuTreeItem.k_id,
          selectedProp: state.selectedProp,
          multiple: skuTreeItem.is_multiple,
          onSkuPropSelected: onPropSelect
        });
      }));
    }));
  };

  var renderStepper = function renderStepper() {
    return props.skuStepper || /*#__PURE__*/_react.default.createElement(_SkuStepper.default, {
      currentNum: state.selectedNum,
      onChange: function onChange(currentValue) {
        updateState({
          selectedNum: parseInt("" + currentValue, 10)
        });
        if (props.onStepperChange) props.onStepperChange(currentValue);
      },
      stock: stock,
      quota: props.quota,
      quotaUsed: props.quotaUsed,
      startSaleNum: props.startSaleNum,
      disableStepperInput: props.disableStepperInput,
      customStepperConfig: props.customStepperConfig,
      stepperTitle: props.stepperTitle,
      hideQuotaText: props.hideQuotaText,
      onSkuStepperState: onStepperState,
      onSkuOverLimit: onOverLimit
    });
  };

  var renderBody = function renderBody() {
    return /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('body')),
      style: bodyStyle
    }, props.skuBodyTop, renderGroup(), props.skuGroupExtra, renderStepper());
  };

  var renderActions = function renderActions() {
    return props.skuActions || /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('actions'))
    }, /*#__PURE__*/_react.default.createElement(_actionBar.default, null, props.showAddCartBtn && /*#__PURE__*/_react.default.createElement(_actionBar.default.Button, {
      type: "warning",
      text: props.addCartText || '加入购物车',
      onClick: function onClick() {
        return onBuyOrAddCart('add-cart');
      }
    }), /*#__PURE__*/_react.default.createElement(_actionBar.default.Button, {
      type: "danger",
      text: props.buyText || '立即购买',
      onClick: function onClick() {
        return onBuyOrAddCart('buy-clicked');
      }
    })));
  };

  (0, _react.useEffect)(function () {
    if (props.initialSku) {
      updateState(props.initialSku);
    }
  }, [JSON.stringify(props.initialSku)]);
  (0, _react.useImperativeHandle)(ref, function () {
    return {
      reset: reset,
      getSkuData: getSkuData,
      show: show,
      update: updateState
    };
  });
  return /*#__PURE__*/_react.default.createElement(_popup.Popup, _extends({
    round: true,
    closeable: true,
    position: "bottom"
  }, props.popupProps, {
    visible: visible,
    onClose: onPopupClose,
    onClosed: onPopupClosed,
    className: (0, _clsx.default)((_props$popupProps = props.popupProps) == null ? void 0 : _props$popupProps.className, bem('container'))
  }), renderHeader(), renderBody(), props.skuActionsTop, renderActions(), props.skuActionsBottom);
}); // defaultProps defined if need

Sku.defaultProps = {
  stepperTitle: '购买数量',
  properties: [],
  showAddCartBtn: true,
  disableSoldoutSku: true,
  showHeaderImage: true,
  previewOnClickImage: true,
  showSoldoutSku: true,
  resetOnHide: true,
  safeAreaInsetBottom: true,
  quota: 0,
  quotaUsed: 0,
  startSaleNum: 1,
  stockThreshold: 50,
  bodyOffsetTop: 200,
  customStepperConfig: {}
};
var _default = Sku;
exports.default = _default;