import { ReactNode } from 'react';
import { Filter } from '../FilterBar/internal/types';
/**
 * A consumer-owned preset of filter values. The component never mutates these
 * — it only emits callbacks describing the user's intent (apply, save, update,
 * delete). The consumer holds the source-of-truth list and re-renders
 * `SavedFiltersButton` with the updated array.
 *
 * `filters` is a snapshot of the bar's full filter schema with the preset's
 * values baked in, in the same shape as `FilterBar`'s `filters` prop. That
 * uniformity lets the edit drilldown reuse the FilterBar adapter
 * `renderDrawer` machinery without bespoke per-filter-type rendering.
 */
export type SavedFilter = {
    id: string;
    name: string;
    filters: Filter[];
    /**
     * When true, this preset cannot be edited from the Edit drawer — its row
     * renders without an Edit affordance and the drilldown is unreachable.
     * Useful for marking system / seeded presets as immutable while still
     * letting users edit their own.
     */
    disableEdit?: boolean;
    /**
     * When true, the "Delete Filter" button is omitted from the drilldown
     * footer for this preset. Independent of `disableEdit` — a preset can be
     * editable but not deletable, or vice versa.
     */
    disableDelete?: boolean;
};
/**
 * Text overrides for the auto-managed success / error Alerts that appear on
 * the "Edit Saved Filters" drawer after a save, update, delete, or reorder
 * settles.
 *
 * All entries are optional; unset values fall back to generic defaults.
 */
export type SavedFiltersAlertText = {
    saveSuccess?: string;
    saveError?: string;
    updateSuccess?: string;
    updateError?: string;
    deleteSuccess?: string;
    deleteError?: string;
    /**
     * Surfaced on the list view when `onReorderSavedFilters` rejects. No
     * matching `reorderSuccess` — successful reorders don't show an alert,
     * because the new order is its own visible confirmation.
     */
    reorderError?: string;
};
export type SavedFiltersButtonProps = {
    /** The presets to list. Consumer owns the storage. */
    savedFilters: SavedFilter[];
    /**
     * The filters currently committed in the FilterBar (or any analogous
     * filter source). Used as the snapshot payload when the user clicks
     * "Save Current Filter."
     */
    currentFilters: Filter[];
    /**
     * Called when the user picks a preset from the list. The consumer is
     * responsible for pushing `saved.filters` into their FilterBar (or
     * equivalent) state. The popover closes immediately after click.
     */
    onApplySavedFilter: (saved: SavedFilter) => void;
    /**
     * Called when the user submits the "Save Current Filter" drawer. The
     * payload `filters` is the snapshot of `currentFilters` at the moment the
     * drawer opened. May return a promise; while pending, the Add button
     * shows a loading state. Rejecting surfaces an error alert; resolving
     * surfaces a success alert and closes the drawer.
     */
    onSaveCurrentFilter: (payload: {
        name: string;
        filters: Filter[];
    }) => void | Promise<void>;
    /**
     * Called when the user submits the drilldown's "Update Filter" action.
     * Same async / alert semantics as `onSaveCurrentFilter`.
     */
    onUpdateSavedFilter: (id: string, update: {
        name: string;
        filters: Filter[];
    }) => void | Promise<void>;
    /**
     * Called when the user clicks "Delete Filter" in the drilldown. Same
     * async / alert semantics as `onSaveCurrentFilter`.
     */
    onDeleteSavedFilter: (id: string) => void | Promise<void>;
    /**
     * Optional validation for the name field in the save / edit flows. Return
     * an error string to block submit (Add / Update is disabled); return
     * `undefined` when valid. The optional `currentId` is set during an edit
     * flow so the consumer can permit the row's own name in uniqueness
     * checks.
     */
    validateName?: (name: string, currentId?: string) => string | undefined;
    /** Optional override for the auto-managed alert text. */
    alertText?: SavedFiltersAlertText;
    /**
     * Optional id of the preset that is currently applied. When set, the
     * matching row in the popover renders with a check affordance. The
     * component does no comparison itself — the consumer is responsible for
     * tracking which preset (if any) reflects the current filter state, and
     * for clearing the id when the filters drift (e.g. the user edited a
     * filter directly).
     *
     * Defaults to `undefined`, in which case no row is marked active.
     */
    activeSavedFilterId?: string;
    /**
     * Optional trigger label override.
     * @default "Saved Filters"
     */
    label?: string;
    /**
     * Optional override for the popover's empty-state content, shown when
     * `savedFilters` is empty. Defaults to "No saved filters yet."
     *
     * - Pass a `string` to keep the default subdued/small `Text` styling — only
     *   the wording changes.
     * - Pass any other `ReactNode` (a CTA, an illustration, a styled block) to
     *   take full control of the empty-state content.
     *
     * Separately, when `savedFilters` is empty the "Edit Saved Filters" footer
     * button is disabled, so this empty-state is the only thing the user sees
     * in the popover.
     */
    emptyState?: ReactNode;
    /**
     * Called when the user drags a preset to a new position in the "Edit Saved
     * Filters" drawer. The payload is the full list of preset ids in their new
     * order; the consumer is responsible for re-sorting their `savedFilters`
     * array to match.
     *
     * Providing this callback opts the Edit drawer into drag-to-reorder UI —
     * each row picks up a drag handle and keyboard-accessible drop affordance.
     * Omitting it renders the list as a static stack with no handles.
     *
     * May return a promise. A rejection surfaces as a danger alert on the
     * list view using `alertText.reorderError` (or the thrown Error's message
     * when present).
     */
    onReorderSavedFilters?: (orderedIds: string[]) => void | Promise<void>;
};
