import { arrayEach } from "../../../helpers/array.mjs";
import { rangeEach } from "../../../helpers/number.mjs";
import { addClass, setAttribute } from "../../../helpers/dom/element.mjs";
import BaseUI from "./_base.mjs";
import { A11Y_DESCRIPTION, A11Y_EXPANDED, A11Y_HIDDEN } from "../../../helpers/a11y.mjs";
import { ROW_HEADER_DESCRIPTION_COLLAPSE_ROW, ROW_HEADER_DESCRIPTION_EXPAND_ROW } from "../../../i18n/constants.mjs";
/**
 * Class responsible for the UI in the Nested Rows' row headers.
 *
 * @private
 * @class HeadersUI
 * @augments BaseUI
 */
class HeadersUI extends BaseUI {
  /**
   * CSS classes used in the row headers.
   *
   * @type {object}
   */
  static get CSS_CLASSES() {
    return {
      indicatorContainer: 'ht_nestingLevels',
      parent: 'ht_nestingParent',
      emptyIndicator: 'ht_nestingLevel_empty',
      button: 'ht_nestingButton',
      expandButton: 'ht_nestingExpand',
      collapseButton: 'ht_nestingCollapse'
    };
  }
  constructor(nestedRowsPlugin, hotInstance) {
    super(nestedRowsPlugin, hotInstance);
    /**
     * Reference to the DataManager instance connected with the Nested Rows plugin.
     *
     * @type {DataManager}
     */
    this.dataManager = this.plugin.dataManager;
    // /**
    //  * Level cache array.
    //  *
    //  * @type {Array}
    //  */
    // this.levelCache = this.dataManager.cache.levels;
    /**
     * Reference to the CollapsingUI instance connected with the Nested Rows plugin.
     *
     * @type {CollapsingUI}
     */
    this.collapsingUI = this.plugin.collapsingUI;
    /**
     * Cache for the row headers width.
     *
     * @type {null|number}
     */
    this.rowHeaderWidthCache = null;
  }

  /**
   * Append nesting indicators and buttons to the row headers.
   *
   * @private
   * @param {number} row Row index.
   * @param {HTMLElement} TH TH 3element.
   */
  appendLevelIndicators(row, TH) {
    const rowIndex = this.hot.toPhysicalRow(row);
    const rowLevel = this.dataManager.getRowLevel(rowIndex);
    const rowObject = this.dataManager.getDataObject(rowIndex);
    const innerDiv = TH.getElementsByTagName('DIV')[0];
    const innerSpan = innerDiv.querySelector('span.rowHeader');
    const previousIndicators = innerDiv.querySelectorAll('[class^="ht_nesting"]');
    const ariaEnabled = this.hot.getSettings().ariaTags;
    arrayEach(previousIndicators, elem => {
      if (elem) {
        innerDiv.removeChild(elem);
      }
    });
    addClass(TH, HeadersUI.CSS_CLASSES.indicatorContainer);
    if (rowLevel) {
      const {
        rootDocument
      } = this.hot;
      const initialContent = innerSpan.cloneNode(true);
      innerDiv.innerHTML = '';
      rangeEach(0, rowLevel - 1, () => {
        const levelIndicator = rootDocument.createElement('SPAN');
        addClass(levelIndicator, HeadersUI.CSS_CLASSES.emptyIndicator);
        innerDiv.appendChild(levelIndicator);
      });
      innerDiv.appendChild(initialContent);
    }
    if (this.dataManager.hasChildren(rowObject)) {
      const buttonsContainer = this.hot.rootDocument.createElement('DIV');
      if (ariaEnabled) {
        setAttribute(buttonsContainer, [A11Y_HIDDEN()]);
      }
      addClass(TH, HeadersUI.CSS_CLASSES.parent);
      if (this.collapsingUI.areChildrenCollapsed(rowIndex)) {
        addClass(buttonsContainer, `${HeadersUI.CSS_CLASSES.button} ${HeadersUI.CSS_CLASSES.expandButton}`);
        if (ariaEnabled) {
          setAttribute(TH, [A11Y_EXPANDED(false), A11Y_DESCRIPTION(this.hot.getTranslatedPhrase(ROW_HEADER_DESCRIPTION_EXPAND_ROW))]);
        }
      } else {
        addClass(buttonsContainer, `${HeadersUI.CSS_CLASSES.button} ${HeadersUI.CSS_CLASSES.collapseButton}`);
        if (ariaEnabled) {
          setAttribute(TH, [A11Y_EXPANDED(true), A11Y_DESCRIPTION(this.hot.getTranslatedPhrase(ROW_HEADER_DESCRIPTION_COLLAPSE_ROW))]);
        }
      }
      innerDiv.appendChild(buttonsContainer);
    }
  }

  /**
   * Update the row header width according to number of levels in the dataset.
   *
   * @private
   * @param {number} deepestLevel Cached deepest level of nesting.
   */
  updateRowHeaderWidth(deepestLevel) {
    let deepestLevelIndex = deepestLevel;
    if (!deepestLevelIndex) {
      deepestLevelIndex = this.dataManager.cache.levelCount;
    }
    this.rowHeaderWidthCache = Math.max(50, 11 + 10 * deepestLevelIndex + 25);
    this.hot.render();
  }
}
export default HeadersUI;