/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */
import { Collection } from '@nocobase/flow-engine';
import { FilterOption, UseFilterOptionsArgs } from '../../../flow/components/filter/useFilterOptions';
import { CollectionFilterItemValue, createCollectionFilterItem } from './CollectionFilterItem';
/** A single condition row (`{ path, operator, value }`) or a nested group. */
export type FilterGroupItem = CollectionFilterItemValue | FilterGroupValue;
/**
 * Reactive shape consumed by `FilterContainer` / `FilterGroup`. `logic` is the join (`$and` / `$or`) and `items` is a heterogeneous list of leaf conditions and nested groups.
 */
export type FilterGroupValue = {
    logic: '$and' | '$or';
    items: FilterGroupItem[];
};
/** Compiled filter param accepted by NocoBase resource `list`. */
export type CompiledFilter = Record<string, unknown> | undefined;
interface FilterCtxModel {
    translate: (key: string) => string;
    dispatchEvent: (event: 'submit' | 'reset' | (string & {})) => void;
}
export interface FilterCtx {
    model: FilterCtxModel;
}
export declare function decompileFilterGroup(filter: CompiledFilter): FilterGroupValue | undefined;
/**
 * Compile a reactive filter group into the `{ $and: [{ path: { op: val } }] }` envelope accepted by NocoBase's resource `list` filter param. Returns `undefined` when the group is empty so callers can drop the param.
 *
 * Mirrors v1's `removeNullCondition` + filter compile path, but works on the v2 `{ logic, items }` group structure rather than v1's Formily-bracketed `$and.0.path.$eq` shape:
 *
 * - Rows missing `path` or `operator` are dropped (still mid-edit).
 * - Rows whose `value` is empty (`undefined`, `''`, `[]`, `{}`) are dropped — matches v1, which sends `filter={}` for a row with only a field/operator picked. Sending `{lockedTs:{}}` would 500.
 * - Dotted association paths (`user.createdBy.password`) are expanded into nested objects — matches v1's payload shape, which the server resolves along the association chain rather than treating the dotted string as a single key.
 * - Empty groups (after pruning) propagate as `undefined` so the outermost caller can drop the whole `filter` param.
 */
export declare function compileFilterGroup(group: FilterGroupValue | undefined): CompiledFilter;
/** Which footer button triggered the apply — useful for closing a popover on Submit but keeping it open on Reset. */
export type FilterApplyAction = 'submit' | 'reset';
export interface UseFilterActionPropsArgs extends UseFilterOptionsArgs {
    /** Collection whose fields populate the filter row's field picker. */
    collection: Collection | undefined;
    /** Previously compiled filter param used to seed the editable filter group. */
    initialValue?: CompiledFilter;
    /**
     * Called when the user submits or resets the filter popover. Receives the compiled filter param (`undefined` when cleared) and which footer button triggered the call. Typical implementation: `(filter, action) => { listRequest.run(filter); if (action === 'submit') closePopover(); }`.
     */
    onApply: (filter: CompiledFilter, action: FilterApplyAction) => void;
}
export interface UseFilterActionPropsResult {
    /**
     * Reactive filter group state. Pass directly to `<FilterContent value={...}>`. Stable across renders.
     */
    value: FilterGroupValue;
    /** Field-option tree (for inspection or custom badges). */
    options: FilterOption[];
    /** Bound `FilterItem` component to plug into `<FilterContent FilterItem={...}>`. */
    FilterItem: ReturnType<typeof createCollectionFilterItem> | undefined;
    /**
     * Ready-to-use `ctx` for `<FilterContent ctx={...}>`. Wires Submit / Reset buttons to `onSubmit` / `onReset` below.
     */
    ctx: FilterCtx;
    /** Imperative trigger — submit current group as a compiled filter. */
    onSubmit: () => void;
    /** Imperative trigger — clear the group and emit an empty filter. */
    onReset: () => void;
    /**
     * Count of top-level condition rows. Useful for showing a badge like `Filter (3)` on the trigger button — matches v1's `field.title = t('{{count}} filter items', { count })`.
     */
    conditionCount: number;
}
/**
 * v2 equivalent of v1's `useFilterActionProps` for non-schema surfaces (settings pages, panels, side drawers). Bundles three things v1's hook returned implicitly through schema:
 *
 * - A reactive `{ logic, items }` group state that `<FilterContent>` reads.
 * - A bound `FilterItem` component (driven by `createCollectionFilterItem`).
 * - A `ctx` object that turns `<FilterContent>`'s `dispatchEvent('submit' | 'reset')` into a compiled filter param passed to `onApply`.
 *
 * Pair with antd `Popover` to recreate the legacy `Filter.Action` UX:
 *
 * ```tsx
 * const { value, ctx, FilterItem, onSubmit, conditionCount } = useFilterActionProps({
 *   collection,
 *   onApply: (filter) => listRequest.run(filter),
 *   t,
 * });
 * return (
 *   <Popover content={<FilterContent value={value} ctx={ctx} FilterItem={FilterItem} />}>
 *     <Button>{t('Filter')}{conditionCount ? ` (${conditionCount})` : ''}</Button>
 *   </Popover>
 * );
 * ```
 */
export declare function useFilterActionProps(args: UseFilterActionPropsArgs): UseFilterActionPropsResult;
export {};
