var __rest = (this && this.__rest) || function (s, e) {
  var t = {};
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
    t[p] = s[p];
  if (s != null && typeof Object.getOwnPropertySymbols === "function")
    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
      if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
        t[p[i]] = s[p[i]];
    }
  return t;
};
import { cleanObject } from '../../../../../utils/object';
import { parseToPixelString } from '../../../../../utils/pixel';
import { UpdateCursorPositionAction } from '../../../dto/actions/update-cursor-position-action';
import { RTETableCellAnnotationsAction } from '../actions/table-cell-annotations-action';
import { RTETableHeadCellAnnotationsAction } from '../actions/table-head-cell-annotations-action';
import { RTETableExtensionAnnotationTypeEnum } from '../annotations/table-annotation';
import { RTETableCellAnnotation } from '../annotations/table-cell-annotation';
import { RTETableHeadCellBlock } from '../dto/table-head-cell-block';
/**
 * Event handler for cell properties in a table.
 */
export class CellPropertiesEventHandler {
  /**
   * Get the style collection from the selected table cells.
   *
   * @param {RTETableCellBlock[]} selectedCells - The selected table cells to merge styles from
   * @returns {TableCellStylePropertiesMap} The merged styles object containing only common style properties
   */
  static getStyleCollectionFromCell(selectedCells) {
    return selectedCells.reduce((accumulator, cell) => {
      const annotation = cell.getAnnotationByType(RTETableExtensionAnnotationTypeEnum.CELL);
      accumulator[cell.id] = {};
      if (annotation) {
        const _a = annotation.toJSON().tableCell, { border } = _a, restProps = __rest(_a, ["border"]);
        const formattedBorder = {};
        if (border) {
          formattedBorder.borderStyle = border.style;
          formattedBorder.borderColor = border.color;
          formattedBorder.borderWidth = border.width;
        }
        accumulator[cell.id] = cleanObject(Object.assign(Object.assign({}, restProps), formattedBorder));
      }
      return accumulator;
    }, {});
  }
  /**
   * Convert the style collection prop to a form field value by merging styles.
   *
   * @param {TableCellStylePropertiesMap} styleMap - The default value prop.
   * @returns {RTETablePropertiesType} The merged form field value.
   */
  static convertStyleMapToFormField(styleMap) {
    const styleCollection = {};
    for (const id in styleMap) {
      const style = styleMap[id];
      for (const key in style) {
        if (styleCollection[key]) {
          styleCollection[key].push(style[key]);
        }
        else {
          styleCollection[key] = [style[key]];
        }
      }
    }
    const defaultValueSize = Object.keys(styleMap).length;
    const mergedStyles = {};
    for (const key in styleCollection) {
      const styleValues = styleCollection[key];
      const uniqueValues = new Set(styleValues);
      if (styleValues.length === defaultValueSize && uniqueValues.size === 1) {
        mergedStyles[key] = styleValues[0];
      }
    }
    return mergedStyles;
  }
  /**
   * Apply the given properties to the selected cells
   *
   * @param {RTETableExtensionContext} extensionContext The extensionContext
   * @param {Record<string, RTETablePropertiesType>} properties - The properties to apply
   * @param {boolean} isFlushable - Whether the action is flushable
   */
  applyProperties(extensionContext, properties, isFlushable) {
    const selectedCells = extensionContext.tableSelection.getSelectedCells();
    selectedCells.forEach((cell) => {
      const originalStyles = properties[cell.id];
      if (originalStyles) {
        const annotation = this.convertToVegaTableCellAnnotation(Object.assign({}, originalStyles));
        this.applyAnnotation(cell, annotation, isFlushable);
      }
    });
  }
  /**
   * Update the rich text editor cursor position
   *
   * @param {RTETableExtensionContext} extensionContext - The table extension context.
   * @param {Nullable<RTENode>} focusNode - The node to focus on.
   */
  updateCursorPosition(extensionContext, focusNode) {
    if (extensionContext && focusNode) {
      extensionContext.host.value.apply(new UpdateCursorPositionAction(focusNode, 0));
    }
  }
  /**
   * Convert RTETablePropertiesType to VegaRTETableCellAnnotation
   *
   * @param {RTETablePropertiesType} originalStyles - The original style properties
   * @returns {VegaRTETableCellAnnotation} The converted VegaRTETableCellAnnotation
   */
  convertToVegaTableCellAnnotation(originalStyles) {
    const { borderStyle, borderWidth, borderColor } = originalStyles, restStyles = __rest(originalStyles, ["borderStyle", "borderWidth", "borderColor"]);
    const border = cleanObject({
      style: borderStyle,
      width: borderWidth ? parseToPixelString(borderWidth) : '',
      color: borderColor,
    });
    return cleanObject(Object.assign(Object.assign({}, restStyles), { backgroundColor: restStyles.backgroundColor || '', padding: restStyles.padding ? parseToPixelString(restStyles.padding) : '', width: restStyles.width ? parseToPixelString(restStyles.width) : '', height: restStyles.height ? parseToPixelString(restStyles.height) : '', verticalAlign: restStyles.verticalAlign || '', textAlign: restStyles.textAlign || '', border }));
  }
  /**
   * Apply the given annotation to the specified table cell
   *
   * @param {RTETableCellBlock} cell - The table cell to apply the annotation to
   * @param {VegaRTETableCellAnnotation} annotation - The annotation to apply
   * @param {boolean} isFlushable - Whether the action is flushable
   */
  applyAnnotation(cell, annotation, isFlushable) {
    const originAnnotation = cell.getAnnotationByType(RTETableExtensionAnnotationTypeEnum.CELL) ||
      new RTETableCellAnnotation({}, false);
    const action = cell instanceof RTETableHeadCellBlock
      ? new RTETableHeadCellAnnotationsAction(annotation, originAnnotation)
      : new RTETableCellAnnotationsAction(annotation, originAnnotation);
    action.isFlushable = isFlushable;
    cell.apply(action);
  }
}
