"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.NoticeList = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _vue = require("vue");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classNames = _interopRequireDefault(require("../_util/classNames"));
var _Notice = _interopRequireDefault(require("./Notice"));
const DEFAULT_OFFSET = 8;
const DEFAULT_THRESHOLD = 3;
const DEFAULT_GAP = 16;
const NoticeList = exports.NoticeList = (0, _vue.defineComponent)({
  name: 'NoticeList',
  inheritAttrs: false,
  props: ['configList', 'notices', 'placement', 'prefixCls', 'closeIcon', 'onClose', 'hashId', 'getStyles', 'onAfterLeave', 'transitionProps', 'wrapperClassName', 'wrapperStyle', 'stack'],
  setup(props) {
    const dictRef = (0, _vue.reactive)({});
    const latestNotice = (0, _vue.ref)(null);
    const hoverKeys = (0, _vue.ref)([]);
    const ins = (0, _vue.getCurrentInstance)();
    const stackConfig = (0, _vue.computed)(() => {
      var _a, _b, _c;
      const result = {
        offset: DEFAULT_OFFSET,
        threshold: DEFAULT_THRESHOLD,
        gap: DEFAULT_GAP
      };
      if (props.stack && typeof props.stack === 'object') {
        result.offset = (_a = props.stack.offset) !== null && _a !== void 0 ? _a : DEFAULT_OFFSET;
        result.threshold = (_b = props.stack.threshold) !== null && _b !== void 0 ? _b : DEFAULT_THRESHOLD;
        result.gap = (_c = props.stack.gap) !== null && _c !== void 0 ? _c : DEFAULT_GAP;
      }
      return result;
    });
    const keys = (0, _vue.computed)(() => props.configList.map(config => ({
      config,
      key: String(config.notice.key)
    })));
    const stack = (0, _vue.computed)(() => !!props.stack);
    // force update when stack change to make transform work.
    (0, _vue.watch)(stack, nextStack => {
      if (nextStack) {
        (0, _vue.nextTick)(() => {
          ins.proxy.$forceUpdate();
        });
      }
    });
    const expanded = (0, _vue.computed)(() => stack.value && (hoverKeys.value.length > 0 || keys.value.length <= stackConfig.value.threshold));
    // Clean hover key
    (0, _vue.watchEffect)(() => {
      if (stack.value && hoverKeys.value.length > 1) {
        hoverKeys.value = hoverKeys.value.filter(key => keys.value.some(_ref => {
          let {
            key: dataKey
          } = _ref;
          return key === dataKey;
        }));
      }
    });
    (0, _vue.watchEffect)(() => {
      var _a;
      const _latestNotice = dictRef[(_a = keys.value[keys.value.length - 1]) === null || _a === void 0 ? void 0 : _a.key];
      if (stack.value && _latestNotice) {
        latestNotice.value = _latestNotice;
      }
    });
    const addHoverKey = strKey => {
      const rawHoverKeys = (0, _vue.unref)(hoverKeys);
      if (rawHoverKeys.includes(strKey)) {
        return;
      }
      hoverKeys.value = [...rawHoverKeys, strKey];
    };
    const removeHoverKey = strKey => {
      hoverKeys.value = (0, _vue.unref)(hoverKeys).filter(key => key !== strKey);
    };
    function strToNumber(str) {
      if (!str) {
        return;
      }
      return Number(str);
    }
    return () => {
      var _a;
      const noticeNodesForPlacement = props.configList.map((_ref2, index) => {
        let {
          notice,
          holderCallback
        } = _ref2;
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        const {
          key,
          userPassKey
        } = notice;
        const strKey = String(key);
        const {
          content
        } = notice;
        const updateMark = index === props.notices.length - 1 ? notice.updateMark : undefined;
        const dataIndex = keys.value.findIndex(item => item.key === strKey);
        const noticeProps = (0, _extends2.default)((0, _extends2.default)((0, _extends2.default)({
          prefixCls: props.prefixCls,
          closeIcon: typeof props.closeIcon === 'function' ? props.closeIcon({
            prefixCls: props.prefixCls
          }) : props.closeIcon
        }, notice), notice.props), {
          key,
          noticeKey: userPassKey || key,
          updateMark,
          onClose: noticeKey => {
            var _a, _b;
            (_a = props.onClose) === null || _a === void 0 ? void 0 : _a.call(props, noticeKey);
            (_b = notice.onClose) === null || _b === void 0 ? void 0 : _b.call(notice);
          },
          onClick: notice.onClick
        });
        const stackStyle = {};
        if (stack.value) {
          const index = keys.value.length - 1 - dataIndex;
          const transformX = props.placement === 'top' || props.placement === 'bottom' ? '-50%' : '0';
          const {
            gap,
            offset
          } = (0, _vue.unref)(stackConfig);
          if (index > 0) {
            const realHeight = ((_a = dictRef[strKey]) === null || _a === void 0 ? void 0 : _a.dataset.originalHeight) || ((_b = dictRef[strKey]) === null || _b === void 0 ? void 0 : _b.offsetHeight);
            stackStyle.height = expanded.value ? `${realHeight}px` : `${(_c = latestNotice.value) === null || _c === void 0 ? void 0 : _c.offsetHeight}px`;
            // Transform
            let verticalOffset = 0;
            for (let i = 0; i < index; i++) {
              const key = keys.value[keys.value.length - 1 - i].key;
              const elementRealHeight = strToNumber((_d = dictRef[key]) === null || _d === void 0 ? void 0 : _d.dataset.originalHeight) || ((_e = dictRef[key]) === null || _e === void 0 ? void 0 : _e.offsetHeight) || 0;
              verticalOffset += elementRealHeight + gap;
            }
            const transformY = (expanded.value ? verticalOffset : index * offset) * (props.placement.startsWith('top') ? 1 : -1);
            const scaleX = !expanded.value && ((_f = latestNotice.value) === null || _f === void 0 ? void 0 : _f.offsetWidth) && ((_g = dictRef[strKey]) === null || _g === void 0 ? void 0 : _g.offsetWidth) ? (((_h = latestNotice.value) === null || _h === void 0 ? void 0 : _h.offsetWidth) - offset * 2 * (index < 3 ? index : 3)) / ((_j = dictRef[strKey]) === null || _j === void 0 ? void 0 : _j.offsetWidth) : 1;
            stackStyle.transform = `translate3d(${transformX}, ${transformY}px, 0) scaleX(${scaleX}) !important`;
          } else {
            stackStyle.transform = `translate3d(${transformX}, 0, 0)`;
          }
        }
        if (holderCallback) {
          return (0, _vue.createVNode)("div", {
            "key": key,
            "class": `${props.prefixCls}-hook-holder`,
            "ref": div => {
              if (typeof key === 'undefined') {
                return;
              }
              if (div) {
                holderCallback(div, noticeProps);
              }
            }
          }, null);
        }
        return (0, _vue.createVNode)(_Notice.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, noticeProps), {}, {
          "style": stackStyle,
          "class": (0, _classNames.default)(noticeProps.class, props.hashId, `${props.prefixCls}-notice-wrapper`),
          "ref": node => {
            const root = node === null || node === void 0 ? void 0 : node.rootRef;
            if (root) {
              if (root !== dictRef[strKey]) {
                root.dataset.originalHeight = root.offsetHeight;
                dictRef[strKey] = root;
              }
            } else {
              delete dictRef[strKey];
            }
          },
          "onMouseenter": () => addHoverKey(strKey),
          "onMouseleave": () => removeHoverKey(strKey)
        }), {
          default: () => [typeof content === 'function' ? content({
            prefixCls: props.prefixCls
          }) : content]
        });
      });
      const styles = (_a = props.getStyles) === null || _a === void 0 ? void 0 : _a.call(props, props.placement);
      const mergedClassName = (0, _classNames.default)(props.wrapperClassName, {
        [`${props.prefixCls}-stack`]: !!stack.value,
        [`${props.prefixCls}-stack-expanded`]: expanded.value
      });
      return (0, _vue.createVNode)("div", {
        "key": props.placement,
        "class": mergedClassName,
        "style": props.wrapperStyle || styles || {
          top: '65px',
          left: '50%'
        }
      }, [(0, _vue.createVNode)(_vue.TransitionGroup, (0, _objectSpread2.default)((0, _objectSpread2.default)({
        "tag": "div"
      }, props.transitionProps), {}, {
        "onAfterLeave": props.onAfterLeave
      }), {
        default: () => [noticeNodesForPlacement]
      })]);
    };
  }
});