import { type AnyType } from '../types/any';
import { type DashboardTile } from '../types/dashboard';
import { type Explore } from '../types/explore';
import { DimensionType, MetricType, TableCalculationType, type CompiledField, type CustomSqlDimension, type Dimension, type Field, type FilterableDimension, type FilterableField, type FilterableItem, type ItemsMap, type Metric, type TableCalculation } from '../types/field';
import { FilterOperator, FilterType, UnitOfTime, type AndFilterGroup, type DashboardFieldTarget, type DashboardFilterRule, type DashboardFilters, type FilterDashboardToRule, type FilterGroup, type FilterGroupItem, type FilterRule, type Filters, type ModelRequiredFilterRule, type OrFilterGroup, type TimeBasedOverrideMap } from '../types/filter';
import { type MetricQuery } from '../types/metricQuery';
import { type ResultColumn } from '../types/results';
import { TimeFrames } from '../types/timeFrames';
export declare const getFilterRulesFromGroup: (filterGroup: FilterGroup | undefined) => FilterRule[];
export declare const getTotalFilterRules: (filters: Filters) => FilterRule[];
export declare const countTotalFilterRules: (filters: Filters) => number;
export declare const hasNestedGroups: (filters: Filters) => boolean;
export declare const getItemsFromFilterGroup: (filterGroup: FilterGroup | undefined) => FilterGroupItem[];
export declare const getFilterGroupItemsPropertyName: (filterGroup: FilterGroup | undefined) => "and" | "or";
export declare const getFilterTypeFromItemType: (type: DimensionType | MetricType | TableCalculationType) => FilterType;
export declare const getFilterTypeFromItem: (item: FilterableField) => FilterType;
export declare const timeframeToUnitOfTime: (timeframe: TimeFrames) => UnitOfTime | undefined;
export declare const supportsSingleValue: (filterType: FilterType, filterOperator: FilterOperator) => boolean;
export declare const isWithValueFilter: (filterOperator: FilterOperator) => filterOperator is FilterOperator.EQUALS | FilterOperator.NOT_EQUALS | FilterOperator.STARTS_WITH | FilterOperator.ENDS_WITH | FilterOperator.INCLUDE | FilterOperator.NOT_INCLUDE | FilterOperator.LESS_THAN | FilterOperator.LESS_THAN_OR_EQUAL | FilterOperator.GREATER_THAN | FilterOperator.GREATER_THAN_OR_EQUAL | FilterOperator.IN_THE_PAST | FilterOperator.NOT_IN_THE_PAST | FilterOperator.IN_THE_NEXT | FilterOperator.IN_THE_CURRENT | FilterOperator.NOT_IN_THE_CURRENT | FilterOperator.IN_BETWEEN | FilterOperator.NOT_IN_BETWEEN;
/**
 * An "empty" dashboard filter is active (not disabled), uses a value-requiring
 * operator, and has no value set — an unset default control the viewer fills in
 * at runtime. It must not override chart-level filters until a value is picked.
 *
 * IN_THE_CURRENT / NOT_IN_THE_CURRENT are excluded: they compile from
 * settings.unitOfTime, not values, so a value-less one is still an active
 * filter. `values` uses Array.isArray to tolerate hand-authored YAML where
 * `values:` / `values: ~` parses to JS `null` instead of `[]`.
 */
export declare const isEmptyDashboardFilterRule: (filter: {
    operator: FilterOperator;
    values?: unknown[] | null;
    disabled?: boolean;
    includeNull?: boolean;
}) => boolean;
export declare const getFilterRuleWithDefaultValue: <T extends FilterRule>(filterType: FilterType, field: FilterableField | undefined, filterRule: T, values?: AnyType[] | null, timezone?: string) => T;
export declare const getFilterRuleFromFieldWithDefaultValue: <T extends FilterRule>(field: FilterableField, filterRule: T, values?: AnyType[] | null, timezone?: string) => T;
export declare const createFilterRuleFromField: (field: FilterableField, value?: AnyType, timezone?: string) => FilterRule;
export declare const matchFieldExact: (a: Field) => (b: Field) => boolean;
export declare const matchFieldByTypeAndName: (a: Field) => (b: Field) => boolean;
export declare const matchFieldByType: (a: Field) => (b: Field) => boolean;
export declare const isTileFilterable: (tile: DashboardTile) => boolean;
export declare const applyDefaultTileTargets: (filterRule: DashboardFilterRule<FilterOperator, DashboardFieldTarget, AnyType, AnyType>, field: FilterableDimension | Metric, availableTileFilters: Record<string, (FilterableDimension | Metric)[] | undefined>) => DashboardFilterRule<FilterOperator, DashboardFieldTarget, any, any>;
export declare const createDashboardFilterRuleFromField: ({ field, availableTileFilters, isTemporary, value, }: {
    field: Exclude<FilterableItem, TableCalculation | CustomSqlDimension> | CompiledField;
    availableTileFilters: Record<string, (FilterableDimension | Metric)[] | undefined>;
    isTemporary: boolean;
    value?: unknown;
}) => FilterDashboardToRule;
export declare const createDashboardFilterRuleFromSqlColumn: ({ column, availableTileColumns, isTemporary, value, }: {
    column: ResultColumn;
    availableTileColumns: Record<string, ResultColumn[]>;
    isTemporary: boolean;
    value?: unknown;
}) => DashboardFilterRule;
type AddFilterRuleArgs = {
    filters: Filters;
    field: FilterableField;
    value?: AnyType;
    timezone?: string;
};
export declare const addFilterRule: ({ filters, field, value, timezone, }: AddFilterRuleArgs) => Filters;
/**
 * Checks if a dimension value is an invalid date before it is added to the filter
 * @param item - The field to compare against the value
 * @param value - The value to check
 * @returns True if the value is an invalid date, false otherwise
 */
export declare const isDimensionValueInvalidDate: (item: FilterableField, value: AnyType) => boolean;
/**
 * Takes a filter group and build a filters object from it based on the field type
 * @param filterGroup - The filter group to extract filters from
 * @param fields - Fields to compare against the filter group items to determine types
 * @returns Filters object with dimensions, metrics, and table calculations
 */
export declare const getFiltersFromGroup: (filterGroup: FilterGroup, fields: ItemsMap[string][]) => Filters;
export declare const deleteFilterRuleFromGroup: (filterGroup: FilterGroup, id: string) => FilterGroup;
export declare const getDashboardFilterRulesForTile: (tileUuid: string, rules: DashboardFilterRule[], needsExplicitTileOverride?: boolean) => DashboardFilterRule[];
export declare const getTabUuidsForFilterRules: (dashboardTiles: DashboardTile[] | undefined, filters: DashboardFilters, filterableFieldsByTileUuid: Record<string, FilterableDimension[]> | undefined) => Record<string, string[]>;
export declare const getDashboardFilterRulesForTileAndReferences: (tileUuid: string, references: string[], rules: DashboardFilterRule[]) => DashboardFilterRule[];
/**
 * Filter dashboard filter rules to those whose target field id is actually
 * present in the explore.
 *
 * Previously this matched by `target.tableName` against the explore's joined
 * table aliases. That diverged from the UI's "is this filter applicable to
 * this tile?" check, which matches by field id (see TileFilterConfiguration's
 * `selectedField` computation). When a filter rule's `target.tableName` is
 * stale (e.g. the dbt model was renamed since the filter was created) but
 * `target.fieldId` still resolves against the explore, the UI rendered the
 * filter as applied while the server silently dropped it — resulting in
 * unfiltered data on dashboards (notably a PII leak risk for org-scoping
 * filters). Matching by field id makes both checks use the same source of
 * truth.
 */
export declare const getDashboardFilterRulesForTables: (availableFieldIds: string[], rules: DashboardFilterRule[]) => DashboardFilterRule[];
export declare const getDashboardFilterRulesForTileAndTables: (tileUuid: string, availableFieldIds: string[], rules: DashboardFilterRule[]) => DashboardFilterRule[];
export declare const getDashboardFiltersForTileAndTables: (tileUuid: string, availableFieldIds: string[], dashboardFilters: DashboardFilters) => DashboardFilters;
export declare const getDashboardFiltersForTile: (tileUuid: string, dashboardFilters: DashboardFilters, dashboardTemporaryFilters?: DashboardFilters) => DashboardFilters;
export declare const isFilterLockedOnTab: (rule: Pick<DashboardFilterRule, "lockedTabUuids">, tabUuid: string | undefined, hasTabs: boolean) => boolean;
export type StripOverridesForLockedFiltersResult = {
    filters: DashboardFilters;
    droppedCount: number;
};
/**
 * Drop override rules that target a field whose saved filter is locked on the
 * given tab. For tab-less dashboards (`hasTabs=false`) any non-empty
 * `lockedTabUuids` is treated as a dashboard-wide lock. For tabbed dashboards
 * `tabUuid` is required to decide; when undefined nothing is stripped.
 */
export declare const stripOverridesForLockedFiltersOnTab: (saved: DashboardFilters, overrides: DashboardFilters, tabUuid: string | undefined, hasTabs: boolean) => StripOverridesForLockedFiltersResult;
export declare const addFiltersToMetricQuery: (metricQuery: MetricQuery, filters: Filters) => MetricQuery;
export declare const overrideChartFilter: (filterGroup: AndFilterGroup | OrFilterGroup, filterRules: FilterRule[], timeBasedOverrideMap: TimeBasedOverrideMap | undefined) => FilterGroup;
/**
 * Merges dashboard filters with existing filters using override tracking
 * @param filterGroup - Existing filter group to override
 * @param filterRules - Dashboard filter rules to apply
 * @param timeBasedOverrideMap - Dictionary tracking time-based field relationships
 * @returns New combined filter group with overrides applied
 */
export declare const overrideFilterGroupWithFilterRules: (filterGroup: FilterGroup | undefined, filterRules: FilterRule[], timeBasedOverrideMap: TimeBasedOverrideMap | undefined) => FilterGroup;
/**
 * Tracks time-based metric filters that need overriding via external map
 * @param metricQueryDimensionFilters - Existing dimension filters in the query
 * @param dashboardFilterRule - Dashboard filter being applied
 * @param explore - Explore context for field relationships
 * @returns Filter rule with override data for external tracking
 */
export declare const trackWhichTimeBasedMetricFiltersToOverride: (metricQueryDimensionFilters: FilterGroup | undefined, dashboardFilterRule: DashboardFilterRule, explore?: Explore) => {
    filter: DashboardFilterRule;
    overrideData?: {
        baseTimeDimensionName: string;
        fieldsToChange: string[];
    };
};
/**
 * Adds dashboard filters to a metric query while tracking time-based overrides
 * @param metricQuery - The original metric query
 * @param dashboardFilters - Dashboard filters to apply
 * @param explore - Explore context for field validation
 * @returns Enhanced metric query with merged filters and override map
 */
export declare const addDashboardFiltersToMetricQuery: (metricQuery: MetricQuery, dashboardFilters: DashboardFilters, explore?: Explore) => MetricQuery;
export declare const getAvailableFilterFieldIds: (explore: Explore) => string[];
export declare const applyDashboardFiltersForTile: ({ tileUuid, metricQuery, dashboardFilters, explore, }: {
    tileUuid: string;
    metricQuery: MetricQuery;
    dashboardFilters: DashboardFilters;
    explore: Explore;
}) => {
    metricQuery: MetricQuery;
    appliedDashboardFilters: DashboardFilters;
};
export declare const createFilterRuleFromModelRequiredFilterRule: (filter: ModelRequiredFilterRule, tableName: string) => FilterRule;
export declare const isFilterRuleInQuery: (dimension: Dimension, filterRule: FilterRule, dimensionsFilterGroup: FilterGroup | undefined, explore: Explore) => undefined | boolean;
export declare const reduceRequiredDimensionFiltersToFilterRules: (requiredFilters: ModelRequiredFilterRule[], filters: FilterGroup | undefined, explore: Explore) => FilterRule[];
export declare const resetRequiredFilterRules: (filterGroup: FilterGroup, requiredFiltersRef: string[]) => FilterGroup;
export type UnmetFilterRequirement = {
    type: 'single';
    filter: DashboardFilterRule;
} | {
    type: 'group';
    groupId: string;
    filters: DashboardFilterRule[];
};
export type FilterRequirementRule = {
    type: 'single' | 'group';
    /**
     * `requiredGroupId` for shared rules; the filter's own id for one-member
     * rules expressed via `required: true`.
     */
    id: string;
    members: DashboardFilterRule[];
};
/**
 * Unified view of filter requirements: every requirement is a rule, a set of
 * filters where at least one must be set. `required: true` is a one-member
 * rule; filters sharing a `requiredGroupId` form one rule. Rules are returned
 * in first-appearance order (dimensions before metrics). `required` wins when
 * hand-authored JSON sets both flags on the same filter.
 */
export declare const getFilterRequirementRules: (dashboardFilters: Pick<DashboardFilters, "dimensions" | "metrics">) => FilterRequirementRule[];
/**
 * A rule only satisfies a requirement when it actually filters the query:
 * disabled rules and enabled rules with a value-requiring operator and no
 * values (e.g. a stale URL override) are both valueless. Value-less operators
 * like `isNull` / `inTheCurrent` still filter.
 */
export declare const isValuelessDashboardFilterRule: (rule: DashboardFilterRule) => boolean;
/** A rule is satisfied when any member actually filters the query */
export declare const isRequirementRuleSatisfied: (rule: FilterRequirementRule) => boolean;
/**
 * Unmet requirements over dimensions + metrics, derived from
 * `getFilterRequirementRules` so the dashboard lock and the requirement UIs
 * share a single rule derivation.
 */
export declare const getUnmetFilterRequirements: (dashboardFilters: DashboardFilters) => UnmetFilterRequirement[];
export {};
//# sourceMappingURL=filters.d.ts.map