import {
  FillPreviewUniDriver,
  NumberInputUniDriver,
  ToggleButtonUniDriver
} from "@wix/design-system/dist/testkit/unidriver.js";
import { toHexFormat } from "./../ricos-styles/index.js";
import { RicosPluginToolbarNames } from "./../ricos-types/ricos-plugin-toolbar-names.js";
import { dataHook } from "./../wix-rich-content-common/index.js";
import { createNewColorPickerUniDriver } from "./../ui-components/color-picker/new-color-picker/new-color-picker-unidriver.js";
import {
  DATA_CELL_SELECTED,
  INSERT_TABLE_BUTTON,
  INSERT_TABLE_MODAL,
  INSERT_TABLE_MODAL_ADD_BUTTON,
  INSERT_TABLE_MODAL_COLUMNS_INPUT,
  INSERT_TABLE_MODAL_ERROR_MESSAGE,
  INSERT_TABLE_MODAL_GRID_SELECTOR,
  INSERT_TABLE_MODAL_ROWS_INPUT,
  PLUGIN_TOOLBAR_ADD_ROW_COL_BUTTON,
  PLUGIN_TOOLBAR_BORDER_COLOR_BUTTON,
  PLUGIN_TOOLBAR_CONTEXT_MENU_BUTTON,
  PLUGIN_TOOLBAR_MERGE_CELLS_BUTTON,
  PLUGIN_TOOLBAR_MOVE_COLUMN_LEFT_BUTTON,
  PLUGIN_TOOLBAR_MOVE_COLUMN_RIGHT_BUTTON,
  PLUGIN_TOOLBAR_MOVE_ROW_DOWN_BUTTON,
  PLUGIN_TOOLBAR_MOVE_ROW_UP_BUTTON,
  PLUGIN_TOOLBAR_SPLIT_CELL_BUTTON,
  ROOT,
  TABLE_ADD_COL_BUTTON,
  TABLE_ADD_ROW_BUTTON,
  TABLE_BORDER_COLOR_PICKER,
  TABLE_BORDER_MODAL,
  TABLE_COLUMN_HANDLE,
  TABLE_ROW_HANDLE,
  TABLE_SELECTOR
} from "./data-hooks.js";
import { toolbarsToAddIn } from "./get-add-buttons.js";
import styles from "./tiptap/plugins/table-scss.js";
import { BORDER_SCOPE_BUTTON_PREFIX } from "./toolbar/modals/border-scope-selector.js";
import {
  CLEAR,
  DELETE_COLUMN,
  DELETE_ROW,
  DELETE_TABLE,
  DISTRIBUTE_COLUMNS,
  DISTRIBUTE_ROWS,
  INSERT_ABOVE,
  INSERT_BELOW,
  INSERT_LEFT,
  INSERT_RIGHT
} from "./toolbar/modals/data-hooks.js";
const createTableTestkit = (getBase) => {
  const getTable = async (index, options) => {
    const table = await getBase().getAll(dataHook(ROOT), options);
    return table.at(index);
  };
  const getTableContainer = async (index) => {
    const containers = await getBase().getAll("[data-table-container]");
    return containers.at(index);
  };
  const getInsertTableModal = async () => await getBase().get(dataHook(INSERT_TABLE_MODAL));
  return {
    content: {
      atIndex: (index) => {
        const getCell = async ({ row, col }) => {
          const table = await getTable(index);
          const tableRow = (await table.getAll("tr")).at(row);
          const cells = await tableRow.getAll("td, th");
          return cells.at(col);
        };
        const sideMap = {
          T: { cssVar: "--bt-c", className: "borderTop" },
          B: { cssVar: "--bb-c", className: "borderBottom" },
          L: { cssVar: "--bl-c", className: "borderLeft" },
          R: { cssVar: "--br-c", className: "borderRight" }
        };
        return {
          exists: async (options) => {
            try {
              const table = await getTable(index, options);
              return table.exists();
            } catch {
              return false;
            }
          },
          getNativeElement: async () => {
            const table = await getTable(index);
            return table.getNative();
          },
          getRowCount: async () => {
            const table = await getTable(index);
            const rows = await table.getAll("tr");
            return rows.count();
          },
          getColumnCount: async () => {
            const table = await getTable(index);
            const firstRow = (await table.getAll("tr")).at(0);
            const cells = await firstRow.getAll("td, th");
            return cells.count();
          },
          getCellText: async ({ row, col }) => {
            const cell = await getCell({ row, col });
            return cell.text();
          },
          clickCell: async ({ row, col }) => {
            const cell = await getCell({ row, col });
            await cell.click();
          },
          getCellBorderColor: async ({ row, col, side }) => {
            const cell = await getCell({ row, col });
            const { cssVar, className } = sideMap[side];
            const borderElement = await cell.$(`.${styles[className]}`);
            if (!await borderElement.exists()) {
              return null;
            }
            const style = await borderElement.prop("style");
            if (style) {
              const backgroundColor = style.getPropertyValue("background-color");
              if (backgroundColor && backgroundColor !== "transparent") {
                try {
                  return toHexFormat(backgroundColor);
                } catch {
                }
              }
            }
            const cellStyle = await cell.prop("style");
            if (cellStyle) {
              const colorValue = cellStyle.getPropertyValue(cssVar);
              if (colorValue && colorValue !== "transparent") {
                try {
                  return toHexFormat(colorValue);
                } catch {
                }
              }
            }
            return null;
          },
          isCellSelected: async ({ row, col }) => {
            const cell = await getCell({ row, col });
            return await cell.attr(DATA_CELL_SELECTED) === "true";
          },
          getSelectedCellsCount: async () => {
            const table = await getTable(index);
            const selectedCells = await table.getAll(`[${DATA_CELL_SELECTED}="true"]`);
            return selectedCells.count();
          },
          isColumnSelected: async (col) => {
            const table = await getTable(index);
            const rows = await table.getAll("tr");
            const rowCount = await rows.count();
            for (let row = 0; row < rowCount; row++) {
              const tableRow = rows.at(row);
              const cells = await tableRow.getAll("td, th");
              const cellCount = await cells.count();
              let currentCol = 0;
              let foundCell = false;
              for (let cellIdx = 0; cellIdx < cellCount; cellIdx++) {
                const cell = cells.at(cellIdx);
                const colspanAttr = await cell.attr("colspan");
                const colspan = colspanAttr ? parseInt(colspanAttr, 10) : 1;
                if (currentCol <= col && col < currentCol + colspan) {
                  if (await cell.attr(DATA_CELL_SELECTED) !== "true") {
                    return false;
                  }
                  foundCell = true;
                  break;
                }
                currentCol += colspan;
              }
              if (!foundCell) {
                return false;
              }
            }
            return rowCount > 0;
          },
          isRowSelected: async (row) => {
            const table = await getTable(index);
            const rows = await table.getAll("tr");
            const tableRow = rows.at(row);
            const cells = await tableRow.getAll("td, th");
            const colCount = await cells.count();
            for (let col = 0; col < colCount; col++) {
              const cell = cells.at(col);
              if (await cell.attr(DATA_CELL_SELECTED) !== "true") {
                return false;
              }
            }
            return colCount > 0;
          },
          isEntireTableSelected: async () => {
            const table = await getTable(index);
            const allCells = await table.getAll("td, th");
            const totalCells = await allCells.count();
            const selectedCells = await table.getAll(`[${DATA_CELL_SELECTED}="true"]`);
            const selectedCount = await selectedCells.count();
            return totalCells > 0 && totalCells === selectedCount;
          },
          handles: {
            columnHandle: {
              exists: async () => {
                try {
                  const container = await getTableContainer(index);
                  const handle = await container.$(dataHook(TABLE_COLUMN_HANDLE));
                  return handle.exists();
                } catch {
                  return false;
                }
              },
              isVisible: async () => {
                try {
                  const container = await getTableContainer(index);
                  const handle = await container.$(dataHook(TABLE_COLUMN_HANDLE));
                  const displayStyle = await handle.attr("style");
                  return !displayStyle?.includes("display: none");
                } catch {
                  return false;
                }
              },
              click: async () => {
                const container = await getTableContainer(index);
                const handle = await container.$(dataHook(TABLE_COLUMN_HANDLE));
                await handle.mouse.press();
              },
              getNativeElement: async () => {
                const container = await getTableContainer(index);
                const handle = await container.$(dataHook(TABLE_COLUMN_HANDLE));
                return handle.getNative();
              }
            },
            rowHandle: {
              exists: async () => {
                try {
                  const container = await getTableContainer(index);
                  const handle = await container.$(dataHook(TABLE_ROW_HANDLE));
                  return handle.exists();
                } catch {
                  return false;
                }
              },
              isVisible: async () => {
                try {
                  const container = await getTableContainer(index);
                  const handle = await container.$(dataHook(TABLE_ROW_HANDLE));
                  const displayStyle = await handle.attr("style");
                  return !displayStyle?.includes("display: none");
                } catch {
                  return false;
                }
              },
              click: async () => {
                const container = await getTableContainer(index);
                const handle = await container.$(dataHook(TABLE_ROW_HANDLE));
                await handle.mouse.press();
              },
              getNativeElement: async () => {
                const container = await getTableContainer(index);
                const handle = await container.$(dataHook(TABLE_ROW_HANDLE));
                return handle.getNative();
              }
            },
            addRowButton: {
              exists: async () => {
                try {
                  const container = await getTableContainer(index);
                  const button = await container.$(dataHook(TABLE_ADD_ROW_BUTTON));
                  return button.exists();
                } catch {
                  return false;
                }
              },
              click: async () => {
                const container = await getTableContainer(index);
                const button = await container.$(dataHook(TABLE_ADD_ROW_BUTTON));
                await button.mouse.press();
              }
            },
            addColButton: {
              exists: async () => {
                try {
                  const container = await getTableContainer(index);
                  const button = await container.$(dataHook(TABLE_ADD_COL_BUTTON));
                  return button.exists();
                } catch {
                  return false;
                }
              },
              click: async () => {
                const container = await getTableContainer(index);
                const button = await container.$(dataHook(TABLE_ADD_COL_BUTTON));
                await button.mouse.press();
              }
            },
            tableSelector: {
              exists: async () => {
                try {
                  const container = await getTableContainer(index);
                  const selector = await container.$(dataHook(TABLE_SELECTOR));
                  return selector.exists();
                } catch {
                  return false;
                }
              },
              click: async () => {
                const container = await getTableContainer(index);
                const selector = await container.$(dataHook(TABLE_SELECTOR));
                await selector.click();
              }
            }
          }
        };
      }
    },
    insertTableModal: {
      exists: async () => {
        try {
          const insertTableModal = await getInsertTableModal();
          return insertTableModal.exists();
        } catch {
          return false;
        }
      },
      clickInsert: async () => {
        const insertTableModal = await getInsertTableModal();
        const button = await insertTableModal.get(dataHook(INSERT_TABLE_MODAL_ADD_BUTTON));
        await button.click();
      },
      addButton: {
        isFocused: async () => {
          const insertTableModal = await getInsertTableModal();
          const button = await insertTableModal.get(dataHook(INSERT_TABLE_MODAL_ADD_BUTTON));
          const nativeElement = await button.getNative();
          return nativeElement === document.activeElement;
        }
      },
      gridSelector: {
        exists: async () => {
          try {
            const insertTableModal = await getInsertTableModal();
            const gridSelector = await insertTableModal.get(
              dataHook(INSERT_TABLE_MODAL_GRID_SELECTOR)
            );
            return gridSelector.exists();
          } catch {
            return false;
          }
        },
        clickCell: async ({ col, row }) => {
          const insertTableModal = await getInsertTableModal();
          const gridSelector = await insertTableModal.get(
            dataHook(INSERT_TABLE_MODAL_GRID_SELECTOR)
          );
          const cells = await gridSelector.getAll("div");
          const cellIndex = (row - 1) * 8 + (col - 1);
          const cell = cells.at(cellIndex);
          await cell.click();
        },
        getCellCount: async () => {
          const insertTableModal = await getInsertTableModal();
          const gridSelector = await insertTableModal.get(
            dataHook(INSERT_TABLE_MODAL_GRID_SELECTOR)
          );
          const cells = await gridSelector.getAll("div");
          return cells.count();
        }
      },
      rowInput: {
        setValue: async (value) => {
          const numberInputDriver = NumberInputUniDriver(
            getBase().$(dataHook(INSERT_TABLE_MODAL_ROWS_INPUT)),
            getBase()
          );
          await numberInputDriver.enterText(value);
        },
        getValue: async () => {
          const numberInputDriver = NumberInputUniDriver(
            getBase().$(dataHook(INSERT_TABLE_MODAL_ROWS_INPUT)),
            getBase()
          );
          return numberInputDriver.getValue();
        },
        blur: async () => {
          const numberInputDriver = NumberInputUniDriver(
            getBase().$(dataHook(INSERT_TABLE_MODAL_ROWS_INPUT)),
            getBase()
          );
          await numberInputDriver.blur();
        }
      },
      columnInput: {
        setValue: async (value) => {
          const numberInputDriver = NumberInputUniDriver(
            getBase().$(dataHook(INSERT_TABLE_MODAL_COLUMNS_INPUT)),
            getBase()
          );
          await numberInputDriver.enterText(value);
        },
        getValue: async () => {
          const numberInputDriver = NumberInputUniDriver(
            getBase().$(dataHook(INSERT_TABLE_MODAL_COLUMNS_INPUT)),
            getBase()
          );
          return numberInputDriver.getValue();
        },
        blur: async () => {
          const numberInputDriver = NumberInputUniDriver(
            getBase().$(dataHook(INSERT_TABLE_MODAL_COLUMNS_INPUT)),
            getBase()
          );
          await numberInputDriver.blur();
        }
      },
      error: {
        exists: async () => {
          try {
            const insertTableModal = await getInsertTableModal();
            const errorMessage = await insertTableModal.get(
              dataHook(INSERT_TABLE_MODAL_ERROR_MESSAGE)
            );
            return errorMessage.exists();
          } catch {
            return false;
          }
        },
        getMessage: async () => {
          const insertTableModal = await getInsertTableModal();
          const errorMessage = await insertTableModal.get(
            dataHook(INSERT_TABLE_MODAL_ERROR_MESSAGE)
          );
          return errorMessage.text();
        }
      }
    },
    toolbars: {
      createAddButtonToolbars: (getAddButton) => ({
        click: async () => {
          const button = await getAddButton().get(dataHook(INSERT_TABLE_BUTTON));
          await button.click();
        },
        toolbarsToAddIn
      }),
      createPluginToolbar: (getPluginToolbarBase) => {
        const getToolbarBase = () => getPluginToolbarBase(RicosPluginToolbarNames.TABLE);
        const clickToolbarButton = async (hook) => {
          const base = getToolbarBase();
          const button = await base.get(dataHook(hook));
          await button.click();
        };
        const clickContextMenuItem = async (hook) => {
          const menuItem = await getBase().get(dataHook(hook));
          await menuItem.click();
        };
        return {
          exists: async () => {
            try {
              return getToolbarBase().exists();
            } catch {
              return false;
            }
          },
          clickBorder: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_BORDER_COLOR_BUTTON);
          },
          clickMergeCells: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_MERGE_CELLS_BUTTON);
          },
          clickSplitCell: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_SPLIT_CELL_BUTTON);
          },
          clickMoveRowUp: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_MOVE_ROW_UP_BUTTON);
          },
          clickMoveRowDown: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_MOVE_ROW_DOWN_BUTTON);
          },
          clickMoveColumnLeft: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_MOVE_COLUMN_LEFT_BUTTON);
          },
          clickMoveColumnRight: async () => {
            await clickToolbarButton(PLUGIN_TOOLBAR_MOVE_COLUMN_RIGHT_BUTTON);
          },
          addRowCol: {
            click: async () => {
              await clickToolbarButton(PLUGIN_TOOLBAR_ADD_ROW_COL_BUTTON);
            },
            clickInsertAbove: async () => {
              await clickContextMenuItem(INSERT_ABOVE);
            },
            clickInsertBelow: async () => {
              await clickContextMenuItem(INSERT_BELOW);
            },
            clickInsertLeft: async () => {
              await clickContextMenuItem(INSERT_LEFT);
            },
            clickInsertRight: async () => {
              await clickContextMenuItem(INSERT_RIGHT);
            }
          },
          contextMenu: {
            click: async () => {
              await clickToolbarButton(PLUGIN_TOOLBAR_CONTEXT_MENU_BUTTON);
            },
            clickDeleteRow: async () => {
              await clickContextMenuItem(DELETE_ROW);
            },
            clickDeleteColumn: async () => {
              await clickContextMenuItem(DELETE_COLUMN);
            },
            clickDeleteTable: async () => {
              await clickContextMenuItem(DELETE_TABLE);
            },
            clickClear: async () => {
              await clickContextMenuItem(CLEAR);
            },
            clickDistributeRows: async () => {
              await clickContextMenuItem(DISTRIBUTE_ROWS);
            },
            clickDistributeColumns: async () => {
              await clickContextMenuItem(DISTRIBUTE_COLUMNS);
            }
          }
        };
      }
    },
    colorPickerModal: createNewColorPickerUniDriver(getBase),
    borderModal: {
      waitForElement: async () => {
        await getBase().$(dataHook(TABLE_BORDER_MODAL)).wait();
      },
      exists: async () => {
        try {
          return getBase().$(dataHook(TABLE_BORDER_MODAL)).exists();
        } catch {
          return false;
        }
      },
      colorPicker: FillPreviewUniDriver(
        getBase().$(dataHook(TABLE_BORDER_COLOR_PICKER)),
        getBase()
      ),
      selectScope: async (scope) => {
        const toggleButton = ToggleButtonUniDriver(
          getBase().$(dataHook(`${BORDER_SCOPE_BUTTON_PREFIX}${scope}`)),
          getBase()
        );
        await toggleButton.click();
      }
    }
  };
};
export {
  createTableTestkit
};
//# sourceMappingURL=testkit.js.map
