import { default as default_2 } from 'react';
import { Message } from '@yunu-lab/rpc-ts';
import { Rpc } from '@yunu-lab/rpc-ts';
import { RpcRepository } from '@yunu-lab/rpc-ts';
import { StorageType } from '@yunu-lab/rpc-ts';
import { Store } from '@reduxjs/toolkit';
import { UnknownAction } from 'redux';
import { z } from 'zod';

export declare const createRpcHooks: <TTypes extends Record<string, Rpc<any>>, RpcStorageType extends Record<keyof TTypes, StorageType> = Record<keyof TTypes, StorageType>>(typeKeys: Array<keyof TTypes>) => RpcHooks<TTypes, RpcStorageType>;

export declare const extendStore: (options: ExtendStoreOptions) => {
    store: Store<any, UnknownAction, unknown>;
    repository: RpcRepository<any, {}>;
    unsubscribe: string;
};

export declare interface ExtendStoreOptions {
    repository: RpcRepository<any>;
    store: Store;
    slices?: Record<string, any>;
}

declare type InferRpcType<T> = T extends Rpc<infer S> ? z.infer<S> : never;

declare type InferRpcType_2<T> = T extends Rpc<infer S> ? z.infer<S> : never;

declare type InlineRpcHooks<TTypes extends Record<string, Rpc<any>>, RpcStorageType extends Record<keyof TTypes, StorageType>> = {
    [K in keyof TTypes as `use${ToPascalCase_2<string & K>}`]: {
        (): {
            [P in K as `${P & string}s`]: RpcStorageType[P] extends "collection" ? InferRpcType_2<TTypes[P]>[] : RpcStorageType[P] extends "singleton" ? InferRpcType_2<TTypes[P]> | null : InferRpcType_2<TTypes[P]>[];
        } & {
            [P in K as `${P & string}Map`]: RpcStorageType[P] extends "collection" ? Record<string, InferRpcType_2<TTypes[P]>> : RpcStorageType[P] extends "singleton" ? InferRpcType_2<TTypes[P]> | null : Record<string, InferRpcType_2<TTypes[P]>>;
        } & {
            findById: (id: string | number) => InferRpcType_2<TTypes[K]> | null;
            findAll: () => InferRpcType_2<TTypes[K]>[];
            mergeRpc: {
                (data: Record<string, Partial<InferRpcType_2<TTypes[K]>> | null> | InferRpcType_2<TTypes[K]>[] | Partial<InferRpcType_2<TTypes[K]>>): InferRpcType_2<TTypes[K]>[];
                <Rst extends Record<keyof TTypes, StorageType>>(data: Rst[K] extends "collection" ? Record<string, Partial<InferRpcType_2<TTypes[K]>> | null> | InferRpcType_2<TTypes[K]>[] : Rst[K] extends "singleton" ? Partial<InferRpcType_2<TTypes[K]>> : never): Rst[K] extends "collection" ? InferRpcType_2<TTypes[K]>[] : Rst[K] extends "singleton" ? InferRpcType_2<TTypes[K]> : never;
            };
            clear: () => void;
        };
        (id: string | number): InferRpcType_2<TTypes[K]> | null;
    };
} & {
    [K in keyof TTypes as `use${ToPascalCase_2<string & K>}Listener`]: <RpcStorageTypeMap extends Record<keyof TTypes, StorageType> = RpcStorageType>(callback: (event: {
        type: K;
        payload: RpcStorageTypeMap[K] extends "collection" ? Array<InferRpcType_2<TTypes[K]>> : RpcStorageTypeMap[K] extends "singleton" ? InferRpcType_2<TTypes[K]> : Array<InferRpcType_2<TTypes[K]>>;
    }) => void) => () => void;
} & {
    useDataListener: <RpcStorageTypeMap extends Record<keyof TTypes, StorageType> = RpcStorageType>(callback: (events: Array<{
        type: keyof TTypes;
        payload: RpcStorageTypeMap[keyof TTypes] extends "collection" ? Array<InferRpcType_2<TTypes[keyof TTypes]>> : RpcStorageTypeMap[keyof TTypes] extends "singleton" ? InferRpcType_2<TTypes[keyof TTypes]> : Array<InferRpcType_2<TTypes[keyof TTypes]>>;
    }>) => void, options?: {
        types?: (keyof TTypes)[];
    }) => () => void;
} & {
    useHandleMessages: () => {
        handleMessages<RpcStorageType extends Record<keyof TTypes, StorageType>>(messages: Array<Message<TTypes>>, callbacks?: {
            [K in keyof TTypes]?: (data: RpcStorageType[K] extends "collection" ? Record<string, Partial<InferRpcType_2<TTypes[K]>> | null> | Array<InferRpcType_2<TTypes[K]>> : RpcStorageType[K] extends "singleton" ? Partial<InferRpcType_2<TTypes[K]>> : never) => void;
        }): void;
    };
};

export declare type InlineRpcsConfig<TTypes extends Record<string, Rpc<any>>, RpcStorageType extends Record<keyof TTypes, StorageType>> = {
    [K in keyof TTypes]: {
        rpc: TTypes[K];
        storageType: RpcStorageType[K];
        idField?: string;
    };
};

export { Rpc }

export declare interface RpcContextType<TTypes extends Record<string, Rpc<any>>> {
    repository: RpcRepository<TTypes>;
}

declare type RpcHooks<TTypes extends Record<string, Rpc<any>>, RpcStorageType extends Record<keyof TTypes, StorageType> = Record<keyof TTypes, StorageType>> = {
    [K in keyof TTypes as `use${ToPascalCase<string & K>}`]: {
        (): {
            [P in K as `${P & string}s`]: RpcStorageType[P] extends "collection" ? InferRpcType<TTypes[P]>[] : RpcStorageType[P] extends "singleton" ? InferRpcType<TTypes[P]> | null : InferRpcType<TTypes[P]>[];
        } & {
            [P in K as `${P & string}Map`]: RpcStorageType[P] extends "collection" ? Record<string, InferRpcType<TTypes[P]>> : RpcStorageType[P] extends "singleton" ? InferRpcType<TTypes[P]> | null : Record<string, InferRpcType<TTypes[P]>>;
        } & {
            findById: (id: string | number) => InferRpcType<TTypes[K]> | null;
            findAll: () => InferRpcType<TTypes[K]>[];
            mergeRpc: {
                (data: Record<string, Partial<InferRpcType<TTypes[K]>> | null> | InferRpcType<TTypes[K]>[] | Partial<InferRpcType<TTypes[K]>>): InferRpcType<TTypes[K]>[];
                <RpcStorageType extends Record<keyof TTypes, StorageType>>(data: RpcStorageType[K] extends "collection" ? Record<string, Partial<InferRpcType<TTypes[K]>> | null> | InferRpcType<TTypes[K]>[] : RpcStorageType[K] extends "singleton" ? Partial<InferRpcType<TTypes[K]>> : never): InferRpcType<TTypes[K]>[];
            };
            clear: () => void;
        };
        (id: string | number): InferRpcType<TTypes[K]> | null;
    };
} & {
    [K in keyof TTypes as `use${ToPascalCase<string & K>}FullRelatedData`]: <TResult = InferRpcType<TTypes[K]>>(id?: string | number) => TResult | TResult[] | null;
} & {
    [K in keyof TTypes as `use${ToPascalCase<string & K>}Listener`]: <RpcStorageType extends Record<keyof TTypes, StorageType> = Record<keyof TTypes, StorageType>>(callback: (event: {
        type: K;
        payload: RpcStorageType[K] extends "collection" ? Array<InferRpcType<TTypes[K]>> : RpcStorageType[K] extends "singleton" ? InferRpcType<TTypes[K]> : Array<InferRpcType<TTypes[K]>>;
    }) => void) => () => void;
} & {
    useDataListener: <RpcStorageType extends Record<keyof TTypes, StorageType> = Record<keyof TTypes, StorageType>>(callback: (events: Array<{
        type: keyof TTypes;
        payload: RpcStorageType[keyof TTypes] extends "collection" ? Array<InferRpcType<TTypes[keyof TTypes]>> : RpcStorageType[keyof TTypes] extends "singleton" ? InferRpcType<TTypes[keyof TTypes]> : Array<InferRpcType<TTypes[keyof TTypes]>>;
    }>) => void, options?: {
        types?: (keyof TTypes)[];
    }) => () => void;
} & {
    [K in keyof TTypes as `use${ToPascalCase<string & K>}Related`]: <TTarget extends keyof TTypes>(id: string | number, targetType: TTarget) => Array<TTypes[TTarget] extends Rpc<infer S> ? z.infer<S> : never>;
} & {
    useHandleMessages: () => {
        handleMessages<RpcStorageType extends Record<keyof TTypes, StorageType>>(messages: Array<Message<TTypes>>, callbacks?: {
            [K in keyof TTypes]?: (data: RpcStorageType[K] extends "collection" ? Record<string, Partial<InferRpcType<TTypes[K]>> | null> | Array<InferRpcType<TTypes[K]>> : RpcStorageType[K] extends "singleton" ? Partial<InferRpcType<TTypes[K]>> : never) => void;
        }): void;
    };
};

export declare const RpcProvider: default_2.FC<RpcProviderProps>;

export declare interface RpcProviderProps {
    children: default_2.ReactNode;
    repository: RpcRepository;
}

export { RpcRepository }

declare type ToPascalCase<S extends string> = S extends `${infer First}_${infer Rest}` ? `${Capitalize<First>}${ToPascalCase<Rest>}` : Capitalize<S>;

declare type ToPascalCase_2<S extends string> = S extends `${infer First}_${infer Rest}` ? `${Capitalize<First>}${ToPascalCase_2<Rest>}` : Capitalize<S>;

export declare function useInlineRpcStore<TTypes extends Record<string, Rpc<any>>, RpcStorageType extends Record<keyof TTypes, StorageType> = Record<keyof TTypes, StorageType>>(rpcs: InlineRpcsConfig<TTypes, RpcStorageType>): {
    readonly hooks: InlineRpcHooks<TTypes, RpcStorageType>;
    readonly repository: RpcRepository<TTypes, {}>;
};

export declare const useRpc: <TTypes extends Record<string, Rpc<any>>>() => RpcContextType<TTypes>;

export { }
