import { Assistant, BaseAssistant, ClaudeAsst, GeminiAsst, OpenAILegacyAsst } from "@elimeleth/vct-assistants";
import { Workflow } from "./core";
import { ProviderClass } from "./io/providerClass";
import { Database } from "./io/database/database";
import { ExecutionError, Logging } from "./io/database/entities/others";
import FollowUp from "./core/followup";
export type PrinterFunction = (message: string | string[], title: string, cName?: 'bgMagenta' | 'bgRed' | 'bgCyan') => void;
export interface Nodes {
    name?: string;
    id: number | string;
    delay?: number;
    wait?: number;
    capture?: boolean;
    wait_for_input?: boolean;
    wait_input_id?: string | number;
    fallback?: (msg: string) => Promise<{
        message?: string;
        passed: boolean;
        next_node?: GotoRotue;
    }>;
    follow_up?: FollowUp;
    isChild: boolean;
    next_node?: GotoRotue;
    conditional?: (ctx: Context) => Promise<boolean>;
}
export interface CrontabSchedule {
    minute: string;
    hour: string;
    dayOfMonth: string;
    month: string;
    dayOfWeek: string;
}
export type FollowUpArgs = {
    to_forward_worflow: {
        workflow_name: string;
        action_id: string | number;
    };
    inactive_at: {
        time: number;
        type: "minutes" | "hours" | "days";
    };
    remove_on?: "target_move_on" | "trigger_message";
    trigger_message: string;
};
export type ReturnTypeFromKey<T, K extends keyof T> = T[K];
export interface FollowUpRecord {
    id: number;
    name: string;
    phone: string;
    current_workflow_name: string;
    current_action_id: string | number;
    workflow_name: string;
    action_id: string | number;
    condition: "equals_to" | "contains";
    remove_on: ReturnTypeFromKey<FollowUpArgs, "remove_on">;
    trigger_message: string;
    inactive_at: Date;
}
export interface Attrb {
    name: string;
    phone: string;
    current_workflow_name: string;
    current_action_id: string | number;
    database: Database;
}
export interface CustomerWorkflowHistory {
    message_id: string;
    phone: string;
    name: string;
    current_workflow_name: string;
    current_action_id: string | number;
    last_date_activity: string;
    last_message: string;
    last_message_bot?: string;
    reason_inactivity?: string | null;
    action_type?: "send" | "goto" | "input" | "end" | "wait" | "follow_up" | "fallback" | "desicion" | "capture";
    action_description?: string | null;
    target_node?: string | null;
    delay?: number | null;
    wait?: number | null;
    capture?: boolean;
    wait_for_input?: boolean;
    follow_up_time?: string | null;
    is_decision?: boolean;
    is_fallback?: boolean;
    is_capture?: boolean;
    is_final?: boolean;
    is_pending?: boolean;
}
export type EdgeRouter = (ctx: Context) => Promise<Workflow<string> | null>;
export type InferWorkflowNames<T extends Workflow<string>[]> = T[number]["metadata"]["name"];
export type GlobalRouterArgs<TProvider extends Partial<ProviderClass>> = {
    database?: Database;
    restorePreviousCheckpoint?: boolean;
    pauseFn?: {
        pause: (ctx: Context) => Promise<boolean>;
        is_pause: (ctx: Context) => Promise<boolean>;
    };
    circuitBreaker?: (ctx: Context) => Promise<boolean>;
    llm?: Llm;
    transform_message?: (message: string) => string;
    follow_up_crontab?: CrontabSchedule | undefined;
    downloadConf?: {
        auto: boolean;
        directory: string;
    };
    on_error?: (error: ExecutionError) => Promise<void>;
    openai_assistant?: {
        apiKey?: string;
        functions?: Function[];
    } | boolean | Assistant;
    assistant?: {
        type?: "openai_legacy" | "gemini" | "claude";
        apiKey?: string;
        functions?: Function[];
        tools?: any[];
    };
    provider: TProvider;
    force_trigger_flow?: boolean;
    cancelEventFromMe?: boolean;
    experimental_tracing_messages?: {
        crontab_schema?: string;
        cb: (messages: Array<Logging>) => Promise<void>;
    };
    force_redirect_flow?: {
        key: WorkflowKey;
        to_workflow: Workflow<any, any> | string;
    }[] | undefined;
};
export type Extensions<TProvider extends Partial<ProviderClass>> = {
    http: <T>(options: HttpRequestOptions<T>) => Promise<T>;
    provider: TProvider;
    assistant: Assistant | BaseAssistant | ClaudeAsst | GeminiAsst | OpenAILegacyAsst;
    database: Database;
    checkpointer: ICheckpointer;
};
export interface InternalMethods<TProvider extends Partial<ProviderClass>> {
    send: (message: DynamicSendMessage, options?: DynamicOptionsSendMessage) => Promise<any>;
    end: (args?: {
        is_pending: boolean;
    }) => Promise<void>;
    goto: (targetNodeId: GotoRotue) => Promise<void>;
    state: StateManager;
    extensions: Extensions<TProvider>;
}
export type GotoRotue = number | string | Workflow<string> | {
    parentNode: Workflow<string> | "this";
    node_id: number | string | "last";
};
export interface CallbackMapping {
    [nodeId: number]: (params: any) => Promise<any>;
}
export interface Provider {
    on(event: 'fromMe' | 'message', callback: (ctx: any) => void): void;
    sendMessage(message: string, options: any, type: 'plain' | 'image' | 'voice' | 'auto'): void;
}
export declare abstract class ICheckpointer {
    abstract isCompleted(ctx: Context): Boolean;
    abstract deleteCheckpoint(thread_id: string): Promise<void>;
    abstract getCheckpointStatusPending(): GlobalCheckpoint[];
    abstract loadAllCheckpointsOnInit(): Promise<void>;
    abstract getCheckpointStatus(thread_id: string): string | null;
    abstract saveCheckpoint(args: GlobalCheckpoint): Promise<void>;
    abstract loadCheckpointFromFile(filePath: string): any;
    abstract updateCheckpointStatus(args: GlobalCheckpoint): Promise<any>;
    abstract updateCheckpointStatus(args: Partial<GlobalCheckpoint>, force?: boolean): Promise<any>;
    abstract getActualThreadID(thread_id: string): GlobalCheckpoint;
}
export type Llm = {
    apiKey?: string;
    model?: string;
    provider: "google-genai" | 'groq' | 'openai';
    multimodal?: {
        capture_intentions?: boolean;
    } | boolean;
};
export interface GlobalCheckpoint {
    trigger_key: WorkflowKey;
    workflow_name: string;
    thread_id: string;
    message_id: string;
    node_id: number | string;
    timestamp?: Date | string | number;
    state: any;
    status?: StatusChck;
    ctx: Context;
}
export type MethodsOROptions<TProvider extends Partial<ProviderClass>> = ((ctx: Context, methods: InternalMethods<TProvider>) => Promise<void>) | Omit<Partial<Nodes>, "isChild">;
export type CallbackMethods<TProvider extends Partial<ProviderClass>> = ((ctx: Context, methods: InternalMethods<TProvider>) => Promise<void>);
export type MessageContentType = 'audio' | 'video' | 'document' | 'image' | 'text' | "url";
export type Metadata<TName extends string> = {
    name?: TName;
    intentions?: {
        intention: string;
        description: string;
    }[];
    id?: string | number;
    [key: string]: any;
};
type ConditionsRaise = "when_not_command_found" | (() => boolean);
export type OptionsWorkFlow<TName extends string> = {
    delay?: number;
    metadata?: Metadata<TName>;
    conditions_raise?: {
        condition?: ConditionsRaise;
    };
    [key: string]: any;
};
export type DynamicSendMessage = string | string[] | DynamicOptionsSendMessage[] | Array<string | DynamicOptionsSendMessage>;
export type DynamicOptionsSendMessage = {
    body: string | string[];
    save_metadata?: {
        usage?: {
            total_tokens: number;
            cost: number;
            model: string;
        };
        intentions?: string;
        services?: string;
        [key: string]: any;
    };
    reaction?: {
        message_id: string;
        emoji: string;
    };
    reply?: any;
    media?: string;
    buttons?: {
        body: string;
    }[];
};
export type HttpCallback = (error: Error | null, data?: any) => Promise<void>;
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
export interface HttpRequestOptions<T> {
    urlString: string;
    method: HttpMethod;
    headers?: Record<string, string>;
    body?: T;
}
export type Context = {
    file_dir_path?: string;
    http_request: {
        data: any;
        error: Error | null;
    };
    created_at?: Date;
    variables?: Record<string, any>;
    file: any;
    type?: "text" | "image" | "audio" | string;
    connection: any;
    breakpoint?: boolean;
    from: string;
    message_id: string;
    phone?: string;
    thread_id?: string;
    name?: string;
    body?: string;
    caption?: string;
    messages?: string[];
    node_id?: number | string;
    timestamp: Date | string | number;
    shouldEnd?: boolean;
    isFromMe?: boolean;
    next_child_id?: number;
    ref?: string;
    host?: string;
    [key: string]: any;
};
export type StatusChck = 'pending' | 'in-progress' | 'completed' | 'reset';
export interface StateManager {
    /**
     * Updates the value associated with the given key.
     *
     * @param {string} key - The key for which the value needs to be updated.
     * @param {any} value - The new value to be associated with the key.
     * @returns {Promise<void>} - A promise that resolves when the update is complete.
     */
    update: (key: string, value: any) => Promise<void>;
    /**
     * Retrieves a value from storage by its key.
     *
     * @template T - The type of the value to be retrieved.
     * @param {string} key - The key associated with the value to retrieve.
     * @returns {Promise<T>} - A promise that resolves to the retrieved value.
     */
    get: <T = any>(key: string) => Promise<T>;
    clear: () => Promise<void>;
    delete: (key: string) => Promise<void>;
}
export type StateHandler = {
    state: any;
    manager: StateManager;
};
export type EventRegex = {
    MEDIA: RegExp;
    DOCUMENT: RegExp;
    VOICE_NOTE: RegExp;
    LOCATION: RegExp;
    ORDER: RegExp;
    TEMPLATE: RegExp;
    ANY: RegExp;
};
export type StaticEventsxp = "image" | "media" | "voice" | "document" | "location" | "order" | "template" | "any";
export type Eventsxp = StaticEventsxp | (string & {});
export type WorkflowKey = Eventsxp | RegExp | Array<Eventsxp | RegExp>;
export type ProviderEventTypes = {
    message: [arg1: any];
    require_action: [
        arg1: {
            title: string;
            instructions: string[];
        }
    ];
    notice: [
        arg1: {
            title: string;
            instructions: string[];
        }
    ];
    ready: any;
    auth_failure: any;
    host: any;
    [extra: string]: any | [args: any];
};
export type GlobalVendorArgs<V = {
    [key: string]: any;
}> = {
    name?: string;
    port?: number;
} & V;
export {};
