import Row from "./Row";
import type DataGrid from "./DataGrid";
interface RowData {
    [key: string]: any;
}
interface CellData {
    label: string;
    value: any;
}
interface SetDataParams {
    colIndex: number;
    rowIndex: number;
    value: any[][];
}
interface ValidationError {
    title: string;
    key: string;
    value: any;
    message: string;
}
declare class Body {
    grid: DataGrid;
    data: RowData[];
    rows: Row[];
    height: number;
    rowHeights: number[];
    rowOffsets: number[];
    visibleRowIndexes: Set<number>;
    visibleRangeFirst: number;
    visibleRangeEnd: number;
    rowCache: Map<number, Row>;
    bufferSize: number;
    private rowAccessTime;
    private maxCacheSize;
    private _nestedDirtyRows;
    private _nestedRenderedRows;
    constructor(grid: DataGrid, data: RowData[]);
    /**
     * Compare two nested data arrays to determine if they are meaningfully equal.
     * Aligned with DOM table's isDataListEqual logic:
     *   1. Quick length check
     *   2. Force-refresh: if any row has `estimateData` (business-specific key), treat as changed
     *   3. Compare row identifiers (id) — if all ids match in order, data is considered equal
     *
     * This avoids both false positives (length-only check misses content changes) and
     * false negatives (reference comparison always differs since preprocessSingleRow creates
     * new objects each time).
     */
    private _isNestedDataListEqual;
    /**
     * Clear all row caches (Row objects + LRU access times).
     * Called when group dimension changes to force re-creation of all rows
     * with updated styles (background colors, color bars, borders, etc.)
     */
    clearRowCache(): void;
    paint(data: RowData[]): void;
    /**
     * CTRL+V 粘贴
     * @param data 粘贴板中的数据
     */
    pasteData(data: any[][]): void;
    batchSetData({ colIndex, rowIndex, value }: SetDataParams): void;
    /**
     * autofull自动填充
     */
    autofillData(): void;
    resizeColumn(colIndex: number, width: number): void;
    resizeAllColumn(width: number): void;
    resizeRow(rowIndex: number, height: number): void;
    handleCheckRow(y?: number): void;
    handleCheckHeader(): void;
    mouseMove(x: number, y: number): void;
    mouseDown(x: number, y: number, shiftKey?: boolean): void;
    click(x: number, y: number, clientX?: number, clientY?: number, event?: MouseEvent): void;
    dbClick(x: number, y: number): void;
    /**
     * Check if double click hits a viewer with onDblClick handler
     * @returns true if viewer handled the double click
     */
    private handleViewerDblClick;
    /**
     * Check if click hits a reminder triangle (blue triangle at top-right corner)
     * @returns true if reminder triangle was clicked and callback was triggered
     */
    private handleReminderClick;
    /**
     * Check if mouse is inside a reminder triangle area (for cursor:pointer)
     */
    private isInsideReminderArea;
    /**
     * Check if click hits a viewer with onClick handler
     * @returns true if viewer handled the click
     */
    private handleViewerClick;
    /**
     * Get viewer interactive cursor for a row at position
     * @returns cursor style string or null
     */
    private getViewerCursor;
    rePaintRow(rowIndex: number): void;
    updateVisibleRows(): void;
    binarySearchRow(targetY: number): number;
    draw(): void;
    getCell(x: number, y: number): any;
    getRow(y: number): Row;
    getRangeData({ xArr, yArr }?: {
        xArr: [number, number];
        yArr: [number, number];
    }): CellData[][];
    getSelectedData({ xArr, yArr }?: {
        xArr: [number, number];
        yArr: [number, number];
    }): {
        text: string;
        value: string[][];
    };
    clearSelectedData(): void;
    getData(): RowData[];
    getCheckedRows(): RowData[];
    getChangedRows(): RowData[];
    validate(callback?: (valid: boolean) => void): void;
    validateChanged(callback?: (valid: boolean) => void): void;
    validateField(ci?: number, ri?: number): void;
    getValidations(): ValidationError[][];
    setValidations(errors?: any[]): void;
    clearValidations(): void;
    getRowData(y: number): RowData;
    getCellData(x: number, y: number): {
        title: string;
        key: string;
        value: any;
    };
    updateData(data?: any[]): void;
    /**
     * Incrementally update a single row by its index.
     *
     * Replaces the data for the specified row and synchronizes cached Row/Cell
     * objects without clearing the entire row cache or triggering a full repaint.
     * Complexity: O(columns) instead of O(rows × columns) for a full refresh.
     *
     * @param rowIndex - The zero-based index of the row to update
     * @param newRowData - The complete new row data object that replaces the old one
     */
    updateRowByIndex(rowIndex: number, newRowData: any): void;
    /**
     * 增量刷新指定列的数据
     *
     * 只更新 data 数组中指定列 key 对应的值，并同步已缓存 Row 中的 Cell 对象。
     * 比 paint()（全量重建）高效得多：O(rows × colKeys.length) vs O(rows × allColumns)，
     * 且不清空 Row 缓存、不重算行高/偏移，仅做数据替换和局部重绘。
     *
     * @param colKeys - 需要刷新的列 key 数组
     * @param newDataByKey - 新的列数据，格式为 { [colKey]: value }[] ，与 this.data 按索引对齐
     *                       如果为 undefined，则从 this.data 中直接读取（适用于外部已直接修改 data 数组的场景）
     */
    refreshColumnData(colKeys: string[], newDataByKey?: Record<string, any>[]): void;
    /**
     * 图片列专用脏检查：提取实际 URL 比较，忽略 string↔object 类型震荡
     * 和对象引用差异（每次 refreshColumnData 传入新对象但内容相同）。
     */
    private _imageValueChanged;
    /** 从 value 中提取图片 URL 数组 */
    private _extractImageUrls;
    updateCellData(_colIndex: number): void;
    /**
     * 获取所有选中的行对象（返回Row对象而不是RowData）
     */
    getCheckedRowObjects(): Row[];
    /**
     * 根据鼠标Y坐标获取对应的行对象
     */
    getRowAtPosition(mouseY: number): Row | null;
    /**
     * Get the absolute X position of a cell, accounting for fixed columns
     */
    private getCellAbsX;
}
export default Body;
