import { ReactNode } from 'react';
import { AsyncMultiSelectFilter, AsyncSelectFilter, BooleanFilter, CustomFilter, DateFilter, DateListFilter, DateListLibraryOptionId, DateRangeFilter, Filter, MultiSelectFilter, NumericRangeFilter, SearchFilter, SingleSelectFilter, TextInputFilter, TreeFilter, AsyncTreeFilter } from '../types';
/**
 * Context passed to renderBarControl — the inline FilterBar control for a filter.
 *
 * `controlledFiltering` mirrors the FilterBar prop of the same name: when true,
 * select-style adapters should opt their underlying menu into confirmation mode
 * (clicks update a draft, Apply commits, dismiss cancels).
 */
export type BarControlRenderCtx<F extends Filter> = {
    filter: F;
    updateFilter: (filterId: string, value: unknown, submit: boolean) => void;
    controlledFiltering: boolean;
};
/**
 * Context passed to renderDrawer — the FilterDrawer form control for a filter.
 * Receives both the draft filter (with current draft selection) and the
 * original filter (for stable references to consumer-supplied data).
 *
 * `requestDateListDialog` is provided so the dateList adapter can ask the drawer
 * to open its shared DateListDialog when a library option is picked.
 */
export type DrawerRenderCtx<F extends Filter> = {
    originalFilter: F;
    draftFilter: F;
    onDraftChange: (filterId: string, value: unknown) => void;
    requestDateListDialog: (filterId: string, libraryId: DateListLibraryOptionId) => void;
};
/**
 * Per-filter-type adapter. Each filter variant contributes one adapter
 * implementing every operation FilterBar / FilterDrawer need.
 *
 * F = the specific Filter variant
 * V = the value type (what getValue / setValue traffic in)
 *
 * `renderBarControl` returns the complete inline UI for this filter type.
 * Most adapters compose `SelectMenu` / `MultiSelectMenu` (or one of the
 * filter-specific shells like `FilterDateSingle`) directly, supplying the
 * trigger via render-prop. The `custom` adapter composes `FilterPopoverButton`
 * for fully consumer-rendered popover bodies; `boolean` uses a toggle button
 * with no popover at all. The adapter type itself stays agnostic about UI
 * shape.
 */
export type FilterTypeAdapter<F extends Filter, V> = {
    getValue: (filter: F) => V;
    setValue: (filter: F, value: V) => F;
    reset: (filter: F) => F;
    isActive: (filter: F) => boolean;
    preserveState: (newFilter: F, existingFilter: F) => F;
    cloneWithItemRefs: (filter: F) => F;
    renderBarControl: (ctx: BarControlRenderCtx<F>) => ReactNode;
    renderDrawer: (ctx: DrawerRenderCtx<F>) => ReactNode;
    formatLabel: (filter: F) => ReactNode;
    isSelected: (filter: F) => boolean;
};
/**
 * Map from a Filter's `type` discriminant to its specific variant.
 * Used to keep the adapter map exhaustive at the type level.
 */
export type FilterVariantMap = {
    boolean: BooleanFilter;
    custom: CustomFilter<any>;
    singleSelect: SingleSelectFilter;
    multiSelect: MultiSelectFilter;
    date: DateFilter;
    dateRange: DateRangeFilter;
    dateList: DateListFilter;
    asyncSelect: AsyncSelectFilter;
    asyncMultiSelect: AsyncMultiSelectFilter;
    tree: TreeFilter;
    asyncTree: AsyncTreeFilter;
    numericRange: NumericRangeFilter;
    textInput: TextInputFilter;
    search: SearchFilter;
};
/**
 * Exhaustive map from Filter["type"] to its adapter. Forces compile-time
 * completeness when a new filter type is added.
 */
export type FilterAdapters = {
    [K in keyof FilterVariantMap]: FilterTypeAdapter<FilterVariantMap[K], any>;
};
