"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.RenderTableRow = exports.RenderTableCell = void 0;
var _react = _interopRequireWildcard(require("react"));
var _slateReact = require("slate-react");
var _slate = require("slate");
var _constant = require("../constant");
var _contextMenu = _interopRequireDefault(require("../context-menu"));
var _helper = require("../helper");
var _core = require("../../../core");
var _constants = require("../../../constants");
var _eventBus = _interopRequireDefault(require("../../../../utils/event-bus"));
var _eventTypes = require("../../../../constants/event-types");
require("./style.css");
const RenderTableContainer = (_ref, editor) => {
  let {
    attributes,
    children,
    element
  } = _ref;
  const tableRef = (0, _react.useRef)(null);
  const startGridRef = (0, _react.useRef)({
    rowIndex: -1,
    colIndex: -1
  });
  const [isShowContextMenu, setIsShowContextMenu] = (0, _react.useState)(false);
  const [contextMenuPosition, setContextMenuPosition] = (0, _react.useState)({
    top: 0,
    left: 0
  });
  const [, setSelectGridRange] = (0, _react.useState)({
    startRowIndex: -1,
    startColIndex: -1,
    endRowIndex: -1,
    endColIndex: -1
  });
  const isReadonly = (0, _slateReact.useReadOnly)();
  (0, _react.useEffect)(() => {
    if (isReadonly) return;
    clearSelectedCells();
    document.addEventListener('contextmenu', handleContextMenu, true);
    document.addEventListener('mousedown', handleOutsideMouseDown);
    const eventBus = _eventBus.default.getInstance();
    const unSubscribe = eventBus.subscribe(_eventTypes.INTERNAL_EVENTS.ON_SELECT_ALL_CELL, handleSelectAllCells);
    return () => {
      document.removeEventListener('contextmenu', handleContextMenu, true);
      document.removeEventListener('mousedown', handleOutsideMouseDown);
      unSubscribe();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  const getTableElement = (0, _react.useCallback)((node, type) => {
    var _target$nodeName;
    let target = node;
    if (((_target$nodeName = target.nodeName) === null || _target$nodeName === void 0 ? void 0 : _target$nodeName.toLowerCase()) === type) return target;
    while (target.nodeName && ((_target$nodeName2 = target.nodeName) === null || _target$nodeName2 === void 0 ? void 0 : _target$nodeName2.toLowerCase()) !== type) {
      var _target$nodeName2;
      target = target.parentNode;
    }
    return target;
  }, []);
  const clearSelectedCells = (0, _react.useCallback)(e => {
    var _document$querySelect, _tableRef$current;
    handleCloseContextMenu();
    // Keep selecting when using alignment tool
    const isTriggerByAlignmentTool = (_document$querySelect = document.querySelector('.sf-table-operations-group')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.contains(e === null || e === void 0 ? void 0 : e.target);
    if (isTriggerByAlignmentTool) return;
    (_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.querySelectorAll('.selected-cell').forEach(selectedCell => {
      selectedCell.classList.remove('selected-cell', 'selected-cell-left', 'selected-cell-bottom', 'selected-cell-top', 'selected-cell-right');
    });
  }, []);
  const updateSelectedCellStyles = (0, _react.useCallback)((startRowIndex, endRowIndex, startColIndex, endColIndex) => {
    clearSelectedCells();
    if (startColIndex < 0 || startRowIndex < 0) return;
    for (let rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
      let currentRow = tableRef.current.querySelectorAll(_constant.TABLE_ROW_NODE_NAME)[rowIndex];
      for (let colIndex = startColIndex; colIndex <= endColIndex; colIndex++) {
        const selectedCell = currentRow.querySelectorAll(_constant.TABLE_CELL_NODE_NAME)[colIndex];
        selectedCell.classList.add('selected-cell');
        // Set selected cell border
        rowIndex === startRowIndex && selectedCell.classList.add('selected-cell-top');
        colIndex === startColIndex && selectedCell.classList.add('selected-cell-left');
        colIndex === endColIndex && selectedCell.classList.add('selected-cell-right');
        rowIndex === endRowIndex && selectedCell.classList.add('selected-cell-bottom');
      }
    }
    setSelectGridRange({
      startRowIndex,
      endRowIndex,
      startColIndex,
      endColIndex
    });
  }, [clearSelectedCells]);
  const handleSelectAllCells = (0, _react.useCallback)(tableId => {
    if (tableId !== element.id) return;
    const startRowIndex = 0;
    const startColIndex = 0;
    const endRowIndex = element.children.length - 1;
    const endColIndex = element.children[0].children.length - 1;
    updateSelectedCellStyles(startRowIndex, endRowIndex, startColIndex, endColIndex);
  }, [element.children, element.id, updateSelectedCellStyles]);

  // select table cells
  const handleMouseMove = (0, _react.useCallback)(e => {
    var _e$target$nodeName;
    // Check if the target is in the table
    if (((_e$target$nodeName = e.target.nodeName) === null || _e$target$nodeName === void 0 ? void 0 : _e$target$nodeName.toLowerCase()) === _constant.TABLE_BODY_NODE_NAME || !tableRef.current.contains(e.target)) return;
    // Figure out select range
    const {
      startRowIndex,
      startColIndex
    } = startGridRef.current;
    const endRowIndex = getTableElement(e.target, _constant.TABLE_ROW_NODE_NAME).rowIndex;
    const endColIndex = getTableElement(e.target, _constant.TABLE_CELL_NODE_NAME).cellIndex;
    const minRowIndex = Math.min(startRowIndex, endRowIndex);
    const maxRowIndex = Math.max(startRowIndex, endRowIndex);
    const minColIndex = Math.min(startColIndex, endColIndex);
    const maxColIndex = Math.max(startColIndex, endColIndex);
    // Select one cell
    if (minRowIndex === maxRowIndex && minColIndex === maxColIndex) return;

    // collapse selection
    window.getSelection().collapseToEnd();
    updateSelectedCellStyles(minRowIndex, maxRowIndex, minColIndex, maxColIndex);
  }, [getTableElement, updateSelectedCellStyles]);

  // end select table cells
  const handleMouseUp = (0, _react.useCallback)(e => {
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);
  }, [handleMouseMove]);
  const handleMouseDown = (0, _react.useCallback)(e => {
    var _e$target$nodeName2;
    if (e.button !== 0) return;
    if (((_e$target$nodeName2 = e.target.nodeName) === null || _e$target$nodeName2 === void 0 ? void 0 : _e$target$nodeName2.toLowerCase()) === _constant.TABLE_BODY_NODE_NAME || !tableRef.current.contains(e.target)) return;
    // Clear last rendered styles
    clearSelectedCells();
    // Set new select range
    const startRowIndex = getTableElement(e.target, _constant.TABLE_ROW_NODE_NAME).rowIndex;
    const startColIndex = getTableElement(e.target, _constant.TABLE_CELL_NODE_NAME).cellIndex;
    startGridRef.current = {
      startRowIndex: startRowIndex,
      startColIndex: startColIndex
    };

    // begin select table cells
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  }, [clearSelectedCells, getTableElement, handleMouseMove, handleMouseUp]);
  const handleOutsideMouseDown = (0, _react.useCallback)(e => {
    if (e.button !== 0) return;
    clearSelectedCells();
  }, [clearSelectedCells]);
  const handleContextMenu = (0, _react.useCallback)(e => {
    if (!tableRef.current.contains(e.target)) {
      handleCloseContextMenu();
      return;
    }
    e.preventDefault();
    e.stopPropagation();
    const position = (0, _helper.getContextMenuPosition)(e, tableRef);
    setContextMenuPosition(position);
    setIsShowContextMenu(true);
  }, []);
  const handleCloseContextMenu = () => {
    setIsShowContextMenu(false);
  };
  return /*#__PURE__*/_react.default.createElement("div", {
    style: {
      position: 'relative'
    },
    "data-id": element.id
  }, /*#__PURE__*/_react.default.createElement("table", {
    ref: tableRef,
    onMouseDown: handleMouseDown,
    className: "sf-table-container"
  }, /*#__PURE__*/_react.default.createElement("tbody", attributes, children)), isShowContextMenu && /*#__PURE__*/_react.default.createElement(_contextMenu.default, {
    element: element,
    handleCloseContextMenu: handleCloseContextMenu,
    position: contextMenuPosition,
    editor: editor
  }));
};
var _default = exports.default = RenderTableContainer;
const RenderTableRow = _ref2 => {
  let {
    attributes,
    children,
    element
  } = _ref2;
  return /*#__PURE__*/_react.default.createElement("tr", Object.assign({}, attributes, {
    "data-id": element.id
  }), children);
};
exports.RenderTableRow = RenderTableRow;
const RenderTableCell = _ref3 => {
  let {
    attributes,
    children,
    element
  } = _ref3;
  const editor = (0, _slateReact.useSlateStatic)();
  const cellPath = (0, _core.findPath)(editor, element, [0, 0]);
  const pathLength = cellPath.length;
  const cellIndex = cellPath[pathLength - 1];
  const rowEntry = _slate.Editor.parent(editor, cellPath);
  const tableEntry = _slate.Editor.parent(editor, rowEntry[1]);
  const table = tableEntry[0];
  let style = {};
  if (table.align && Array.isArray(table.align)) {
    style['textAlign'] = table.align[cellIndex] || _constants.TEXT_ALIGN.LEFT;
  } else {
    style['textAlign'] = _constants.TEXT_ALIGN.LEFT;
  }
  return /*#__PURE__*/_react.default.createElement("td", Object.assign({
    "data-root": "true",
    "data-id": element.id,
    style: style
  }, attributes), children);
};
exports.RenderTableCell = RenderTableCell;