import { DomNodeSubjectObserverFactory } from '../../../../../helpers/change-manager/subject/dom-node-subject/dom-node-subject-observer-factory';
import { VegaPopoverShow } from '../../../../../helpers/event-manager/event-id/vega-event-id';
import { UpdateCursorPositionAction } from '../../../dto/actions/update-cursor-position-action';
import { InsertTableBlockAction } from '../actions/insert-table-block-action';
import { TablePopoverBaseRenderer } from './table-popover-base-renderer';
/**
 * Table toolbar popover renderer class. Render the popover content for the table toolbar button, which includes the table size picker grid.
 */
export class RTETableToolbarPopoverRenderer extends TablePopoverBaseRenderer {
  constructor() {
    super(...arguments);
    this.hoveredRows = 1;
    this.hoveredCols = 1;
  }
  /**
   * Renders the table toolbar popover.
   *
   * @param {VegaRTECreateElementFunction} h - Create element function.
   * @param {VegaRTERenderResult} children - Child elements to be rendered inside the popover.
   * @returns {VegaRTERenderResult} Render result for the table toolbar popover.
   */
  render(h, children) {
    return h('vega-popover', {
      trigger: 'click',
      alignment: 'start',
      placement: 'bottom',
      showArrow: false,
      // eslint-disable-next-line jsdoc/require-jsdoc
      ref: (ref) => {
        if (ref) {
          this.tablePickerPopoverRef = ref;
          DomNodeSubjectObserverFactory.addUniqueObserverToNode(ref, VegaPopoverShow, () => {
            this.resetPicker();
          });
        }
      },
    }, [
      h('div', { slot: 'popover' }, [this.generatePickerStyles(h), this.generateTableSizeGrid(h)]),
      h('div', { slot: 'popover-content' }, children),
    ]);
  }
  /**
   * Generates the table size picker grid.
   *
   * @param {VegaRTECreateElementFunction} h - Create element function.
   * @returns {VegaRTERenderResult} - The render result for the table size picker.
   */
  generateTableSizeGrid(h) {
    const rows = 10;
    const cols = 10;
    const gridCells = [];
    for (let r = 1; r <= rows; r++) {
      for (let c = 1; c <= cols; c++) {
        gridCells.push(h('button', {
          'class': `rte-table-picker__cell`,
          'data-row': r,
          'data-col': c,
          'onMouseenter': this.handlePickerCellHover.bind(this, r, c),
          'onClick': this.handlePickerClick.bind(this, r, c),
        }, []));
      }
    }
    return h('div', { class: 'rte-table-picker' }, [
      h('div', {
        class: 'rte-table-picker__grid',
        // eslint-disable-next-line jsdoc/require-jsdoc
        ref: (ref) => {
          if (ref) {
            this.tablePickerGridRef = ref;
          }
        },
        style: {
          gridTemplateColumns: `repeat(${cols}, 16px)`,
          gridTemplateRows: `repeat(${rows}, 16px)`,
        },
      }, gridCells),
      h('div', {
        class: 'rte-table-picker__hint',
      }, h('vega-hint', {
        // eslint-disable-next-line jsdoc/require-jsdoc
        ref: (ref) => {
          if (ref) {
            this.selectedHintRef = ref;
          }
        },
      }, [`${this.hoveredRows} × ${this.hoveredCols}`])),
    ]);
  }
  /**
   * Generates the styles for the table size picker.
   *
   * @param {VegaRTECreateElementFunction} h - Create element function.
   * @returns {VegaRTERenderResult} - The render result for the styles.
   */
  generatePickerStyles(h) {
    return h('style', {}, [
      // eslint-disable-next-line spellcheck/spell-checker
      `
.rte-table-picker__grid { display: grid; gap: 2px; }
.rte-table-picker__cell {
    box-sizing: border-box;
    border: 1px solid #ccc;
    background-color: transparent;
    cursor: pointer;
}
.rte-table-picker__cell:hover {
    background-color: #cae1fc;
}
.rte-table-picker__cell.active {
    background-color: #cae1fc;
}
.rte-table-picker__hint {
    text-align: center;
}
          `,
    ]);
  }
  /**
   * Creates a table block with the specified number of rows and columns.
   *
   * @param {number} row - The number of rows for the table.
   * @param {number} column - The number of columns for the table.
   */
  createTable(row, column) {
    const extensionContext = this.getTableExtensionContext();
    if (extensionContext) {
      const { host, getSelectedNodes } = extensionContext;
      const focusNode = getSelectedNodes()[0];
      const action = new InsertTableBlockAction(row, column);
      if (!focusNode) {
        host.value.apply(action);
      }
      else if (focusNode.parent) {
        focusNode.parent.apply(action);
      }
      if (action.nextFocusNode) {
        host.value.apply(new UpdateCursorPositionAction(action.nextFocusNode, 1));
      }
    }
  }
  /**
   * Handles the click event on a picker cell.
   *
   * @param {number} r - The number of rows selected.
   * @param {number} c - The number of columns selected.
   */
  handlePickerClick(r, c) {
    this.createTable(r, c);
    void this.tablePickerPopoverRef.hide();
  }
  /**
   * Handles the hover event on a picker cell.
   *
   * @param {number} r - The number of rows being hovered over.
   * @param {number} c - The number of columns being hovered over.
   */
  handlePickerCellHover(r, c) {
    this.hoveredRows = r;
    this.hoveredCols = c;
    Array.from(this.tablePickerGridRef.children).forEach((cell) => {
      const rIndex = Number(cell.dataset.row);
      const cIndex = Number(cell.dataset.col);
      if (rIndex <= this.hoveredRows && cIndex <= this.hoveredCols) {
        cell.classList.add('active');
      }
      else {
        cell.classList.remove('active');
      }
    });
    this.selectedHintRef.textContent = `${this.hoveredRows} × ${this.hoveredCols}`;
  }
  /**
   * Resets the table picker to its initial state.
   */
  resetPicker() {
    this.handlePickerCellHover(1, 1);
  }
}
