type CommonParams = {
    page?: number;
    page_size?: number;
};
type MergeParams<M, O> = {
    [K in keyof M]: M[K];
} & {
    [K in keyof O]?: O[K];
};
type EmptyParamValue = '' | null | undefined;
type SanitizedMandatoryParams<M> = {
    [K in keyof M]: Exclude<M[K], EmptyParamValue>;
};
type SanitizedOptionalParams<O> = {
    [K in keyof O as Exclude<O[K], EmptyParamValue> extends never ? never : K]?: Exclude<O[K], EmptyParamValue>;
};
type RequestSafeParams<M, O> = SanitizedMandatoryParams<M> & SanitizedOptionalParams<O>;
type ParamCodec<TValue> = {
    parse?: (value: string | string[] | null, context: {
        key: string;
        searchParams: URLSearchParams;
    }) => TValue;
    serialize?: (value: TValue, context: {
        key: string;
    }) => string | string[] | null | undefined;
};
type ParamCodecs<TParams extends Record<string, unknown>> = Partial<{
    [K in keyof TParams]: ParamCodec<TParams[K]>;
}>;
type ParamKey<TParams extends Record<string, unknown>> = Extract<keyof TParams, string>;
type ProtectedParamCodec<TValue> = true | {
    parse?: (value: string | string[] | null, context: {
        key: string;
        searchParams: URLSearchParams;
    }) => TValue;
    serialize?: (value: TValue, context: {
        key: string;
    }) => string | string[] | null | undefined;
};
type ProtectedParams<TParams extends Record<string, unknown>> = Partial<{
    [K in keyof TParams]: ProtectedParamCodec<TParams[K]>;
}>;
type CoerceParamType = 'string' | 'number' | 'boolean' | 'array';
type CoerceParams<TParams extends Record<string, unknown>> = Partial<Record<ParamKey<TParams>, CoerceParamType>>;
type PaginationStrategy<TParams extends Record<string, unknown>> = {
    mode: 'page';
    pageKey?: ParamKey<TParams>;
    pageSizeKey?: ParamKey<TParams>;
} | {
    mode: 'offset';
    offsetKey?: ParamKey<TParams>;
    limitKey?: ParamKey<TParams>;
} | {
    mode: 'cursor';
    cursorKey?: ParamKey<TParams>;
};
type ResetOnChangeRules<TParams extends Record<string, unknown>> = Partial<Record<ParamKey<TParams>, Array<ParamKey<TParams>>>>;
type UnknownParamsPolicy = 'drop' | 'preserve';
type HistoryMode = 'push' | 'replace';
type BuiltInOmitParamValue = 'all' | 'default' | 'unknown' | 'none' | 'void';
type OmitParamValue = BuiltInOmitParamValue | (string & {});
type OnChangeEvent<TParams extends Record<string, unknown>> = {
    key: keyof TParams;
    previousValue: unknown;
    currentValue: unknown;
};
type OnChangeCallback<TParams extends Record<string, unknown>> = ((event: OnChangeEvent<TParams>) => void) | (() => void);
/**
 * Interface for the configuration object that the hook receives
 */
interface UseMagicSearchParamsOptions<M extends Record<string, unknown>, O extends Record<string, unknown>> {
    mandatory: M;
    optional?: O;
    defaultParams?: Partial<MergeParams<M, O>>;
    forceParams?: Partial<MergeParams<M, O>>;
    arraySerialization?: 'csv' | 'repeat' | 'brackets';
    omitParamsByValues?: Array<OmitParamValue>;
    coerceParams?: CoerceParams<MergeParams<M, O>>;
    codecs?: ParamCodecs<MergeParams<M, O>>;
    protectedParams?: ProtectedParams<MergeParams<M, O>>;
    historyMode?: HistoryMode;
    resetOnChange?: ResetOnChangeRules<MergeParams<M, O>>;
    paginationStrategy?: PaginationStrategy<MergeParams<M, O>>;
    unknownParamsPolicy?: UnknownParamsPolicy;
}
/**
Generic hook to handle search parameters in the URL
@param mandatory - Mandatory parameters (e.g., page=1, page_size=10, etc.)
@param optional - Optional parameters (e.g., order, search, etc.)
@param defaultParams - Default parameters sent in the URL on initialization
@param forceParams - Parameters forced into the URL regardless of user input
@param omitParamsByValues - Parameters omitted if they have specific values
*/
declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, coerceParams, codecs, protectedParams, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
    searchParams: URLSearchParams;
    updateParams: (input?: {
        newParams?: Partial<{ [K in keyof MergeParams<M, O>]: "" | MergeParams<M, O>[K] | (MergeParams<M, O>[K] extends infer T ? T extends MergeParams<M, O>[K] ? T extends (infer TItem)[] ? TItem : never : never : never); }> | ((current: MergeParams<M, O>) => Partial<{ [K in keyof MergeParams<M, O>]: "" | MergeParams<M, O>[K] | (MergeParams<M, O>[K] extends infer T ? T extends MergeParams<M, O>[K] ? T extends (infer TItem)[] ? TItem : never : never : never); }>);
        keepParams?: Partial<Record<Extract<keyof M, string> | Extract<keyof O, string>, boolean>>;
        historyMode?: HistoryMode;
    } | ((current: MergeParams<M, O>) => {
        newParams?: Partial<{ [K in keyof MergeParams<M, O>]: "" | MergeParams<M, O>[K] | (MergeParams<M, O>[K] extends infer T ? T extends MergeParams<M, O>[K] ? T extends (infer TItem)[] ? TItem : never : never : never); }> | ((current: MergeParams<M, O>) => Partial<{ [K in keyof MergeParams<M, O>]: "" | MergeParams<M, O>[K] | (MergeParams<M, O>[K] extends infer T ? T extends MergeParams<M, O>[K] ? T extends (infer TItem)[] ? TItem : never : never : never); }>);
        keepParams?: Partial<Record<Extract<keyof M, string> | Extract<keyof O, string>, boolean>>;
        historyMode?: HistoryMode;
    } | Partial<{ [K in keyof MergeParams<M, O>]: "" | MergeParams<M, O>[K] | (MergeParams<M, O>[K] extends infer T ? T extends MergeParams<M, O>[K] ? T extends (infer TItem)[] ? TItem : never : never : never); }>)) => void;
    clearParams: ({ keepMandatoryParams, historyMode: historyModeOverride }?: {
        keepMandatoryParams?: boolean;
        historyMode?: HistoryMode;
    }) => void;
    getParams: {
        (options: {
            convert: false;
            forRequest?: boolean;
        }): MergeParams<M, O>;
        (options: {
            convert?: true;
            forRequest: true;
        }): RequestSafeParams<M, O>;
        (options?: {
            convert?: true;
            forRequest?: false;
        }): MergeParams<M, O>;
        (options: {
            convert: boolean;
            forRequest?: boolean;
        }): MergeParams<M, O> | RequestSafeParams<M, O>;
    };
    getParam: <K extends Extract<keyof M, string> | Extract<keyof O, string>, T extends boolean = true>(key: K, options?: {
        convert: T;
    }) => T extends true ? MergeParams<M, O>[K] : string;
    onChange: (paramName: Extract<keyof M, string> | Extract<keyof O, string>, callbacks: Array<OnChangeCallback<MergeParams<M, O>>>) => () => void;
    pagination: {
        mode: "page" | "offset" | "cursor";
        next: (cursor?: string) => void;
        prev: () => void;
        reset: () => void;
        setCursor: (cursor: string | null | undefined) => void;
    };
};

export { type BuiltInOmitParamValue, type CoerceParamType, type CoerceParams, type HistoryMode, type OmitParamValue, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ProtectedParamCodec, type ProtectedParams, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
