import { ToggleHeaderTableColumnStrategy } from '../action-handler-strategies/toggle-header-table-column-strategy';
import { DeleteTableColumnAction } from '../actions/delete-table-column-action';
import { InsertTableColumnDirection, InsertTableColumnAction } from '../actions/insert-table-column-action';
import { SelectTableColumnAction } from '../actions/select-table-column-action';
import { ToggleHeaderTableColumnAction } from '../actions/toggle-header-table-column-action';
import { RTETableBlock } from '../dto/table-block';
import { getParentBlockByType } from '../utils/utils';
import { SettingEventHandler, TableSettingType } from './setting-event-handler.abstract';
export var ColumnOperationType;
(function (ColumnOperationType) {
  ColumnOperationType["HEADER_COLUMN"] = "HEADER_COLUMN";
  ColumnOperationType["ADD_COLUMN_LEFT"] = "ADD_COLUMN_LEFT";
  ColumnOperationType["ADD_COLUMN_RIGHT"] = "ADD_COLUMN_RIGHT";
  ColumnOperationType["DELETE_COLUMN"] = "DELETE_COLUMN";
  ColumnOperationType["SELECT_COLUMN"] = "SELECT_COLUMN";
})(ColumnOperationType || (ColumnOperationType = {}));
/**
 * Event handler for column operations in a table.
 */
export class ColumnOperationEventHandler extends SettingEventHandler {
  /**
   * @inheritDoc
   */
  canHandle(action) {
    return action[0] === TableSettingType.COLUMN;
  }
  /**
   * @inheritDoc
   */
  execute(action, extensionContext) {
    const selectedCells = extensionContext.tableSelection.getSelectedCells();
    if (!selectedCells || selectedCells.length === 0) {
      return;
    }
    const operation = action[1];
    switch (operation) {
      case ColumnOperationType.ADD_COLUMN_LEFT:
      case ColumnOperationType.ADD_COLUMN_RIGHT:
        this.handleInsertColumn(operation, selectedCells);
        break;
      case ColumnOperationType.DELETE_COLUMN:
        this.handleDeleteColumn(selectedCells);
        break;
      case ColumnOperationType.SELECT_COLUMN:
        this.handleSelectColumn(selectedCells, extensionContext);
        break;
      case ColumnOperationType.HEADER_COLUMN:
        this.handleToggleHeaderColumn(selectedCells);
        break;
      default:
        break;
    }
  }
  /**
   * Adds a new column to the table at the specified position.
   *
   * @param {ColumnOperationType} direction - The position to insert the new column (left or right).
   * @param {RTETableCellBlock[] | RTETableHeadCellBlock[]} selectedCells - The selected table cells.
   */
  handleInsertColumn(direction, selectedCells) {
    const action = new InsertTableColumnAction(direction === ColumnOperationType.ADD_COLUMN_LEFT
      ? InsertTableColumnDirection.LEFT
      : InsertTableColumnDirection.RIGHT, selectedCells);
    this.applyActionOnTable(action, selectedCells[0]);
  }
  /**
   * Deletes the selected column from the table.
   *
   * @param {RTETableCellBlock[] | RTETableHeadCellBlock[]} selectedCells - The selected table cells.
   */
  handleDeleteColumn(selectedCells) {
    const action = new DeleteTableColumnAction(selectedCells);
    this.applyActionOnTable(action, selectedCells[0]);
  }
  /**
   * Selects the entire column in the table.
   *
   * @param {RTETableCellBlock[] | RTETableHeadCellBlock[]} selectedCells - The selected table cells.
   * @param {RTETableExtensionContext} extensionContext - The table extension context.
   */
  handleSelectColumn(selectedCells, extensionContext) {
    const action = new SelectTableColumnAction(selectedCells, (allSelectedCells) => {
      extensionContext.tableSelection.setSelectedCells(allSelectedCells);
    });
    this.applyActionOnTable(action, selectedCells[0]);
  }
  /**
   * Toggles the header state of the selected column in the table.
   *
   * @param {RTETableCellBlock[] | RTETableHeadCellBlock[]} selectedCells - The selected table cells.
   */
  handleToggleHeaderColumn(selectedCells) {
    const headerOn = !ToggleHeaderTableColumnStrategy.isFullHeaderSelection(selectedCells);
    const action = new ToggleHeaderTableColumnAction(selectedCells, headerOn);
    this.applyActionOnTable(action, selectedCells[0]);
  }
  /**
   * Apply the specified action on the table containing the selected cell.
   *
   * @param {DeleteTableColumnAction | InsertTableColumnAction} action - The action to apply.
   * @param {RTETableCellBlock | RTETableHeadCellBlock} selectedCell - The selected table cell.
   */
  applyActionOnTable(action, selectedCell) {
    const table = getParentBlockByType(selectedCell, RTETableBlock);
    if (table) {
      table.apply(action);
    }
  }
}
