import { ClassValue } from 'clsx';
import { Emitter } from 'react-event-hook';
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 AddBlocksDialog: () => JSX_2.Element;

export declare const AddBlocksPanel: ({ className, showHeading, parentId, }: {
    parentId?: string;
    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;
};

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 const CHAI_BUILDER_EVENTS: {
    OPEN_ADD_BLOCK: string;
    CLOSE_ADD_BLOCK: string;
    SHOW_BLOCK_SETTINGS: string;
};

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.
 */
export declare const ChaiBuilderEditor: React_3.FC<ChaiBuilderEditorProps>;

export declare interface ChaiBuilderEditorProps {
    /**
     * onError callback function
     * @param error
     */
    onError?: (error: Error) => void;
    /**
     * Translations object
     */
    translations?: Record<string, Record<string, any>>;
    /**
     * onLoad callback function
     * @param editorInstance
     */
    onLoad?: (editorInstance: ChaiBuilderInstance) => void;
    /**
     * Custom layout component
     */
    layout?: React_3.ComponentType;
    /**
     * Layout variant. Not supported with custom layout
     */
    layoutVariant?: LayoutVariant;
    /**
     * HTML direction.
     */
    htmlDir?: "ltr" | "rtl";
    /**
     * Filter function for blocks to be shown in the builder
     */
    filterChaiBlock?: (block: any) => boolean;
    /**
     * Show debug logs
     */
    showDebugLogs?: boolean;
    /**
     * Auto save support
     */
    autoSaveSupport?: boolean;
    /**
     * Auto save interval in seconds
     */
    autoSaveInterval?: TimeInSeconds;
    /**
     * Breakpoints
     */
    breakpoints?: Breakpoint[];
    /**
     * Editable
     */
    editable?: boolean;
    /**
     * Loading state
     */
    loading?: boolean;
    /**
     * Locale
     */
    locale?: string;
    nonEditableComponent?: ReactComponentType;
    /**
     * Canvas component. Not supported with custom layout
     */
    canvasTopBarComponents?: {
        right?: ReactComponentType[];
    };
    previewLink?: string;
    dataBindingSupport?: boolean;
    dataProviders?: DataProvider[];
    darkMode?: boolean;
    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;
    uiLibraries?: Omit<UILibrary, "blocks">[];
    getUILibraryBlocks?: (library: UILibrary) => Promise<UiLibraryBlock[]>;
    getUILibraryBlock?: (library: UILibrary, uiLibBlock: UiLibraryBlock) => Promise<ChaiBlock[]>;
    blocks?: ChaiBlock[];
    onSave?: ({ blocks, providers }: SavePageData) => Promise<boolean | Error>;
    brandingOptions?: Record<string, string>;
    /**
     * Theme configuration
     */
    themeConfiguration?: Record<string, string>;
    /**
     * onSaveStateChange callback function
     * @param syncStatus
     */
    onSaveStateChange?: (syncStatus: "UNSAVED" | "SAVED" | "SAVING") => void;
    /**
     * Preview component
     */
    previewComponent?: ReactComponentType;
    /**
     * Sidebar components. Not supported with custom layout
     */
    sideBarComponents?: {
        bottom?: ReactComponentType[];
        top?: {
            icon: ReactNode;
            label: string;
            component: ReactComponentType;
        }[];
    };
    /**
     * Topbar components. Not supported with custom layout
     */
    topBarComponents?: {
        center?: ReactComponentType[];
        left?: ReactComponentType[];
        right?: ReactComponentType[];
    };
    /**
     * Outline menu items
     */
    outlineMenuItems?: OutlineMenuItems;
    /**
     * getPages callback function
     */
    getPages?: () => Promise<ChaiPage[]>;
    /**
     * Unsplash access key
     */
    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>;
};

export declare const DefaultChaiBlocks: ({ parentId, gridCols }: {
    parentId?: string;
    gridCols?: string;
}) => JSX_2.Element;

export declare const emitChaiBuilderMsg: Emitter<{
    name: string;
    data?: 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[];

/**
 * Get the value and unit for a tw class
 * @param className
 */
export declare const getClassValueAndUnit: (className: string) => {
    unit: string;
    value: string;
};

export { i18n }

export declare const ImportHTML: ({ parentId }: {
    parentId?: string;
}) => JSX_2.Element;

declare type LayoutVariant = "SINGLE_SIDE_PANEL" | "DUAL_SIDE_PANEL" | "DUAL_SIDE_PANEL_ADVANCED";

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 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: ({ parentId }: {
    parentId?: string;
}) => 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 useAddBlock: () => AddBlocks;

export declare const useAddClassesToBlocks: () => Function;

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

export declare const useBlocksStoreUndoableActions: () => {
    moveBlocks: (blockIds: string[], parent: string | undefined, position: number) => void;
    addBlocks: (newBlocks: ChaiBlock[], parent?: string, position?: number) => void;
    removeBlocks: (blocks: ChaiBlock[]) => void;
    updateBlocks: (blockIds: string[], props: Partial<ChaiBlock>, oldPropsState?: Partial<ChaiBlock>) => void;
    updateBlocksRuntime: (blockIds: string[], props: Record<string, any>) => void;
    setNewBlocks: (newBlocks: ChaiBlock[]) => void;
    updateMultipleBlocksProps: (blocks: Array<{
        _id: string;
    } & Partial<ChaiBlock>>) => void;
};

/**
 * 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 useChaiBuilderMsgListener: (handler: (payload: {
    name: string;
    data?: any;
}) => void) => void;

/**
 * Custom hook to access the current state of the code editor.
 * @category Hooks
 * @returns The current state of the code editor from the `codeEditorAtom`.
 */
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 useHiddenBlockIds: () => readonly [string[], (args_0: string[] | ((prev: string[]) => string[])) => void, (blockId: string) => void];

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

export declare const useLayoutVariant: () => readonly [LayoutVariant, (args_0: LayoutVariant | typeof RESET | ((prev: LayoutVariant) => LayoutVariant | typeof RESET)) => void];

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

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

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];

/**
 * @group Hooks
 * @returns {TStyleBlock[]} selected styling blocks
 */
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 { }
