import { ReactElement, ReactNode, FunctionComponent, Dispatch, SetStateAction } from 'react';
import { TObject, Static } from '@sinclair/typebox';
import { CreateTRPCProxyClient } from '@trpc/client';
import { CreateTRPCReact } from '@trpc/react-query';
import { AnyRouter } from '@trpc/server';

type ObjPathProxy<TRoot, T> = {
    [P in keyof T]: ObjPathProxy<TRoot, T[P]>;
};
type Variable = {
    id: string;
    label: string;
    type: "string";
    isBrokenRef?: true;
};
type GetVariablesFn = (ctx: {
    variables: readonly Variable[];
}) => readonly Variable[] | boolean | null;
type CommonInputProps<PropType extends any> = {
    bind: ObjPathProxy<any, PropType>;
    onChange?: (newValue: PropType) => void;
    label?: string;
    description?: string;
    placeholder?: string;
    variables?: GetVariablesFn | boolean | null;
};

type RichTextInputProps = CommonInputProps<string | undefined> & {
    isRequired?: boolean;
    isDisabled?: boolean;
    hideToolbar?: boolean;
};

type MultiSelectOption = {
    id: string;
    name: string;
};
type MultiSelectInputProps = CommonInputProps<string[] | string | undefined> & {
    fetchOptions: () => Promise<MultiSelectOption[]> | MultiSelectOption[];
    dependencies?: any[];
    isRequired?: boolean;
};

type KeyValuesProps = {
    bind: ObjPathProxy<any, any> | undefined;
};

type FindByProps = CommonInputProps<string | undefined> & {
    filterInput: ReactElement;
    filterValueInput: ReactElement;
    selectInput: ReactElement;
    resource: string;
};

type File = {
    path: string;
    name: string;
    id: string;
    isFolder: boolean;
};
type FileBrowserInputProps = CommonInputProps<string | undefined> & {
    selectionMode: "file" | "folder";
    dependencies?: any[];
    isDisabled?: boolean;
    isRequired?: boolean;
    fetchOptions: (folderPath: string) => Promise<File[]>;
};

type DropdownInputOption = {
    id: string;
    name: string;
};
type DropdownInputProps = CommonInputProps<string | undefined> & {
    allowOnlyVariables?: boolean;
    dependencies?: any[];
    isClearable?: boolean;
    isRequired?: boolean;
    isDisabled?: boolean;
    defaultsToFirstOption?: boolean;
    fetchOptions: () => Promise<readonly DropdownInputOption[]> | readonly DropdownInputOption[];
};

type BooleanInputProps = CommonInputProps<boolean | undefined> & {
    isDisabled?: boolean;
    isRequired?: boolean;
};

type ActionCardProps = {
    children: ReactNode;
    title?: string;
    description?: string;
    collapsable?: true | {
        collapsedOnLoad: boolean;
    };
    isLoading?: boolean;
    required?: boolean;
};

declare const ActionCard: FunctionComponent<ActionCardProps>;
declare const BooleanInput: FunctionComponent<BooleanInputProps>;
declare const DropdownInput: FunctionComponent<DropdownInputProps>;
declare const FileBrowserInput: FunctionComponent<FileBrowserInputProps>;
declare const FindBy: FunctionComponent<FindByProps>;
declare const KeyValues: FunctionComponent<KeyValuesProps>;
declare const MultiSelectInput: FunctionComponent<MultiSelectInputProps>;
declare const RichTextInput: FunctionComponent<RichTextInputProps>;
declare const Spinner: FunctionComponent<{}>;
declare const useApiBaseUrl: () => {
    apiBaseUrl: string;
};
declare const useConsumerToken: () => {
    getToken: () => Promise<string>;
    getFreshToken: () => Promise<string>;
};
declare const useCredentialKey: () => {
    credentialKey: string;
};
type DeepPartial<T> = T extends object ? {
    [P in keyof T]?: DeepPartial<T[P]>;
} : T;
interface UIComponentProps<Params extends TObject, TRouter extends AnyRouter | never = never> {
    /**
     * Proxy object used to bind `inputParams` properties to inputs.
     * Can't be used to access the actual data!
     * The following example binds value of `RichTextInput` to the `inputParams.name` param.
     * @example
     * <RichTextInput bind={b.name} />
     */
    b: ObjPathProxy<Static<Params>, Static<Params>>;
    /**
     * Currently selected Credential key.
     */
    credentialKey: string;
    /**
     * Object holding currently set values for `inputParams`,
     * corresponding to the `inputParamsSchema`.
     */
    inputParams: DeepPartial<Static<Params>>;
    /**
     * Sets values of `inputParams`. Accepts either object representing the new values,
     * or a callback which receives current values and returns new ones.
     */
    setInputParams: Dispatch<SetStateAction<DeepPartial<Static<Params>>>>;
    /**
     * @internal
     * @deprecated
     */
    appAPI: CreateTRPCReact<TRouter, any, any> & CreateTRPCProxyClient<TRouter>;
    /**
     * Array of currently available Variables from Trigger Payload Schema.
     */
    variables: readonly Variable[];
}
/**
 * Used to define UI component for Action or Trigger.
 * @example
 * ```tsx
 * import { defineUIComponent, RichTextEditor } from "@rollout/framework/ui";
 * import { inputParamsSchema } from "./input";

 * export const UI = defineUIComponent<typeof inputParamsSchema>((props) => {
 *   return (
 *     <>
 *       <RichTextEditor bind={b.name} />
 *     </>
 *   );
 * });
 * ```
 */
declare function defineUIComponent<Params extends TObject, TRouter extends AnyRouter | never = never>(component: FunctionComponent<UIComponentProps<Params, TRouter>>): FunctionComponent<UIComponentProps<Params, TRouter>>;

export { ActionCard, BooleanInput, DropdownInput, FileBrowserInput, FindBy, KeyValues, MultiSelectInput, RichTextInput, Spinner, UIComponentProps, defineUIComponent, useApiBaseUrl, useConsumerToken, useCredentialKey };
