import { ComponentType } from "react";
import { IOConnectModals } from "@interopio/modals-api";
import { IODialogTemplates } from "@interopio/components-react";

export type IOBrowserModalsUIFactoryFunction = (io: any, config: IOBrowserModalsUI.Config) => Promise<IOBrowserModalsUI.API>;

declare const IOBrowserModalsUIFactory: IOBrowserModalsUIFactoryFunction;

export default IOBrowserModalsUIFactory;

export namespace IOBrowserModalsUI {
    export interface Config {
        rootElement: HTMLDivElement;
        alerts?: {
            enabled: boolean;
            components?: Alerts.Components;
        };
        dialogs?: {
            enabled: boolean;
            templates?: Dialogs.TemplateConfig[];
        };
    }

    export interface API {
        alerts: Alerts.API;
        dialogs: Dialogs.API;
    }

    export interface OpenAlertMessage {
        id: string;
        config: Omit<IOBrowserModalsUI.Alerts.OpenConfig, "onClick" | "onClose">;
    }

    export interface AlertProps {
        data: OpenAlertMessage;
        onClick: (data: {
            interopAction?: IOBrowserModalsUI.Alerts.InteropAction;
            shouldCloseAlert?: boolean;
        }) => void;
    }

    export namespace Alerts {
        export interface API {
            open: (config: OpenConfig) => OpenResult;
            close: (config: CloseConfig) => void;
        }

        export interface InteropAction {
            name: string;
            settings: IOConnectModals.InteropSettings;
        }

        export type OpenConfig = Omit<IOConnectModals.AlertRequestConfig, "target" | "ttl"> & {
            onClose: () => void;
            onClick: (config: OnClickConfig) => void;
        }

        export interface OpenResult {
            id: string;
        }

        export interface CloseConfig {
            id: string;
        }

        export interface OnClickConfig {
            interopAction: InteropAction;
        }

        export interface Components {
            Alert?: React.ComponentType<AlertProps>;
        }
    }

    export namespace Dialogs {
        export interface API {
            open: (config: OpenConfig) => OpenResult;
            close: (config: CloseConfig) => void;
        }

        export interface OpenConfig<Name extends string = string, Variables = any> {
            templateName: Name;
            onCompletion: (config: OnCompletionConfig) => void;
            size?: IOConnectModals.DialogRequestConfig["size"];
            variables: Variables;
        }

        export interface OpenResult {
            id: string;
        }

        export interface CloseConfig {
            id: string;
        }

        export interface OnCompletionConfig {
            response: IOConnectModals.DialogResponse;
        }

        interface DialogProps {
            onCompletion: (response: IOConnectModals.DialogResponse) => void;
            size?: IOConnectModals.DialogRequestConfig["size"];
            variables: any;
        }

        export interface TemplateConfig {
            name: string;
            Dialog: ComponentType<DialogProps>;
            validate: (config: Dialogs.OpenConfig) => Dialogs.OpenConfig;
        }

        export namespace Templates {
            export namespace NoInputsConfirmationDialog {
                export type Config = OpenConfig<"noInputsConfirmationDialog", Variables>;

                export type Variables = IODialogTemplates.NoInputsConfirmationDialogProps["variables"];
            }

            export namespace SingleCheckboxDialog {
                export type Config = OpenConfig<"singleCheckboxDialog", Variables>;

                export type Variables = IODialogTemplates.SingleCheckboxDialogProps["variables"]
            }

            export namespace SingleTextInputDialog {
                export type Config = OpenConfig<"singleTextInputDialog", Variables>;

                export type Variables = IODialogTemplates.SingleTextInputDialogProps["variables"];
            }
        }
    }
}
