"use strict";

var _typeof = require("@babel/runtime-corejs3/helpers/typeof");
var _WeakMap = require("@babel/runtime-corejs3/core-js-stable/weak-map");
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.contextMenu = contextMenu;
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _react = _interopRequireWildcard(require("react"));
var _reactDom = _interopRequireDefault(require("react-dom"));
var _classnames = _interopRequireDefault(require("classnames"));
var _commonViews = require("../../common-views");
var _utils = require("../../utils");
var _others = require("../../utils/others");
var _internals = require("../../internals");
var _styles = require("../../base/styles");
function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && _Object$getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function contextMenu() {
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  return function step(pipeline) {
    var popupParent = opts.popupParent || document.body;
    var menuClassName = opts.menuClassName;
    var menuHelper = new MenuHelper();
    var addPopup = function addPopup(menu) {
      var ePopupDiv = document.createElement('div');
      ePopupDiv.setAttribute('class', 'kd-table-popup');
      popupParent.appendChild(ePopupDiv);
      var popupHidden = false;
      var eventList = ['mousedown', 'contextmenu'];
      var _hidePopup2 = function hidePopup(event) {
        if (isEventFromCurrentPopup(event, ePopupDiv) || popupHidden) {
          return;
        }
        popupHidden = true;
        popupParent.removeChild(ePopupDiv);
        eventList.forEach(function (eventType) {
          window.removeEventListener(eventType, _hidePopup2, true);
        });
      };
      _reactDom.default.render(menu, ePopupDiv, function () {
        setTimeout(function () {
          eventList.forEach(function (eventType) {
            window.addEventListener(eventType, _hidePopup2, true);
          });
        }, 0);
      });
      return _hidePopup2;
    };
    var onContextMenu = function onContextMenu(e) {
      if (canShowContextMenu(e, pipeline)) {
        e.preventDefault();
        e.stopPropagation();
        showContextMenu(e);
      }
    };
    pipeline.addTableProps({
      onContextMenu: onContextMenu
    });
    var getContextMenuOptions = function getContextMenuOptions(record, column, value, event) {
      var defaultMenuOptions = [];
      if (column) {
        defaultMenuOptions.push(getCopyItem(value));
      }
      if (opts.getContextMenuItems) {
        var params = {
          record: record,
          column: column,
          value: value,
          event: event
        };
        return opts.getContextMenuItems(params);
      }
      return defaultMenuOptions;
    };
    var hideContextMenu = function hideContextMenu() {
      menuHelper.destroy();
    };
    var getPopupParent = function getPopupParent() {
      return popupParent;
    };
    var showContextMenu = function showContextMenu(e) {
      var path = (0, _utils.getEventPath)(e);
      var cellEle = getCellEleInEventPath(path);
      var code;
      var rowIndex;
      var isInFooter;
      if (cellEle) {
        code = cellEle.getAttribute('data-code');
        rowIndex = cellEle.getAttribute('data-rowindex');
        isInFooter = isElementInsideTheFooter(cellEle);
      } else {
        var rowEle = getRowEleInEventPath(path);
        rowIndex = rowEle === null || rowEle === void 0 ? void 0 : rowEle.getAttribute('data-rowindex');
        isInFooter = isElementInsideTheFooter(rowEle);
      }
      var dataSource = isInFooter ? pipeline.getFooterDataSource() || [] : pipeline.getDataSource();
      var record = dataSource[rowIndex];
      var column = code !== undefined && (0, _others.findByTree)(pipeline.getColumns(), function (item) {
        return item.code === code;
      });
      var value = column && record && _internals.internals.safeGetValue(column, record, rowIndex);
      var options = getContextMenuOptions(record, column, value, e);
      if (options.length === 0) {
        _utils.console.warn('context menu options is empty');
        return;
      }
      var position = positionForMenu(e, popupParent);
      var menu = /*#__PURE__*/_react.default.createElement(Menu, {
        options: options,
        hideContextMenu: hideContextMenu,
        position: position,
        getPopupParent: getPopupParent,
        className: menuClassName,
        direction: pipeline.ctx.direction
      });
      var _hidePopup = addPopup(menu);
      menuHelper.init(_hidePopup);
    };
    return pipeline;
  };
}
function getMenuItemKey(_ref) {
  var name = _ref.name,
    index = _ref.index;
  if (name) {
    var _context;
    var _key = 0;
    name = name + '';
    for (var i = 0; i < name.length; i++) {
      _key += name.charCodeAt(name[i]);
    }
    return (0, _concat.default)(_context = "".concat(_key, "_")).call(_context, index);
  }
  return index;
}
function Menu(props) {
  var className = props.className,
    _props$options = props.options,
    options = _props$options === void 0 ? [] : _props$options,
    hideContextMenu = props.hideContextMenu,
    position = props.position,
    getPopupParent = props.getPopupParent;
  var menuRef = (0, _react.useRef)();
  (0, _react.useLayoutEffect)(function () {
    if (menuRef.current) {
      var popupParent = getPopupParent();
      var x = position.x,
        y = position.y;
      var isRTL = props.direction === 'rtl';
      if (isRTL) {
        x -= menuRef.current.offsetWidth;
      }
      var _keepWithinBounds = keepWithinBounds(popupParent, menuRef.current, x, y),
        _x = _keepWithinBounds.x,
        _y = _keepWithinBounds.y;
      menuRef.current.style.left = _x + 'px';
      menuRef.current.style.top = _y + 'px';
    }
  }, [position, props.direction]);
  return /*#__PURE__*/_react.default.createElement(_commonViews.ContextMenuStyleWrap, {
    className: (0, _classnames.default)(_styles.MenuClasses.menu, className),
    ref: menuRef,
    style: {
      left: position.x,
      top: position.y
    }
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: _styles.MenuClasses.menuList
  }, (0, _map.default)(options).call(options, function (item, index) {
    return /*#__PURE__*/_react.default.createElement(MenuItem, {
      key: item.key ? item.key : getMenuItemKey({
        name: item.name,
        index: index
      }),
      name: item.name,
      action: item.action,
      className: item.className,
      disabled: item.disabled,
      hideContextMenu: hideContextMenu
    });
  })));
}
function MenuItem(props) {
  var name = props.name,
    action = props.action,
    className = props.className,
    disabled = props.disabled,
    hideContextMenu = props.hideContextMenu;
  var itemRef = (0, _react.useRef)();
  var handleClick = function handleClick() {
    if (disabled) {
      return;
    }
    hideContextMenu();
    typeof action === 'function' && action();
  };
  var handleMouseEnter = function handleMouseEnter(e) {
    if (disabled) {
      return;
    }
    var itemDom = itemRef.current;
    if (itemDom) {
      itemDom.classList.add(_styles.MenuClasses.menuOptionActive);
    }
  };
  var handleMouseLeave = function handleMouseLeave(e) {
    if (disabled) {
      return;
    }
    var itemDom = itemRef.current;
    if (itemDom) {
      setTimeout(function () {
        itemDom.classList.remove(_styles.MenuClasses.menuOptionActive);
      }, 10);
    }
  };
  return /*#__PURE__*/_react.default.createElement("div", {
    className: (0, _classnames.default)(_styles.MenuClasses.menuOption, className, (0, _defineProperty2.default)({}, _styles.MenuClasses.menuOptionDisable, disabled)),
    ref: itemRef,
    onClick: handleClick,
    onMouseEnter: handleMouseEnter,
    onMouseLeave: handleMouseLeave
  }, /*#__PURE__*/_react.default.createElement("span", {
    className: _styles.MenuClasses.menuOptionText
  }, name));
}
var MenuHelper = /*#__PURE__*/(0, _createClass2.default)(function MenuHelper() {
  var _this = this;
  (0, _classCallCheck2.default)(this, MenuHelper);
  this.init = function (hidePopup) {
    _this.hidePopup = hidePopup;
  };
  this.destroy = function () {
    _this.hidePopup && _this.hidePopup();
    _this.hidePopup = null;
  };
});
/** 是否点击是外部 start */
function isEventFromCurrentPopup(event, ele) {
  if (!event || !ele) {
    return false;
  }
  if ((0, _utils.isElementInEventPath)(ele, event)) {
    return true;
  }
  return false;
}
/** 是否点击是外部 end */
/** 计算位置 start */
function calculatePointerRelative(event, popupParent) {
  var parentRect = popupParent.getBoundingClientRect();
  var documentRect = document.documentElement.getBoundingClientRect();
  return {
    x: event.clientX - (popupParent === document.body ? documentRect.left : parentRect.left),
    y: event.clientY - (popupParent === document.body ? documentRect.top : parentRect.top)
  };
}
function positionForMenu(event, popupParent, params) {
  var _calculatePointerRela = calculatePointerRelative(event, popupParent),
    x = _calculatePointerRela.x,
    y = _calculatePointerRela.y;
  if (params) {
    var offsetX = params.offsetX,
      offsetY = params.offsetY;
    if (offsetX) {
      x -= offsetX;
    }
    if (offsetY) {
      y -= offsetY;
    }
  }
  return {
    x: x,
    y: y
  };
}
function keepWithinBounds(popupParent, ePopup, x, y) {
  var parentRect = popupParent.getBoundingClientRect();
  var docElement = document.documentElement;
  var documentRect = docElement.getBoundingClientRect();
  var ePopupRect = ePopup.getBoundingClientRect();
  var parentWidth = parentRect.width;
  var parentHeight = parentRect.height;
  if (popupParent === document.body) {
    parentWidth = documentRect.width;
    parentWidth -= Math.abs(documentRect.left - parentRect.left);
    parentHeight = documentRect.height + docElement.scrollTop;
    parentHeight -= Math.abs(documentRect.top - parentRect.top);
  }
  if (x) {
    var minWidth = Math.min(ePopupRect.width, 120);
    ePopup.style.minWidth = minWidth + 'px';
    var maxX = parentWidth - minWidth;
    x = Math.min(Math.max(x, 0), Math.abs(maxX)); // 目前位置，最大支持的位置
  }
  if (y) {
    var maxY = parentHeight - ePopupRect.height;
    y = Math.min(Math.max(y, 0), Math.abs(maxY)); // 目前位置，最大支持的位置
  }
  return {
    x: x,
    y: y
  };
}
/** 计算位置 end */
/** 获得点击的元素 start */
function getCellEleInEventPath(path) {
  return (0, _utils.getTargetEleInEventPath)(path, function (ele) {
    return ele && ele.getAttribute('data-role') === 'table-cell';
  });
}
function getRowEleInEventPath(path) {
  return (0, _utils.getTargetEleInEventPath)(path, function (ele) {
    return ele && ele.getAttribute('data-role') === 'table-row';
  });
}
/** 获得点击的元素 end */
function isElementInsideTheFooter(ele) {
  var pointer = ele;
  while (pointer) {
    if (pointer.tagName === 'TFOOT') {
      return true;
    }
    if (pointer.tagName === 'TABLE' || pointer.tagName === 'TBODY') {
      return false;
    }
    pointer = pointer.parentElement;
  }
  return false;
}
function canShowContextMenu(e, pipeline) {
  var _a, _b;
  return ((_a = pipeline.ref.current.domHelper) === null || _a === void 0 ? void 0 : _a.tableBody.contains(e.target)) || ((_b = pipeline.ref.current.domHelper) === null || _b === void 0 ? void 0 : _b.tableFooter.contains(e.target));
}
// 默认选项
function getCopyItem(v) {
  return {
    name: '复制',
    action: function action() {
      (0, _utils.executeOnTempElement)((0, _utils.copyDataToClipboard)(v));
    }
  };
}