'use client';

import { c as _c } from "react/compiler-runtime";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
import { $deleteTableColumn__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL, $getNodeTriplet, $getTableCellNodeFromLexicalNode, $getTableColumnIndexFromTableCellNode, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $insertTableColumn__EXPERIMENTAL, $insertTableRow__EXPERIMENTAL, $isTableCellNode, $isTableRowNode, $isTableSelection, $unmergeCell, getTableObserverFromTableElement, TableCellHeaderStates, TableCellNode } from '@lexical/table';
import { useScrollInfo } from '@payloadcms/ui';
import { $createParagraphNode, $getRoot, $getSelection, $isElementNode, $isParagraphNode, $isRangeSelection, $isTextNode } from 'lexical';
import * as React from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { MeatballsIcon } from '../../../../../lexical/ui/icons/Meatballs/index.js';
function computeSelectionCount(selection) {
  const selectionShape = selection.getShape();
  return {
    columns: selectionShape.toX - selectionShape.fromX + 1,
    rows: selectionShape.toY - selectionShape.fromY + 1
  };
}
function $canUnmerge() {
  const selection = $getSelection();
  if ($isRangeSelection(selection) && !selection.isCollapsed() || $isTableSelection(selection) && !selection.anchor.is(selection.focus) || !$isRangeSelection(selection) && !$isTableSelection(selection)) {
    return false;
  }
  const [cell] = $getNodeTriplet(selection.anchor);
  return cell.__colSpan > 1 || cell.__rowSpan > 1;
}
function $cellContainsEmptyParagraph(cell) {
  if (cell.getChildrenSize() !== 1) {
    return false;
  }
  const firstChild = cell.getFirstChildOrThrow();
  if (!$isParagraphNode(firstChild) || !firstChild.isEmpty()) {
    return false;
  }
  return true;
}
function $selectLastDescendant(node) {
  const lastDescendant = node.getLastDescendant();
  if ($isTextNode(lastDescendant)) {
    lastDescendant.select();
  } else if ($isElementNode(lastDescendant)) {
    lastDescendant.selectEnd();
  } else if (lastDescendant !== null) {
    lastDescendant.selectNext();
  }
}
function TableActionMenu({
  cellMerge,
  contextRef,
  onClose,
  setIsMenuOpen,
  tableCellNode: _tableCellNode
}) {
  const [editor] = useLexicalComposerContext();
  const dropDownRef = useRef(null);
  const [tableCellNode, updateTableCellNode] = useState(_tableCellNode);
  const [selectionCounts, updateSelectionCounts] = useState({
    columns: 1,
    rows: 1
  });
  const [canMergeCells, setCanMergeCells] = useState(false);
  const [canUnmergeCell, setCanUnmergeCell] = useState(false);
  const {
    y
  } = useScrollInfo();
  useEffect(() => {
    return editor.registerMutationListener(TableCellNode, nodeMutations => {
      const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === 'updated';
      if (nodeUpdated) {
        editor.getEditorState().read(() => {
          updateTableCellNode(tableCellNode.getLatest());
        });
      }
    }, {
      skipInitialization: true
    });
  }, [editor, tableCellNode]);
  useEffect(() => {
    editor.getEditorState().read(() => {
      const selection = $getSelection();
      // Merge cells
      if ($isTableSelection(selection)) {
        const currentSelectionCounts = computeSelectionCount(selection);
        updateSelectionCounts(computeSelectionCount(selection));
        setCanMergeCells(currentSelectionCounts.columns > 1 || currentSelectionCounts.rows > 1);
      }
      // Unmerge cell
      setCanUnmergeCell($canUnmerge());
    });
  }, [editor]);
  useEffect(() => {
    const menuButtonElement = contextRef.current;
    const dropDownElement = dropDownRef.current;
    const rootElement = editor.getRootElement();
    if (menuButtonElement != null && dropDownElement != null && rootElement != null) {
      const rootEleRect = rootElement.getBoundingClientRect();
      const menuButtonRect = menuButtonElement.getBoundingClientRect();
      dropDownElement.style.opacity = '1';
      const dropDownElementRect = dropDownElement.getBoundingClientRect();
      const margin = 5;
      let leftPosition = menuButtonRect.right + margin;
      if (leftPosition + dropDownElementRect.width > window.innerWidth || leftPosition + dropDownElementRect.width > rootEleRect.right) {
        const position = menuButtonRect.left - dropDownElementRect.width - margin;
        leftPosition = (position < 0 ? margin : position) + window.pageXOffset;
      }
      dropDownElement.style.left = `${leftPosition + window.pageXOffset}px`;
      let topPosition = menuButtonRect.top;
      if (topPosition + dropDownElementRect.height > window.innerHeight) {
        const position_0 = menuButtonRect.bottom - dropDownElementRect.height;
        topPosition = (position_0 < 0 ? margin : position_0) + window.pageYOffset;
      }
      dropDownElement.style.top = `${topPosition}px`;
    }
  }, [contextRef, dropDownRef, editor, y]);
  useEffect(() => {
    function handleClickOutside(event) {
      if (dropDownRef.current != null && contextRef.current != null && !dropDownRef.current.contains(event.target) && !contextRef.current.contains(event.target)) {
        setIsMenuOpen(false);
      }
    }
    window.addEventListener('click', handleClickOutside);
    return () => window.removeEventListener('click', handleClickOutside);
  }, [setIsMenuOpen, contextRef]);
  const clearTableSelection = useCallback(() => {
    editor.update(() => {
      if (tableCellNode.isAttached()) {
        const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
        const tableElement = editor.getElementByKey(tableNode.getKey());
        if (!tableElement) {
          throw new Error('Expected to find tableElement in DOM');
        }
        const tableObserver = getTableObserverFromTableElement(tableElement);
        if (tableObserver !== null) {
          tableObserver.clearHighlight();
        }
        tableNode.markDirty();
        updateTableCellNode(tableCellNode.getLatest());
      }
      const rootNode = $getRoot();
      rootNode.selectStart();
    });
  }, [editor, tableCellNode]);
  const mergeTableCellsAtSelection = () => {
    editor.update(() => {
      const selection_0 = $getSelection();
      if ($isTableSelection(selection_0)) {
        const {
          columns,
          rows
        } = computeSelectionCount(selection_0);
        const nodes = selection_0.getNodes();
        let firstCell = null;
        for (let i = 0; i < nodes.length; i++) {
          const node = nodes[i];
          if ($isTableCellNode(node)) {
            if (firstCell === null) {
              node.setColSpan(columns).setRowSpan(rows);
              firstCell = node;
              const isEmpty = $cellContainsEmptyParagraph(node);
              let firstChild;
              if (isEmpty && $isParagraphNode(firstChild = node.getFirstChild())) {
                firstChild.remove();
              }
            } else if ($isTableCellNode(firstCell)) {
              const isEmpty_0 = $cellContainsEmptyParagraph(node);
              if (!isEmpty_0) {
                firstCell.append(...node.getChildren());
              }
              node.remove();
            }
          }
        }
        if (firstCell !== null) {
          if (firstCell.getChildrenSize() === 0) {
            firstCell.append($createParagraphNode());
          }
          $selectLastDescendant(firstCell);
        }
        onClose();
      }
    });
  };
  const unmergeTableCellsAtSelection = () => {
    editor.update(() => {
      $unmergeCell();
    });
  };
  const insertTableRowAtSelection = useCallback(shouldInsertAfter => {
    editor.update(() => {
      $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
      onClose();
    });
  }, [editor, onClose]);
  const insertTableColumnAtSelection = useCallback(shouldInsertAfter_0 => {
    editor.update(() => {
      for (let i_0 = 0; i_0 < selectionCounts.columns; i_0++) {
        $insertTableColumn__EXPERIMENTAL(shouldInsertAfter_0);
      }
      onClose();
    });
  }, [editor, onClose, selectionCounts.columns]);
  const deleteTableRowAtSelection = useCallback(() => {
    editor.update(() => {
      $deleteTableRow__EXPERIMENTAL();
      onClose();
    });
  }, [editor, onClose]);
  const deleteTableAtSelection = useCallback(() => {
    editor.update(() => {
      const tableNode_0 = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
      tableNode_0.remove();
      clearTableSelection();
      onClose();
    });
  }, [editor, tableCellNode, clearTableSelection, onClose]);
  const deleteTableColumnAtSelection = useCallback(() => {
    editor.update(() => {
      $deleteTableColumn__EXPERIMENTAL();
      onClose();
    });
  }, [editor, onClose]);
  const toggleTableRowIsHeader = useCallback(() => {
    editor.update(() => {
      const tableNode_1 = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
      const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
      const tableRows = tableNode_1.getChildren();
      if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
        throw new Error('Expected table cell to be inside of table row.');
      }
      const tableRow = tableRows[tableRowIndex];
      if (!$isTableRowNode(tableRow)) {
        throw new Error('Expected table row');
      }
      const newStyle = tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.ROW;
      tableRow.getChildren().forEach(tableCell => {
        if (!$isTableCellNode(tableCell)) {
          throw new Error('Expected table cell');
        }
        tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.ROW);
      });
      clearTableSelection();
      onClose();
    });
  }, [editor, tableCellNode, clearTableSelection, onClose]);
  const toggleTableColumnIsHeader = useCallback(() => {
    editor.update(() => {
      const tableNode_2 = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
      const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
      const tableRows_0 = tableNode_2.getChildren();
      const maxRowsLength = Math.max(...tableRows_0.map(row => row.getChildren().length));
      if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {
        throw new Error('Expected table cell to be inside of table row.');
      }
      const newStyle_0 = tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.COLUMN;
      for (let r = 0; r < tableRows_0.length; r++) {
        const tableRow_0 = tableRows_0[r];
        if (!$isTableRowNode(tableRow_0)) {
          throw new Error('Expected table row');
        }
        const tableCells = tableRow_0.getChildren();
        if (tableColumnIndex >= tableCells.length) {
          continue;
        }
        const tableCell_0 = tableCells[tableColumnIndex];
        if (!$isTableCellNode(tableCell_0)) {
          throw new Error('Expected table cell');
        }
        tableCell_0.setHeaderStyles(newStyle_0, TableCellHeaderStates.COLUMN);
      }
      clearTableSelection();
      onClose();
    });
  }, [editor, tableCellNode, clearTableSelection, onClose]);
  const toggleRowStriping = useCallback(() => {
    editor.update(() => {
      if (tableCellNode.isAttached()) {
        const tableNode_3 = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
        if (tableNode_3) {
          tableNode_3.setRowStriping(!tableNode_3.getRowStriping());
        }
      }
      clearTableSelection();
      onClose();
    });
  }, [editor, tableCellNode, clearTableSelection, onClose]);
  let mergeCellButton = null;
  if (cellMerge) {
    if (canMergeCells) {
      mergeCellButton = /*#__PURE__*/_jsx("button", {
        className: "item",
        "data-test-id": "table-merge-cells",
        onClick: () => mergeTableCellsAtSelection(),
        type: "button",
        children: "Merge cells"
      });
    } else if (canUnmergeCell) {
      mergeCellButton = /*#__PURE__*/_jsx("button", {
        className: "item",
        "data-test-id": "table-unmerge-cells",
        onClick: () => unmergeTableCellsAtSelection(),
        type: "button",
        children: "Unmerge cells"
      });
    }
  }
  return /*#__PURE__*/createPortal(
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions,jsx-a11y/click-events-have-key-events
  /*#__PURE__*/
  _jsxs("div", {
    className: "table-action-menu-dropdown",
    onClick: e => {
      e.stopPropagation();
    },
    ref: dropDownRef,
    children: [mergeCellButton ? /*#__PURE__*/_jsxs(React.Fragment, {
      children: [mergeCellButton, /*#__PURE__*/_jsx("hr", {})]
    }) : null, /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-row-striping",
      onClick: () => toggleRowStriping(),
      type: "button",
      children: /*#__PURE__*/_jsx("span", {
        className: "text",
        children: "Toggle Row Striping"
      })
    }), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-insert-row-above",
      onClick: () => insertTableRowAtSelection(false),
      type: "button",
      children: /*#__PURE__*/_jsxs("span", {
        className: "text",
        children: ["Insert ", selectionCounts.rows === 1 ? 'row' : `${selectionCounts.rows} rows`, " above"]
      })
    }), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-insert-row-below",
      onClick: () => insertTableRowAtSelection(true),
      type: "button",
      children: /*#__PURE__*/_jsxs("span", {
        className: "text",
        children: ["Insert ", selectionCounts.rows === 1 ? 'row' : `${selectionCounts.rows} rows`, " below"]
      })
    }), /*#__PURE__*/_jsx("hr", {}), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-insert-column-before",
      onClick: () => insertTableColumnAtSelection(false),
      type: "button",
      children: /*#__PURE__*/_jsxs("span", {
        className: "text",
        children: ["Insert ", selectionCounts.columns === 1 ? 'column' : `${selectionCounts.columns} columns`, ' ', "left"]
      })
    }), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-insert-column-after",
      onClick: () => insertTableColumnAtSelection(true),
      type: "button",
      children: /*#__PURE__*/_jsxs("span", {
        className: "text",
        children: ["Insert ", selectionCounts.columns === 1 ? 'column' : `${selectionCounts.columns} columns`, ' ', "right"]
      })
    }), /*#__PURE__*/_jsx("hr", {}), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-delete-columns",
      onClick: () => deleteTableColumnAtSelection(),
      type: "button",
      children: /*#__PURE__*/_jsx("span", {
        className: "text",
        children: "Delete column"
      })
    }), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-delete-rows",
      onClick: () => deleteTableRowAtSelection(),
      type: "button",
      children: /*#__PURE__*/_jsx("span", {
        className: "text",
        children: "Delete row"
      })
    }), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-delete",
      onClick: () => deleteTableAtSelection(),
      type: "button",
      children: /*#__PURE__*/_jsx("span", {
        className: "text",
        children: "Delete table"
      })
    }), /*#__PURE__*/_jsx("hr", {}), /*#__PURE__*/_jsx("button", {
      className: "item",
      onClick: () => toggleTableRowIsHeader(),
      type: "button",
      children: /*#__PURE__*/_jsxs("span", {
        className: "text",
        children: [(tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? 'Remove' : 'Add', ' ', "row header"]
      })
    }), /*#__PURE__*/_jsx("button", {
      className: "item",
      "data-test-id": "table-column-header",
      onClick: () => toggleTableColumnIsHeader(),
      type: "button",
      children: /*#__PURE__*/_jsxs("span", {
        className: "text",
        children: [(tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? 'Remove' : 'Add', ' ', "column header"]
      })
    })]
  }), document.body);
}
function TableCellActionMenuContainer({
  anchorElem,
  cellMerge
}) {
  const [editor] = useLexicalComposerContext();
  const menuButtonRef = useRef(null);
  const menuRootRef = useRef(null);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [tableCellNode, setTableMenuCellNode] = useState(null);
  const $moveMenu = useCallback(() => {
    const menu = menuButtonRef.current;
    const selection = $getSelection();
    const nativeSelection = window.getSelection();
    const activeElement = document.activeElement;
    if (selection == null || menu == null) {
      setTableMenuCellNode(null);
      return;
    }
    const rootElement = editor.getRootElement();
    if ($isRangeSelection(selection) && rootElement !== null && nativeSelection !== null && rootElement.contains(nativeSelection.anchorNode)) {
      const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(selection.anchor.getNode());
      if (tableCellNodeFromSelection == null) {
        setTableMenuCellNode(null);
        return;
      }
      const tableCellParentNodeDOM = editor.getElementByKey(tableCellNodeFromSelection.getKey());
      if (tableCellParentNodeDOM == null) {
        setTableMenuCellNode(null);
        return;
      }
      setTableMenuCellNode(tableCellNodeFromSelection);
    } else if (!activeElement) {
      setTableMenuCellNode(null);
    }
  }, [editor]);
  useEffect(() => {
    return editor.registerUpdateListener(() => {
      editor.getEditorState().read(() => {
        $moveMenu();
      });
    });
  });
  useEffect(() => {
    const menuButtonDOM = menuButtonRef.current;
    if (menuButtonDOM != null && tableCellNode != null) {
      const tableCellNodeDOM = editor.getElementByKey(tableCellNode.getKey());
      if (tableCellNodeDOM != null) {
        const tableCellRect = tableCellNodeDOM.getBoundingClientRect();
        const menuRect = menuButtonDOM.getBoundingClientRect();
        const anchorRect = anchorElem.getBoundingClientRect();
        const top = tableCellRect.top - anchorRect.top + 4;
        const left = tableCellRect.right - menuRect.width - 10 - anchorRect.left;
        menuButtonDOM.style.opacity = '1';
        menuButtonDOM.style.transform = `translate(${left}px, ${top}px)`;
      } else {
        menuButtonDOM.style.opacity = '0';
        menuButtonDOM.style.transform = 'translate(-10000px, -10000px)';
      }
    }
  }, [menuButtonRef, tableCellNode, editor, anchorElem]);
  const prevTableCellDOM = useRef(tableCellNode);
  useEffect(() => {
    if (prevTableCellDOM.current !== tableCellNode) {
      setIsMenuOpen(false);
    }
    prevTableCellDOM.current = tableCellNode;
  }, [prevTableCellDOM, tableCellNode]);
  return /*#__PURE__*/_jsx("div", {
    className: "table-cell-action-button-container",
    ref: menuButtonRef,
    children: tableCellNode != null && /*#__PURE__*/_jsxs(React.Fragment, {
      children: [/*#__PURE__*/_jsx("button", {
        className: "table-cell-action-button",
        onClick: e => {
          e.stopPropagation();
          setIsMenuOpen(!isMenuOpen);
        },
        ref: menuRootRef,
        type: "button",
        children: /*#__PURE__*/_jsx(MeatballsIcon, {})
      }), isMenuOpen && /*#__PURE__*/_jsx(TableActionMenu, {
        cellMerge: cellMerge,
        contextRef: menuRootRef,
        onClose: () => setIsMenuOpen(false),
        setIsMenuOpen: setIsMenuOpen,
        tableCellNode: tableCellNode
      })]
    })
  });
}
export const TableActionMenuPlugin = t0 => {
  const $ = _c(3);
  const {
    anchorElem
  } = t0;
  const isEditable = useLexicalEditable();
  let t1;
  if ($[0] !== anchorElem || $[1] !== isEditable) {
    t1 = createPortal(isEditable ? _jsx(TableCellActionMenuContainer, {
      anchorElem: anchorElem ?? document.body,
      cellMerge: true
    }) : null, anchorElem ?? document.body);
    $[0] = anchorElem;
    $[1] = isEditable;
    $[2] = t1;
  } else {
    t1 = $[2];
  }
  return t1;
};
//# sourceMappingURL=index.js.map