import { findTable } from '@atlaskit/editor-tables';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';

/*
 * Returns the level of nesting of a given `nodeType` in the current position.
 * eg. table > table is nested 1 level, table > table > table is nested 2 levels.
 *
 * ```typescript
 * const nestingLevel = getParentOfTypeCount(schema.nodes.table)(position);
 * ```
 */
export const getParentOfTypeCount = nodeType => $pos => {
  let count = 0;
  // Loop through parent nodes from bottom to top
  for (let depth = $pos.depth; depth > 0; depth--) {
    const node = $pos.node(depth);
    // Count the table nodes
    if (node.type === nodeType) {
      count++;
    }
  }
  return count;
};

/*
 * Returns the (absolute) position directly after the top parent node of a given `nodeType` in the current position.
 *
 * ```typescript
 * const nestingLevel = getEndTopParentNodeOfType(schema.nodes.table)(position);
 * ```
 */
export const getPositionAfterTopParentNodeOfType = nodeType => $pos => {
  // Loop through parent nodes from top to bottom
  for (let depth = 1; depth <= $pos.depth; depth++) {
    const node = $pos.node(depth);
    // Count the table nodes
    if (node.type === nodeType) {
      return $pos.after(depth);
    }
  }
};

/*
 * Returns true if the current selection is inside a table nested within a table.
 *
 * ```typescript
 * const isNestedTable = isSelectionTableNestedInTable(state);
 * ```
 */
export const isSelectionTableNestedInTable = state => {
  const table = findTable(state.selection);
  if (!table) {
    return false;
  }
  const parent = state.doc.resolve(table.pos).parent;
  const nodeTypes = state.schema.nodes;
  return [nodeTypes.tableHeader, nodeTypes.tableCell].includes(parent.type);
};

/*
 * Returns true if the schema supports nesting tables inside table cells.
 * This is determined by checking if table cells can contain table nodes in their content model.
 *
 * ```typescript
 * const supportsNestedTables = isNestedTablesSupported(state.schema);
 * ```
 */
export const isNestedTablesSupported = schema => {
  var _tableCell$contentMat, _tableHeader$contentM;
  const {
    table,
    tableCell,
    tableHeader
  } = schema.nodes;
  if (!table || !tableCell || !tableHeader) {
    return false;
  }

  // Check if table cells can contain table nodes by testing their content match
  const tableCellCanContainTable = ((_tableCell$contentMat = tableCell.contentMatch.matchType(table)) === null || _tableCell$contentMat === void 0 ? void 0 : _tableCell$contentMat.validEnd) === true;
  const tableHeaderCanContainTable = ((_tableHeader$contentM = tableHeader.contentMatch.matchType(table)) === null || _tableHeader$contentM === void 0 ? void 0 : _tableHeader$contentM.validEnd) === true;
  return tableCellCanContainTable || tableHeaderCanContainTable;
};

/*
 * Returns true if the schema supports nesting a table inside a panel (panel_c1 variant),
 * AND the `platform_editor_nest_table_in_panel` experiment is enabled.
 *
 * ```typescript
 * const supportsTableInPanel = isPanelNestingTableSupported(state.schema);
 * ```
 */
export const isPanelNestingTableSupported = schema => {
  var _panel_c1$contentMatc;
  const {
    table,
    panel_c1
  } = schema.nodes;
  if (!table || !panel_c1) {
    return false;
  }

  // Confirm the PM schema actually allows table inside panel_c1
  const panelC1CanContainTable = ((_panel_c1$contentMatc = panel_c1.contentMatch.matchType(table)) === null || _panel_c1$contentMatc === void 0 ? void 0 : _panel_c1$contentMatc.validEnd) === true;
  return panelC1CanContainTable && expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true);
};