import { ClassValue } from 'clsx';
import i18n from 'i18next';
import { JSX as JSX_2 } from 'react/jsx-runtime';
import * as React_2 from 'react';
import { default as React_3 } from 'react';
import { ReactNode } from 'react';
import { RESET } from 'jotai/utils';
import { ThrottledFunction } from '@react-hookz/web';
import { useTranslation } from 'react-i18next';

declare type AddBlocks = {
    addCoreBlock: any;
    addPredefinedBlock: any;
};

export declare const AddBlocksPanel: ({ className, showHeading }: {
    showHeading?: boolean;
    className?: string;
}) => JSX_2.Element;

export declare const AISetContext: () => JSX_2.Element;

export declare const AIUserPrompt: ({ blockId }: {
    blockId: string | undefined;
}) => JSX_2.Element;

declare type AskAiResponse = {
    blocks?: Array<{
        _id: string;
    } & Partial<ChaiBlock>>;
    usage?: Record<any, number>;
    error?: any;
};

declare interface Block {
    type: string;
    [key: string]: any;
}

export declare const BlockAttributesEditor: React_2.MemoExoticComponent<() => JSX_2.Element>;

/**
 *
 * @returns Block Setting
 */
export declare function BlockPropsEditor(): JSX_2.Element;

export declare function BlockStyleEditor(): JSX_2.Element;

declare type Breakpoint = {
    title: string;
    content: string;
    breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | string;
    icon: React_3.ReactNode | Element;
    width: number;
};

export declare type ChaiBlock = {
    _id: string;
    _type: string;
    _name?: string;
    _parent?: string | null | undefined;
    _bindings?: Record<string, string>;
} & Record<string, any>;

export declare const ChaiBuilderCanvas: React_3.FC;

/**
 * ChaiBuilder is the main entry point for the Chai Builder Studio.
 * @param props
 * @constructor
 */
export declare const ChaiBuilderEditor: (props: ChaiBuilderEditorProps) => JSX_2.Element;

export declare interface ChaiBuilderEditorProps {
    onLoad?: (editorInstance: ChaiBuilderInstance) => void;
    customRootLayout?: React_3.ComponentType;
    htmlDir?: "ltr" | "rtl";
    hideSaveButton?: boolean;
    filterChaiBlock?: (block: any) => boolean;
    showDebugLogs?: boolean;
    autoSaveSupport?: boolean;
    autoSaveInterval?: TimeInSeconds;
    breakpoints?: Breakpoint[];
    editable?: boolean;
    loading?: boolean;
    locale?: string;
    nonEditableComponent?: ReactComponentType;
    canvas?: React_3.FC<any>;
    canvasTopBarComponents?: {
        right?: ReactComponentType[];
    };
    previewLink?: string;
    dataBindingSupport?: boolean;
    dataProviders?: DataProvider[];
    darkMode?: boolean;
    dndOptions?: any;
    importHTMLSupport?: boolean;
    fetchMediaCallback?: (limit?: number, offset?: number) => Promise<any[]>;
    uploadMediaCallback?: (file: File) => Promise<{
        url: string;
    }>;
    askAiCallBack?: (type: "styles" | "content", prompt: string, blocks: ChaiBlock[]) => Promise<AskAiResponse>;
    saveAiContextCallback?: (content: string) => Promise<true | Error>;
    aiContext?: string;
    getExternalPredefinedBlock?: (block: PredefinedBlock) => Promise<PredefinedBlock & {
        blocks: ChaiBlock[];
        html: string;
    }>;
    uiLibraries?: Omit<UILibrary, "blocks">[];
    getUILibraryBlocks?: (library: UILibrary) => Promise<UiLibraryBlock[]>;
    getUILibraryBlock?: (library: UILibrary, uiLibBlock: UiLibraryBlock) => Promise<ChaiBlock[]>;
    subPages?: Block[];
    subPagesSupport?: boolean;
    blocks?: ChaiBlock[];
    onSaveBlocks?: ({ blocks, providers }: any) => Promise<any>;
    onSavePage?: ({ blocks, providers }: SavePageData) => Promise<boolean | Error>;
    onSave?: ({ blocks, providers }: SavePageData) => Promise<boolean | Error>;
    brandingOptions?: Record<string, string>;
    onSaveBrandingOptions?: (brandingOptions: Record<string, any>) => Promise<boolean | Error>;
    onSaveStateChange?: (syncStatus: "UNSAVED" | "SAVED" | "SAVING") => void;
    previewComponent?: ReactComponentType;
    sideBarComponents?: {
        bottom?: ReactComponentType[];
        top?: {
            icon: ReactComponentType | string;
            name: string;
            panel: ReactComponentType;
        }[];
    };
    topBarComponents?: {
        center?: ReactComponentType[];
        left?: ReactComponentType[];
        right?: ReactComponentType[];
    };
    outlineMenuItems?: OutlineMenuItems;
    getPages?: () => Promise<ChaiPage[]>;
    unsplashAccessKey?: string;
    _flags?: Record<string, boolean>;
}

declare type ChaiBuilderInstance = {
    setBlocks: (blocks: ChaiBlock[]) => void;
};

declare type ChaiPage = {
    uuid?: string;
    page_name?: string;
    blocks: ChaiBlock[];
    custom_code: string;
    seo_data: Record<string, string>;
    slug: string;
    translations: Record<string, Record<string, string>>;
};

declare type ClassDerivedObject = {
    cls: string;
    dark: boolean;
    fullCls: string;
    mod: string;
    mq: string;
    property: string;
};

declare type CodeEditorProps = {
    blockId: string;
    blockProp: string;
    initialCode: string;
    placeholder?: string;
};

declare type CopiedValue = string | null;

declare type CopyFn = (text: string) => Promise<boolean>;

export declare function DarkModeSwitcher(): JSX_2.Element;

declare type DataProvider = {
    providerKey: string;
    args: Record<string, any>;
};

declare type ExcludedBuilderProps = "blocks" | "subPages" | "brandingOptions" | "dataProviders";

/**
 * Get the unique uuid
 */
export declare function generateBlockId(length?: number, chars?: string): string;

/**
 *
 * @param html
 * @returns Blocks JSON
 */
export declare const getBlocksFromHTML: (html: string) => ChaiBlock[];

export { i18n }

export declare const ImportHTML: () => JSX_2.Element;

export declare const mergeClasses: (...inputs: ClassValue[]) => string;

export declare const Outline: () => JSX_2.Element;

declare type OutlineMenuItem = {
    item: React_3.ComponentType<{
        blockId: string;
    }>;
    tooltip: string | ReactNode;
};

declare type OutlineMenuItems = OutlineMenuItem[];

declare type PredefinedBlock = {
    uuid: string;
    name: string;
    preview: string;
    blocks?: ChaiBlock[];
    html?: string;
};

declare type ReactComponentType = React_3.ComponentType<any>;

declare type RichText = string;

declare type SavePageData = {
    blocks: ChaiBlock[];
    providers?: DataProvider[];
    brandingOptions?: Record<string, any>;
    themeConfiguration?: Record<string, any>;
};

export declare const ScreenSizes: () => JSX_2.Element;

export declare const ThemeOptions: ({ showHeading, className, }: {
    className?: string;
    showHeading?: boolean;
}) => React_2.JSX.Element;

declare type TimeInSeconds = number;

declare type TStyleBlock = {
    blockId: string;
    id: string;
    prop: string;
};

export declare const UILibraries: () => JSX_2.Element;

declare interface UILibrary {
    uuid: string;
    name: string;
    url: string;
    blocks?: UiLibraryBlock[];
    link?: string;
    description?: RichText;
}

declare type UiLibraryBlock = {
    uuid: string;
    group: string;
    name?: string;
    path: string;
    preview?: string;
    tags?: string[];
    description?: string;
};

export declare const UndoRedo: () => JSX_2.Element;

export declare const useActiveModal: () => any;

/**
 *
 */
export declare const useActivePanel: () => [string, (args_0: string | ((prev: string) => string)) => void];

export declare const useAddBlock: () => AddBlocks;

/**
 *
 */
export declare const useAddBlockParent: () => [string, never];

export declare const useAddClassesToBlocks: () => Function;

/**
 * useTreeData hook
 */
export declare const useAllBlocks: () => ChaiBlock[];

export declare const useBlocksStore: () => [ChaiBlock[], Function];

/**
 * Wrapper around useAtom
 */
export declare const useBrandingOptions: () => readonly [any, (args_0: any) => void];

export declare const useBuilderProp: <T>(propKey: keyof Omit<ChaiBuilderEditorProps, ExcludedBuilderProps> | "sideBarComponents.top" | "sideBarComponents.bottom" | "topBarComponents.left" | "topBarComponents.right" | "topBarComponents.center" | "languages", defaultValue?: T) => T;

export declare const useBuilderReset: () => () => void;

/**
 *
 */
export declare const useCanvasWidth: () => [number, string, Function];

/**
 * Wrapper hook around useAtom
 */
export declare const useCanvasZoom: () => [number, (args_0: number | typeof RESET | ((prev: number) => number | typeof RESET)) => void];

export declare const useCodeEditor: () => [CodeEditorProps, never];

export declare const useCopyBlockIds: () => [Array<string>, Function];

export declare const useCopyToClipboard: () => [CopiedValue, CopyFn];

export declare const useCurrentPage: () => {
    currentPage: unknown;
};

export declare const useCutBlockIds: () => [Array<string>, Function];

/**
 * Wrapper hook around useAtom
 */
export declare const useDarkMode: () => [boolean, Function];

/**
 * useDuplicateBlock
 */
export declare const useDuplicateBlocks: () => Function;

export declare const useGetPageData: () => () => {
    currentPage: unknown;
    blocks: any;
};

export declare const useHiddenBlockIds: () => (string[] | ((args_0: string[] | ((prev: string[]) => string[])) => void) | ((blockId: string) => void))[];

/**
 *
 */
export declare const useHighlightBlockId: () => [string, Function];

export declare const usePasteBlocks: () => {
    canPaste: (newParentId: string) => boolean;
    pasteBlocks: Function;
};

/**
 *
 */
export declare const usePreviewMode: () => [boolean, Function];

export declare const useReadOnlyMode: () => unknown;

export declare const useRemoveBlocks: () => (blockIds: Array<string>) => void;

export declare const useRemoveClassesFromBlocks: () => Function;

export declare const useSavePage: () => {
    savePage: ThrottledFunction<() => Promise<boolean>>;
    saveState: "UNSAVED" | "SAVED" | "SAVING";
    setSaveState: (args_0: "UNSAVED" | "SAVED" | "SAVING" | ((prev: "UNSAVED" | "SAVED" | "SAVING") => "UNSAVED" | "SAVED" | "SAVING")) => void;
};

/**
 * useSelectedBlock hook
 */
export declare const useSelectedBlock: () => ChaiBlock;

export declare const useSelectedBlockAllClasses: () => Array<ClassDerivedObject>;

export declare const useSelectedBlockCurrentClasses: () => Array<ClassDerivedObject>;

/**
 *
 */
export declare const useSelectedBlockIds: () => [Array<string>, Function, Function];

/**
 * Hook to get selected block ids
 */
export declare const useSelectedBlocksDisplayChild: () => {
    flexChild: boolean;
    gridChild: boolean;
};

export declare const useSelectedBreakpoints: () => [string[], Function];

/**
 *
 */
export declare const useSelectedStylingBlocks: () => [TStyleBlock[], (args_0: TStyleBlock[] | ((prev: TStyleBlock[]) => TStyleBlock[])) => void];

export declare const useStylingBreakpoint: () => [string, (args_0: string | typeof RESET | ((prev: string) => string | typeof RESET)) => void];

export declare const useStylingState: () => [unknown, (...args: unknown[]) => unknown];

export { useTranslation }

export declare const useUILibraryBlocks: () => {
    data: any[];
    isLoading: boolean;
};

export declare const useUndoManager: () => {
    add: any;
    undo: any;
    redo: any;
    hasRedo: any;
    hasUndo: any;
    clear: any;
};

/**
 *
 */
export declare const useUpdateBlocksProps: () => (blockIds: Array<string>, props: Record<string, any>, prevPropsState?: Record<string, any>) => void;

export declare const useUpdateBlocksPropsRealtime: () => (blockIds: Array<string>, props: Record<string, any>) => void;

export { }
