import { Group } from '@antv/g';
import { type Timer } from '@antv/vendor/d3-timer';
import { flruCache } from 'flru';
import { ColCell, CornerCell, DataCell, MergedCell, RowCell, SeriesNumberCell, TableColCell, TableSeriesNumberCell } from '../cell';
import { DataCellPool } from '../cell/pool';
import { ScrollDirection } from '../common/constant';
import { type AdjustLeafNodesParams, type CellCustomSize, type GridInfo, type HiddenColumnsInfo, type LayoutResult, type S2CellType, type ScrollOffsetConfig, type SimpleData, type ViewMeta } from '../common/interface';
import type { CellScrollOffset, CellScrollPosition, ScrollOffset } from '../common/interface/scroll';
import { PanelScrollGroup } from '../group/panel-scroll-group';
import type { SpreadSheet } from '../sheet-type';
import { ScrollBar } from '../ui/scrollbar';
import type { SelectedIds } from '../utils';
import { type PanelIndexes } from '../utils/indexes';
import { CornerBBox } from './bbox/corner-bbox';
import { PanelBBox } from './bbox/panel-bbox';
import { ColHeader, CornerHeader, Frame, RowHeader, SeriesNumberHeader, type BaseHeaderConfig, type RowHeaderConfig } from './header';
import type { TableColHeader } from './header/table-col';
import type { Hierarchy } from './layout/hierarchy';
import type { ViewCellHeights } from './layout/interface';
import { Node } from './layout/node';
import { WheelEvent as MobileWheel } from './mobile/wheelEvent';
export declare abstract class BaseFacet {
    spreadsheet: SpreadSheet;
    cornerBBox: CornerBBox;
    panelBBox: PanelBBox;
    backgroundGroup: Group;
    panelGroup: Group;
    panelScrollGroup: PanelScrollGroup;
    foregroundGroup: Group;
    /**
     * 当前布局节点信息
     * @private 内部消费, 外部调用请使用 facet.getLayoutResult()
     */
    protected layoutResult: LayoutResult;
    viewCellWidths: number[];
    viewCellHeights: ViewCellHeights;
    protected mobileWheel: MobileWheel;
    protected timer: Timer;
    hScrollBar: ScrollBar;
    hRowScrollBar: ScrollBar;
    vScrollBar: ScrollBar;
    rowHeader: RowHeader | null;
    columnHeader: ColHeader | TableColHeader;
    cornerHeader: CornerHeader;
    seriesNumberHeader: SeriesNumberHeader | null;
    centerFrame: Frame;
    gridInfo: GridInfo;
    protected textWrapNodeHeightCache: flruCache<number>;
    protected textWrapTempCornerCell: CornerCell | null;
    protected textWrapTempRowCell: RowCell | DataCell;
    protected textWrapTempColCell: ColCell | TableColCell;
    protected dataCellPool: DataCellPool;
    customRowHeightStatusMap: Record<string, boolean>;
    protected abstract getCornerCellInstance(node: Node, spreadsheet: SpreadSheet, config: Partial<BaseHeaderConfig>): CornerCell | null;
    protected abstract getRowCellInstance(node: Node | ViewMeta, spreadsheet: SpreadSheet, config: Partial<BaseHeaderConfig>): RowCell | DataCell;
    protected abstract getColCellInstance(node: Node, spreadsheet: SpreadSheet, config: Partial<BaseHeaderConfig>): ColCell;
    protected abstract doLayout(): LayoutResult;
    protected abstract clip(scrollX: number, scrollY: number): void;
    abstract calculateXYIndexes(scrollX: number, scrollY: number): PanelIndexes;
    abstract getViewCellHeights(layoutResult?: LayoutResult): ViewCellHeights;
    abstract getViewCellHeights(): ViewCellHeights;
    abstract addDataCell(cell: DataCell): void;
    abstract getCellMeta(rowIndex: number, colIndex: number): ViewMeta | null;
    abstract getContentWidth(): number;
    abstract getContentHeight(): number;
    protected scrollFrameId: ReturnType<typeof requestAnimationFrame> | null;
    protected scrollDirection: ScrollDirection;
    get scrollBarTheme(): import("../common/interface").DeepRequired<import("../common/interface").ScrollBarTheme>;
    get scrollBarSize(): number;
    protected preCellIndexes: PanelIndexes | null;
    constructor(spreadsheet: SpreadSheet);
    protected shouldRender(): boolean;
    getLayoutResult: () => LayoutResult;
    protected initTextWrapTemp(): void;
    protected initGroups(): void;
    protected initForegroundGroup(): void;
    protected initBackgroundGroup(): void;
    protected initPanelGroups(): void;
    getCellCustomSize(node: Node | null, customSize: CellCustomSize): number | null | undefined;
    protected getRowCellDraggedWidth(node: Node): number | undefined;
    protected getRowCellDraggedHeight(node: Node): number | undefined;
    protected isCustomRowCellHeight(node: Node): boolean;
    protected getCustomRowCellHeight(node: Node): number | null | undefined;
    protected getRowCellHeight(node: Node): number | undefined;
    protected getColCellDraggedWidth(node: Node): number | undefined;
    protected getColCellDraggedHeight(node: Node): number | undefined;
    protected getColNodeHeight(options: {
        colNode: Node;
        colsHierarchy: Hierarchy;
        useCache?: boolean;
        cornerNodes?: Node[];
    }): number;
    protected getDefaultColNodeHeight(colNode: Node, colsHierarchy: Hierarchy): number;
    protected getNodeAdaptiveHeight(options: {
        meta: Node | ViewMeta;
        cell: S2CellType;
        defaultHeight?: number;
        useCache?: boolean;
    }): number;
    /**
     * 根据叶子节点宽度计算所有父级节点宽度和 x 坐标
     */
    protected calculateColParentNodeWidthAndX(colLeafNodes: Node[]): void;
    /**
     * 将每一层级的采样节点更新为高度最大的节点 (未隐藏, 非汇总节点)
     */
    protected updateColsHierarchySampleMaxHeightNodes(colsHierarchy: Hierarchy, rowsHierarchy?: Hierarchy): void;
    hideScrollBar: () => void;
    delayHideScrollBar: import("lodash").DebouncedFunc<() => void>;
    delayHideScrollbarOnMobile: () => void;
    showVerticalScrollBar: () => void;
    showHorizontalScrollBar: () => void;
    onContainerWheelForMobileCompatibility: () => void;
    onContainerWheel: () => void;
    getMobileWheelDeltaY: (deltaY: number) => number;
    onContainerWheelForPc: () => void;
    onContainerWheelForMobile: () => void;
    bindEvents: () => void;
    render(): void;
    /**
     * 在每次render, 校验scroll offset是否在合法范围中
     * 比如在滚动条已经滚动到100%的状态的前提下：（ maxAvailableScrollOffsetX = colsHierarchy.width - viewportBBox.width ）
     *     此时changeSheetSize，sheet从 small width 变为 big width
     *     导致后者 viewport 区域更大，其结果就是后者的 maxAvailableScrollOffsetX 更小
     *     此时就需要重置 scrollOffsetX，否则就会导致滚动过多，出现空白区域
     */
    protected adjustScrollOffset(): void;
    getSeriesNumberWidth(): number;
    getCanvasSize(): {
        width: number;
        height: number;
    };
    /**
     * @alias s2.interaction.scrollTo(offsetConfig)
     */
    updateScrollOffset(offsetConfig: ScrollOffsetConfig): void;
    getPaginationScrollY(): number;
    destroy(): void;
    setScrollOffset: (scrollOffset: ScrollOffset) => void;
    getScrollOffset: () => Required<ScrollOffset>;
    resetScrollX: () => void;
    resetRowScrollX: () => void;
    resetScrollY: () => void;
    resetScrollOffset: () => void;
    emitPaginationEvent: () => void;
    protected unbindEvents: () => void;
    calculateCellWidthHeight: () => void;
    /**
     * 提供给明细表做 rowOffsets 计算的 hook
     */
    protected abstract calculateRowOffsets(): void;
    getRealScrollX: (scrollX: number, hRowScroll?: number) => number;
    protected calculateCornerBBox(): void;
    protected calculatePanelBBox(): void;
    getRealWidth: () => number;
    getCellRange(): {
        start: number;
        end: number;
    };
    getRealHeight: () => number;
    clearAllGroup(): void;
    scrollWithAnimation: (offsetConfig?: ScrollOffsetConfig, duration?: number, cb?: () => void) => void;
    scrollImmediately: (offsetConfig?: ScrollOffsetConfig) => void;
    /**
     * @param skipScrollEvent 不触发 S2Event.GLOBAL_SCROLL
     */
    startScroll: (skipScrollEvent?: boolean) => void;
    protected getRendererHeight: () => number;
    protected getAdjustedScrollOffset: ({ scrollX, scrollY, rowHeaderScrollX, }: ScrollOffset) => ScrollOffset;
    protected renderRowScrollBar(rowHeaderScrollX: number): void;
    getValidScrollBarOffset(offset: number, maxOffset: number): number;
    renderHScrollBar(width: number, realWidth: number, scrollX: number): void;
    protected getScrollbarPosition(): {
        maxX: number;
        maxY: number;
    };
    renderVScrollBar(height: number, realHeight: number, scrollY: number): void;
    getScrollBarOffset: (offset: number, scrollbar: ScrollBar) => number;
    isScrollOverThePanelArea: ({ offsetX, offsetY }: CellScrollOffset) => boolean;
    isScrollOverTheCornerArea: ({ offsetX, offsetY }: CellScrollOffset) => boolean;
    updateHorizontalRowScrollOffset: ({ offset, offsetX, offsetY, }: CellScrollOffset) => void;
    updateHorizontalScrollOffset: ({ offset, offsetX, offsetY, }: CellScrollOffset) => void;
    isScrollToLeft: ({ deltaX, offsetX, offsetY }: CellScrollOffset) => boolean;
    isScrollToRight: ({ deltaX, offsetX, offsetY }: CellScrollOffset) => boolean;
    isScrollToTop: (deltaY: number) => boolean;
    isScrollToBottom: (deltaY: number) => boolean;
    isVerticalScrollOverTheViewport: (deltaY: number) => boolean;
    isHorizontalScrollOverTheViewport: (scrollOffset: CellScrollOffset) => boolean;
    /**
     * 在当前表格滚动分两种情况:
     *  1. 当前表格无滚动条: 无需阻止外部容器滚动
     *  2. 当前表格有滚动条:
     *    - 未滚动到顶部或底部: 当前表格滚动, 阻止外部容器滚动
     *    - 滚动到顶部或底部: 恢复外部容器滚动
     */
    isScrollOverTheViewport: (scrollOffset: CellScrollOffset) => boolean;
    cancelScrollFrame: () => boolean;
    clearScrollFrameIdOnMobile: () => void;
    /**
     * https://developer.mozilla.org/zh-CN/docs/Web/CSS/overscroll-behavior
     * 阻止外部容器滚动: 表格是虚拟滚动, 这里按照标准模拟浏览器的 [overscroll-behavior] 实现
     * 1. auto => 只有在滚动到表格顶部或底部时才触发外部容器滚动
     * 1. contain => 默认的滚动边界行为不变（“触底”效果或者刷新），但是临近的滚动区域不会被滚动链影响到
     * 2. none => 临近滚动区域不受到滚动链影响，而且默认的滚动到边界的表现也被阻止
     * 所以只要不为 `auto`, 或者表格内, 都需要阻止外部容器滚动
     */
    protected stopScrollChainingIfNeeded: (event: WheelEvent) => void;
    protected stopScrollChaining: (event: WheelEvent) => void;
    onWheel: (event: WheelEvent) => void;
    /**
     * Translate panelGroup, rowHeader, cornerHeader, columnHeader ect
     * according to new scroll offset
     * @param scrollX
     * @param scrollY
     * @param hRowScroll
     * @protected
     */
    protected translateRelatedGroups(scrollX: number, scrollY: number, hRowScroll: number): void;
    protected getCenterFrameScrollX(scrollX: number): number;
    createDataCell(viewMeta: ViewMeta | null): DataCell | undefined;
    realDataCellRender: (scrollX: number, scrollY: number) => void;
    protected init(): void;
    protected renderBackground(): void;
    /**
     * Render all scrollbars, default horizontal scrollbar only control viewport
     * area(it means not contains row header)
     * 1. individual row scrollbar
     * 2. horizontal scroll bar(can control whether contains row header)
     * 3. vertical scroll bar
     */
    protected renderScrollBars(): void;
    /**
     * Render all headers in {@link #foregroundGroup}, contains:
     * 1. row header
     * 2. col header
     * 3. center frame
     * 4. corner header
     * 5. series number header
     */
    protected renderHeaders(): void;
    protected getRowHeaderCfg(): RowHeaderConfig;
    protected getRowHeader(): RowHeader | null;
    protected getColHeader(): ColHeader;
    protected getCornerHeader(): CornerHeader;
    protected getSeriesNumberHeader(): SeriesNumberHeader | null;
    protected getCenterFrame(): Frame;
    protected getGridInfo: () => {
        cols: number[];
        rows: number[];
    };
    updatePanelScrollGroup(): void;
    /**
     * @param skipScrollEvent: 不触发 GLOBAL_SCROLL 事件
     */
    protected dynamicRenderCell(skipScrollEvent?: boolean): void;
    protected emitScrollEvent(position: CellScrollPosition): void;
    protected onAfterScroll: import("lodash").DebouncedFunc<() => void>;
    protected saveInitColumnLeafNodes(columnNodes?: Node[]): void;
    getHiddenColumnsInfo(columnNode: Node): HiddenColumnsInfo | undefined;
    updateCustomFieldsSampleNodes(colsHierarchy: Hierarchy): void;
    /**
     * @description 自定义行头时, 叶子节点层级不定, 需要自动对齐其宽度, 填充空白
     * -------------------------------------------------
     * |  自定义节点 a-1  |  自定义节点 a-1-1              |
     * |-------------   |-------------     |------------|
     * |  自定义节点 b-1  |  自定义节点 b-1-1 |  指标 1    |
     * -------------------------------------------------
     */
    adjustCustomRowLeafNodesWidth(params: AdjustLeafNodesParams): void;
    /**
     * @description 自定义列头时, 叶子节点层级不定, 需要自动对齐其高度, 填充空白
     * ------------------------------------------------------------------------
     * |                       自定义节点 a-1                                   |
     * |----------------------------------------------------------------------|
     * |                 自定义节点 a-1-1               |                       |
     * |-------------|-------------|------------------|   自定义节点 a-1-2      |
     * |   指标 1    |  自定义节点 a-1-1-1    | 指标 2  |                        |
     * ----------------------------------------------------------------------
     */
    adjustCustomColLeafNodesHeight(params: AdjustLeafNodesParams): void;
    adjustLeafNodesSize(type: 'width' | 'height'): ({ leafNodes, hierarchy }: AdjustLeafNodesParams) => void;
    /**
     * 获取表头节点 (角头,序号,行头,列头) (含可视区域)
     * @example 获取全部: facet.getHeaderNodes()
     * @example 获取一组 facet.getHeaderNodes(['root[&]浙江省[&]宁波市', 'root[&]浙江省[&]杭州市'])
     */
    getHeaderNodes(nodeIds?: string[]): Node[];
    /**
     * 获取角头节点
     */
    getCornerNodes(): Node[];
    /**
     * 获取序号节点
     */
    getSeriesNumberNodes(): Node[];
    /**
     * 获取列头节点 (含非可视区域)
     * @description 获取列头单元格 (可视区域内) facet.getColCells()
     * @example 获取全部: facet.getColNodes()
     * @example 指定层级: facet.getColNodes(level)
     */
    getColNodes(level?: number): Node[];
    getTopLevelColNodes(): Node[];
    /**
     * 根据 id 获取指定列头节点
     * @example facet.getColNodeById('root[&]节点1[&]数值')
     */
    getColNodeById(nodeId: string): Node | undefined;
    /**
     * 根据列头索引获取指定列头节点
     * @example facet.getColNodeByIndex(colIndex)
     */
    getColNodeByIndex(colIndex: number): Node | undefined;
    /**
     * 获取在索引范围内的列头叶子节点
     * @example facet.getColLeafNodesByRange(0,10) 获取索引范围在 0（包括 0） 到 10（包括 10）的列头叶子节点
     */
    getColLeafNodesByRange(minIndex: number, maxIndex: number): Node[];
    /**
     * 根据列头索引获取指定列头叶子节点
     * @example facet.getColLeafNodes(colIndex)
     */
    getColLeafNodeByIndex(colIndex: number): Node | undefined;
    /**
     * 根据 field 获取指定列头节点
     * @example facet.getColCellNodeByField('number')
     */
    getColNodesByField(nodeField: string): Node[];
    /**
     * 获取列头叶子节点节点 (含非可视区域)
     */
    getColLeafNodes(): Node[];
    /**
     * 获取列头小计/总计节点 (含非可视区域)
     * @example 获取全部: facet.getColTotalsNodes()
     * @example 指定层级: facet.getColTotalsNodes(level)
     */
    getColTotalsNodes(level?: number): Node[];
    /**
     * 获取列头小计节点 (含非可视区域)
     * @example 获取全部: facet.getColSubTotalsNodes()
     * @example 指定层级: facet.getColSubTotalsNodes(level)
     */
    getColSubTotalsNodes(level?: number): Node[];
    /**
     * 获取列头总计节点 (含非可视区域)
     * @example 获取全部: facet.getColGrandTotalsNodes()
     * @example 指定层级: facet.getColGrandTotalsNodes(level)
     */
    getColGrandTotalsNodes(level?: number): Node[];
    /**
     * 获取行头节点 (含非可视区域)
     * @description 获取行头单元格 (可视区域内) facet.getRowCells()
     * @example 获取全部: facet.getRowNodes()
     * @example 指定层级: facet.getRowNodes(level)
     */
    getRowNodes(level?: number): Node[];
    /**
     * 根据 id 获取单个行头节点
     * @example facet.getRowNodeById('root[&]节点1[&]数值')
     */
    getRowNodeById(nodeId: string): Node | undefined;
    /**
     * 根据行头索引获取指定列头节点
     * @example facet.getRowNodeByIndex(rowIndex)
     */
    getRowNodeByIndex(rowIndex: number): Node | undefined;
    /**
     * 根据行头索引获取指定列头叶子节点
     * @example facet.getRowLeafNodeByIndex(rowIndex)
     */
    getRowLeafNodeByIndex(rowIndex: number): Node | undefined;
    /**
     * 获取在索引范围内的行头叶子节点
     * @example facet.getRowLeafNodesByRange(0,10) 获取索引范围在 0（包括 0） 到 10（包括 10）的行头叶子节点
     */
    getRowLeafNodesByRange(minIndex: number, maxIndex: number): Node[];
    /**
     * 根据 field 获取行头节点
     * @example facet.getRowNodeByField('number')
     */
    getRowNodesByField(nodeField: string): Node[];
    /**
     * 获取行头叶子节点节点 (含非可视区域)
     * @example 获取全部: facet.getRowLeafNodes()
     */
    getRowLeafNodes(): Node[];
    /**
     * 获取行头小计/总计节点 (含非可视区域)
     * @example 获取全部: facet.getRowTotalsNodes()
     * @example 指定层级: facet.getRowTotalsNodes(level)
     */
    getRowTotalsNodes(level?: number): Node[];
    /**
     * 获取行头小计节点 (含非可视区域)
     * @example 获取全部: facet.getRowSubTotalsNodes()
     * @example 指定层级: facet.getRowSubTotalsNodes(level)
     */
    getRowSubTotalsNodes(level?: number): Node[];
    /**
     * 获取行头总计节点 (含非可视区域)
     * @example 获取全部: facet.getRowGrandTotalsNodes()
     * @example 指定层级: facet.getRowGrandTotalsNodes(level)
     */
    getRowGrandTotalsNodes(level?: number): Node[];
    /**
     * 获取单元格的所有子节点 (含非可视区域)
     * @example
     * const rowCell = facet.getRowCells()[0]
     * facet.getCellChildrenNodes(rowCell)
     */
    getCellChildrenNodes: (cell: S2CellType) => Node[];
    /**
     * 获取数值单元格 (不含可视区域)
     * @description 由于虚拟滚动, 按需加载的特性, 非可视区域的单元格未被实例化
     * @example 获取非可视区域的数值节点 facet.getCellMeta(rowIndex, colIndex)
     */
    getDataCells(): DataCell[];
    /**
     * 获取行头单元格 (不含可视区域)
     */
    getRowCells(): RowCell[];
    /**
     * 获取行头叶子节点单元格 (不含可视区域)
     */
    getRowLeafCells(): RowCell[];
    /**
     * 获取列头单元格 (不含可视区域)
     */
    getColCells(): ColCell[];
    /**
     * 获取列头叶子节点单元格 (不含可视区域)
     */
    getColLeafCells(): ColCell[];
    /**
     * 获取合并单元格 (不含可视区域)
     */
    getMergedCells(): MergedCell[];
    /**
     * 获取角头单元格 (不含可视区域)
     */
    getCornerCells(): CornerCell[];
    protected filterCells(cells: S2CellType[], filterIds?: string[] | SelectedIds): S2CellType[];
    /**
     * 获取序号单元格 (不含可视区域)
     */
    abstract getSeriesNumberCells(): SeriesNumberCell[] | TableSeriesNumberCell[];
    /**
     * 获取表头单元格 (序号,角头,行头,列头) (不含可视区域)
     * @example 获取全部: facet.getHeaderCells()
     * @example 获取一组 facet.getHeaderCells(['root[&]浙江省[&]宁波市', 'root[&]浙江省[&]杭州市'])
     */
    getHeaderCells(cellIds?: string[] | SelectedIds): S2CellType<ViewMeta>[];
    /**
     * 根据单元格 id 获取指定单元格 (不含可视区域)
     * @example facet.getCellById('root[&]浙江省[&]宁波市')
     */
    getCellById(cellId: string): S2CellType<ViewMeta> | undefined;
    /**
     * 根据单元格 field 获取指定单元格 (不含可视区域)
     * @example facet.getCellByField('city')
     */
    getCellsByField(cellField: string): S2CellType<ViewMeta>[];
    /**
     * 获取所有单元格 (角头,行头,列头,数值) (不含可视区域)
     * @example 获取全部: facet.getCells()
     * @example 获取一组 facet.getCells(['root[&]浙江省[&]宁波市', 'root[&]浙江省[&]杭州市'])
     */
    getCells(cellIds?: string[]): S2CellType<ViewMeta>[];
    getInitColIndexLeafNodes(): Node[];
    getInitColLeafNodes(): Node[];
    clearInitColLeafNodes(): void;
    /**
     * @tip 和 this.spreadsheet.measureTextWidth() 的区别在于:
     * 1. 额外添加一像素余量，防止 maxLabel 有多个同样长度情况下，一些 label 不能展示完全, 出现省略号
     * 2. 测量时, 文本宽度取整, 避免子像素的不一致性
     */
    protected measureTextWidth(text: SimpleData, font: unknown): number;
    protected initCellPool(): void;
}
