"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports._onHeaderRender = void 0;
exports._copyAndSort = _copyAndSort;
exports.focusEditedCell = focusEditedCell;
exports.getCellFromCoords = getCellFromCoords;
exports.scrollToColumn = scrollToColumn;
exports.scrollToRow = scrollToRow;
exports.waitFor = waitFor;
exports.sleep = sleep;
exports.addRowNumbers = addRowNumbers;
exports.getStylesForSelectedCell = getStylesForSelectedCell;
exports.showFocus = showFocus;
exports.hideFocus = hideFocus;
exports.getComboBoxInput = getComboBoxInput;
const react_1 = __importDefault(require("react"));
const react_2 = require("@fluentui/react");
const __1 = require("..");
/**
 * Method to copy and sort.
 *
 * @param {T[]} items
 * @param {string }columnKey
 * @param {boolean} isSortedDescending
 * @returns {T[]}
 */
function _copyAndSort(items, columnKey, isSortedDescending) {
    const key = columnKey;
    return items.slice(0).sort((a, b) => {
        const comparison = a[key] < b[key];
        const shouldSwap = isSortedDescending ? !comparison : comparison;
        return shouldSwap ? 1 : -1;
    });
}
/**
 * Focus edited cell.
 *
 * @param {EditedCell | undefined} editedCell
 * @param {UITableProps} props
 * @param {string} direction
 * @returns {Promise<void>}
 */
function focusEditedCell(editedCell, props, direction = '') {
    const rowIndex = editedCell?.rowIndex || 0;
    const colKey = editedCell?.column?.key || '';
    let newRowIndex = rowIndex;
    let newColKey = colKey;
    if (!colKey) {
        return Promise.resolve();
    }
    // go up/down/left/right
    if (direction) {
        const editableColumnKeys = props.columns.filter((c) => c.editable).map((c) => c.key);
        const rowsLen = props.items.length;
        const colIdx = editableColumnKeys.indexOf(colKey);
        if (direction === 'right') {
            if (colIdx < editableColumnKeys.length - 1) {
                newColKey = editableColumnKeys[colIdx + 1];
            }
        }
        else if (direction === 'left') {
            if (colIdx > 0) {
                newColKey = editableColumnKeys[colIdx - 1];
            }
        }
        else if (direction === 'down') {
            if (rowIndex < rowsLen - 1) {
                newRowIndex = rowIndex + 1;
            }
        }
        else if (direction === 'up') {
            if (rowIndex > 0) {
                newRowIndex = rowIndex - 1;
            }
        }
    }
    return new Promise((resolve) => {
        requestAnimationFrame(() => {
            const cell = getCellFromCoords(newRowIndex, newColKey, props.columns, props.showRowNumbers);
            if (cell && direction) {
                cell.click();
            }
            cell?.focus();
            requestAnimationFrame(() => resolve());
        });
    });
}
/**
 * Get cell from coordinates.
 *
 * @param {number} rowIdx
 * @param {string} columnKey
 * @param {UIColumn} columns
 * @param {boolean} addOneToColIndex
 * @returns {NodeListOf<Element>}
 */
function getCellFromCoords(rowIdx, columnKey, columns, addOneToColIndex = false) {
    const selectedIdx = (columns.findIndex((col) => col.key === columnKey) || 0) + +addOneToColIndex;
    const row = document.querySelector(`.ms-DetailsList .ms-DetailsList-contentWrapper .ms-List-page .ms-DetailsRow[data-item-index="${rowIdx || 0}"]`);
    const cols = row?.querySelectorAll('.ms-DetailsRow-cell');
    return cols?.length && cols[selectedIdx];
}
// manual workaround due to the lack of API for selecting columns
/**
 * Scrolls to column.
 *
 * @param {string} columnKey
 * @param {UIColumn[]} columns
 * @param {number} selectedRow
 * @param {boolean} addOneToColIndex
 */
function scrollToColumn(columnKey, columns, selectedRow, addOneToColIndex = false) {
    const sidebar = document.querySelector('.data-editor__sidebar');
    const sidebarWidth = (sidebar?.getBoundingClientRect().width ?? 0) + (addOneToColIndex ? 20 : 0);
    const scrollContainer = document.querySelector('.ms-ScrollablePane--contentContainer');
    const cell = getCellFromCoords(selectedRow, columnKey, columns, addOneToColIndex);
    const box = cell?.getBoundingClientRect();
    if (scrollContainer && box) {
        const left = scrollContainer.scrollLeft + Math.ceil(box.x) - sidebarWidth;
        requestAnimationFrame(() => scrollContainer.scrollTo({ left, behavior: 'smooth' }));
    }
}
/**
 * Scrolls to row.
 *
 * @param {number} idx
 * @param {IDetailsList | null} table
 */
function scrollToRow(idx = 0, table = null) {
    if (!table) {
        return;
    }
    table.focusIndex(idx, false);
    const slctr = `.ms-DetailsList-contentWrapper .ms-DetailsRow[data-selection-index="${idx}"]`;
    waitFor(slctr)
        .then((rowEl) => {
        rowEl.setAttribute('tabIndex', '0');
        rowEl.click();
        rowEl.focus();
        showFocus();
    })
        .catch((e) => {
        throw e;
    });
}
/**
 * Wait for selector.
 *
 * @param {string} selector
 * @param {number} count - number of tries, after which the element is considered not found
 *                          (so that the function doesn't run forever)
 * @returns {Promise<Element>}
 */
async function waitFor(selector, count = 10) {
    if (count === 0) {
        throw new Error('Element for selector not found: ' + selector);
    }
    await sleep();
    const el = document.querySelector(selector);
    return el ? Promise.resolve(el) : waitFor(selector, count - 1);
}
/**
 * Promisified setTimeout.
 *
 * @param ms
 * @returns Promise
 */
function sleep(ms = 200) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
 * Adds row numbers.
 *
 * @param {any} columns
 * @param {boolean} showRowNumbers
 * @returns {any}
 */
function addRowNumbers(columns, showRowNumbers = false) {
    if (showRowNumbers && columns[0].key !== '__row_number__') {
        columns.unshift({
            key: '__row_number__',
            name: '#',
            fieldName: '__row_number__',
            minWidth: 24,
            maxWidth: 24,
            isResizable: false
        });
    }
    return columns;
}
const _onHeaderRender = (props, defaultRender) => {
    if (!props || !defaultRender) {
        return null;
    }
    const customProps = {
        ...props,
        onRenderColumnHeaderTooltip: (item, tooltipDefaultRender) => {
            if (item?.column) {
                const column = item.column;
                const editable = (column.editable ? '' : 'not-') + 'editable-container';
                const isRowNumber = column.key === '__row_number__';
                const containerDiv = isRowNumber ? react_1.default.createElement("div", { className: editable }) : null;
                // row number column header is focusable on the parent of this cell
                const isFocusable = !isRowNumber;
                return (react_1.default.createElement("div", { className: "data-editor__header-cell", "data-is-focusable": isFocusable },
                    column.iconName && (react_1.default.createElement(__1.UIIcon, { className: "type-icon", iconName: column.iconName, title: column.iconTooltip || '' })),
                    react_1.default.createElement("span", { title: column?.headerTooltip || column.name }, column.name),
                    containerDiv));
            }
            const isCheckTooltip = item?.hostClassName === 'ms-DetailsHeader-checkTooltip';
            if (props.selection && isCheckTooltip && tooltipDefaultRender) {
                return tooltipDefaultRender(item);
            }
            return null;
        }
    };
    return react_1.default.createElement(react_2.Sticky, null, defaultRender(customProps));
};
exports._onHeaderRender = _onHeaderRender;
/**
 * Gets styles for selected cell.
 *
 * @param state
 * @returns {Partial<IDetailsListStyles>}
 */
function getStylesForSelectedCell(state) {
    let styles = {};
    const editedRow = state.editedCell ? state.editedCell.rowIndex : undefined;
    const editedColumn = state.editedCell ? state.editedCell.column : undefined;
    if (editedRow !== undefined && editedColumn !== undefined) {
        styles = {
            root: {
                ['div.ms-List-cell']: {
                    position: 'relative',
                    zIndex: 0
                },
                [`div.ms-List-cell[data-list-index="${editedRow}"]`]: {
                    zIndex: 1
                },
                [`.ms-DetailsRow-cell`]: {
                    overflow: 'hidden'
                },
                [`div.ms-List-cell[data-list-index="${editedRow}"] .ms-DetailsRow-cell[data-automation-key="${editedColumn.key}"]`]: {
                    overflow: 'visible'
                }
            }
        };
    }
    return styles;
}
function showFocus() {
    document.body.classList.remove('ms-Fabric--isFocusHidden');
    document.body.classList.add('ms-Fabric--isFocusVisible');
}
function hideFocus() {
    document.body.classList.add('ms-Fabric--isFocusHidden');
    document.body.classList.remove('ms-Fabric--isFocusVisible');
}
/**
 * Gets ComboBox input.
 *
 * @param ref
 * @returns {HTMLInputElement | undefined }
 */
function getComboBoxInput(ref) {
    return ref?.current?.querySelector('input');
}
//# sourceMappingURL=UITable-helper.js.map