import { type DomainWithMetadata } from 'ag-charts-core';
import type { EventsHub } from '../../core/eventsHub';
import type { ChartMode } from '../chartMode';
import type { DataGroup, DataModelOptions, GroupDatumIteratorOutput, GroupedData, ProcessedData, ProcessedDataDef, PropertyDefinition, ScopeProvider, UngroupedData } from './dataModelTypes';
import type { DataChangeDescription, DataSet } from './dataSet';
import { type SortOrder } from './sortOrder';
export * from './dataModelTypes';
export { fixNumericExtent, getMissCount, datumKeys, getPathComponents, NULL_KEY_STRING, UNDEFINED_KEY_STRING, } from './data-model/utils/helpers';
/**
 * Transforms raw chart data into a structured, renderable format for series visualization.
 *
 * The DataModel is responsible for processing data through a multi-stage pipeline:
 * - Extracting and validating data from input datasets
 * - Grouping data by keys (for categorical axes or stacked series)
 * - Computing aggregations (sum, average, etc.) for grouped data
 * - Calculating domains (value ranges) for axes and scales
 * - Managing scoped data processing for multi-series charts
 * - Supporting incremental updates when data changes
 *
 * The class orchestrates several specialized subsystems:
 * - DataExtractor: Extracts and validates raw data
 * - DataGrouper: Groups data by keys
 * - Aggregator: Computes aggregations over grouped data
 * - DomainManager: Calculates and maintains value domains
 * - IncrementalProcessor: Handles efficient data updates
 *
 * Performance optimizations:
 *
 * 1. SHARED MEMORY OPTIMIZATION (groupsUnique=true):
 *    When each datum has unique keys, all groups share the same datumIndices array
 *    containing [0], since each datum's relative offset from its group is always 0.
 *
 * 2. BANDED DOMAIN PROCESSING:
 *    Large datasets are divided into bands for efficient domain calculation.
 *    Only dirty bands are recalculated during incremental updates.
 *
 * 3. BATCH MERGING:
 *    Column batches with identical characteristics (keys, invalidity) are merged
 *    to reduce processing overhead.
 *
 * 4. INCREMENTAL REPROCESSING:
 *    When supported, only changed data is reprocessed instead of full recalculation.
 */
export declare class DataModel<D extends object, K extends keyof D & string = keyof D & string, Grouped extends boolean | undefined = undefined> {
    private readonly opts;
    private readonly mode;
    private readonly suppressFieldDotNotation;
    private readonly eventsHub?;
    private readonly debug;
    private readonly scopeCache;
    private readonly keys;
    private readonly values;
    private readonly resolvers;
    private readonly scopeCacheManager;
    private readonly domainInitializer;
    private readonly domainManager;
    private readonly reducerManager;
    private readonly dataExtractor;
    private readonly dataGrouper;
    private readonly aggregator;
    private readonly incrementalProcessor;
    private readonly aggregates;
    private readonly groupProcessors;
    private readonly propertyProcessors;
    private readonly reducers;
    private readonly processors;
    constructor(opts: DataModelOptions<K, Grouped, true>, mode?: ChartMode, suppressFieldDotNotation?: boolean, eventsHub?: EventsHub | undefined);
    resolveProcessedDataDefById(scope: ScopeProvider, searchId: string): ProcessedDataDef | never;
    resolveProcessedDataIndexById(scope: ScopeProvider, searchId: string): number;
    resolveKeysById<T = string>(scope: ScopeProvider, searchId: string, processedData: UngroupedData<any> | GroupedData<any>): T[];
    hasColumnById(scope: ScopeProvider, searchId: string): boolean;
    resolveColumnById<T = any>(scope: ScopeProvider, searchId: string, processedData: UngroupedData<any> | GroupedData<any>): T[];
    resolveColumnNeedsValueOf(scope: ScopeProvider, searchId: string, processedData: UngroupedData<any> | GroupedData<any>): boolean;
    resolveMissingDataCount(scope: ScopeProvider): number;
    /**
     * Provides a convenience iterator to iterate over all of the extract datum values in a
     * specific DataGroup.
     *
     * @param scope to which datums should belong
     * @param group containing the datums
     * @param processedData containing the group
     * @param groupIndex index of the group in processedData.groups
     */
    forEachDatum(scope: ScopeProvider, processedData: GroupedData<any>, group: DataGroup, groupIndex: number): Generator<any, void, unknown>;
    private getUniqueDataSets;
    /**
     * Provides a convenience iterator to iterate over all of the extracted datum values in a
     * GroupedData.
     *
     * @param scope to which datums should belong
     * @param processedData to iterate through
     */
    forEachGroupDatum(scope: ScopeProvider, processedData: GroupedData<any>): Generator<GroupDatumIteratorOutput, void, unknown>;
    getDomain(scope: ScopeProvider, searchId: string, type: PropertyDefinition<any>['type'], processedData: ProcessedData<K>): DomainWithMetadata<any>;
    getDomainBetweenRange(scope: ScopeProvider, searchIds: string[], [i0, i1]: [number, number], processedData: ProcessedData<K>): [number, number];
    getKeySortOrder(scope: ScopeProvider, searchId: string, processedData: ProcessedData<K>): SortOrder;
    getColumnSortOrder(scope: ScopeProvider, searchId: string, processedData: ProcessedData<K>): SortOrder;
    /**
     * Get sort metadata for a key column if available.
     * Returns undefined if metadata is not available, is dirty, or data is unsorted.
     */
    getKeySortMetadata(scope: ScopeProvider, searchId: string, processedData: ProcessedData<K>): {
        sortOrder: 1 | -1 | undefined;
        isUnique?: boolean;
    } | undefined;
    processData(sources: Map<string, DataSet<unknown>>): (Grouped extends true ? GroupedData<D> : UngroupedData<D>) | undefined;
    /**
     * Determines if incremental reprocessing is supported for the given data.
     *
     * Reprocessing is supported when:
     * - For ungrouped data: No aggregates, reducers, processors, or property processors
     * - For grouped data: Additionally requires:
     *   - groupsUnique=true (each datum has unique keys)
     *   - Single data source (all scopes share same DataSet)
     *   - No invalid keys (to maintain groups.length === columns.length invariant)
     *   - All group processors support reprocessing
     *
     * When unsupported, falls back to full reprocessing automatically.
     *
     * @returns true if incremental reprocessing can be used, false otherwise
     */
    isReprocessingSupported(processedData: ProcessedData<D>): boolean;
    reprocessData(processedData: ProcessedData<D>, dataSets?: Map<DataSet<any>, DataChangeDescription | undefined>): ProcessedData<D>;
    /**
     * Recomputes domains from transformed arrays.
     * Uses BandedDomain optimization for continuous domains to avoid full rescans.
     */
    private recomputeDomains;
    private warnDataMissingProperties;
    private processScopeCache;
    private valueGroupIdxLookup;
    private valueIdxLookup;
    private extractData;
    /**
     * Reprocesses group processors for incremental updates.
     * Only processes newly inserted groups to avoid double-processing.
     * This is safe only when all group processors support reprocessing.
     * Deduplicates change descriptions to avoid processing the same groups multiple times
     * when multiple scopes share the same DataSet.
     */
    private reprocessGroupProcessors;
    private postProcessProperties;
    private reduceData;
    private shouldUseReducerBanding;
    private reduceWithBands;
    private reduceStandard;
    private postProcessData;
    private initDataDomainProcessor;
    /**
     * Collects optimization metadata for debugging purposes.
     * Only called when debug mode is enabled.
     */
    private collectOptimizationMetadata;
    /**
     * Collects reducer banding metadata for debugging purposes.
     * Tracks which reducers used banding and their performance stats.
     */
    private collectReducerBandingMetadata;
    buildAccessors(defs: Iterable<{
        property: string;
    }>): Map<string, (d: any) => any>;
}
