import { jsx as _jsx } from "react/jsx-runtime";
import { AgentSearchScope, mergeInCodePromptSchemas, supportsToolUse } from "@vertesia/common";
import { useUserSession } from "@vertesia/ui/session";
import Ajv from "ajv";
import { createContext, useContext, useEffect, useState } from "react";
// export interface ConversationWorkflowPayload {
//     config: {
//         environment?: ExecutionEnvironmentRef | undefined;
//         model?: string;
//     }
//     data?: JSONObject | undefined,
//     tool_names: string[],
// }
export class PayloadBuilder {
    vertesia;
    updateState;
    _interactive = true;
    _debug_mode = false;
    _collection;
    _start = false;
    _preserveRunValues = false;
    _interaction;
    _environment;
    _model = '';
    _tool_names = [];
    _data;
    _interactionParamsSchema;
    _inputValidator;
    constructor(vertesia, updateState) {
        this.vertesia = vertesia;
        this.updateState = updateState;
    }
    onStateChanged() {
        const newInstance = this.clone();
        this.updateState(newInstance);
    }
    clone() {
        const builder = new PayloadBuilder(this.vertesia, this.updateState);
        builder._interactionParamsSchema = this._interactionParamsSchema;
        builder._interaction = this._interaction;
        builder._data = this._data;
        builder._environment = this._environment;
        builder._model = this._model;
        builder._tool_names = [...this._tool_names];
        builder._interactive = this._interactive;
        builder._debug_mode = this._debug_mode;
        builder._inputValidator = this._inputValidator;
        builder._start = this._start;
        builder._collection = this._collection;
        builder._preserveRunValues = this._preserveRunValues;
        return builder;
    }
    get interactive() {
        return this._interactive;
    }
    set interactive(interactive) {
        if (interactive !== this._interactive) {
            this._interactive = interactive;
            this.onStateChanged();
        }
    }
    get debug_mode() {
        return this._debug_mode;
    }
    set debug_mode(debug_mode) {
        if (debug_mode !== this._debug_mode) {
            this._debug_mode = debug_mode;
            this.onStateChanged();
        }
    }
    get collection() {
        return this._collection;
    }
    set collection(collection) {
        if (collection !== this._collection) {
            this._collection = collection;
            this.onStateChanged();
        }
    }
    get search_scope() {
        return this._collection ? AgentSearchScope.Collection : undefined;
    }
    async restoreConversation(context) {
        // Handle version-specific interaction resolution
        let interactionRef = context.interaction;
        if (context.version) {
            const objectIdRegex = /^[a-fA-F0-9]{24}$/;
            if (!objectIdRegex.test(interactionRef)) {
                // regex to check if interactionRef is an object id (24 hex characters), only append version if not an object id
                interactionRef = `${interactionRef}@${context.version}`;
            }
        }
        const inter = await this.vertesia.interactions.catalog.resolve(interactionRef);
        const envId = inter.runtime?.environment || context.config?.environment;
        const model = context.config?.model;
        const env = await (envId ?
            this.vertesia.environments.retrieve(context.config?.environment)
            :
                Promise.resolve(undefined));
        this.interactionParamsSchema = context.interactionParamsSchema ?? null;
        // trigger the setter to update the corresponding interactionParamsSchema
        this.interaction = inter;
        this._tool_names = context.tool_names || [];
        this._data = context.data;
        this._interactive = context.interactive;
        this._debug_mode = context.debug_mode ?? false;
        this.collection = context.collection_id ?? undefined;
        // we need to trigger the setter to deal with default models
        this.environment = env;
        if (model) {
            this._model = model;
        }
        this.onStateChanged();
    }
    get interaction() {
        return this._interaction;
    }
    set interaction(interaction) {
        if (interaction?.id !== this._interaction?.id) {
            this._interaction = interaction;
            // trigger the setter to update the onChange state
            this.interactionParamsSchema = interaction ? mergeInCodePromptSchemas(interaction.prompts) : undefined;
            // Reset the validator when schema changes
            this._inputValidator = undefined;
            if (interaction && !this._preserveRunValues) {
                if (interaction.runtime?.environment) {
                    const envId = interaction.runtime.environment;
                    this.vertesia.environments.retrieve(envId).then((environment) => this.environment = environment);
                }
            }
            this.onStateChanged();
        }
    }
    get environment() {
        return this._environment;
    }
    set environment(environment) {
        if (environment?.id !== this._environment?.id) {
            this._environment = environment;
            if (!this._preserveRunValues) {
                // First try to use the interaction model, then the environment default model
                const interactionModel = this.interaction?.runtime?.model;
                if (interactionModel && environment && supportsToolUse(interactionModel, environment.provider)) {
                    this._model = interactionModel;
                }
                else {
                    this._model = environment?.default_model && supportsToolUse(environment.default_model, environment.provider)
                        ? environment.default_model : '';
                }
            }
            this.onStateChanged();
        }
    }
    get model() {
        return this._model;
    }
    set model(model) {
        if (model !== this._model) {
            this._model = model || '';
            this.onStateChanged();
        }
    }
    get tool_names() {
        return this._tool_names;
    }
    set tool_names(tools) {
        this._tool_names = tools;
        this.onStateChanged();
    }
    get data() {
        return this._data;
    }
    set data(prompt_data) {
        this._data = prompt_data;
        this.onStateChanged();
    }
    set run(run) {
        console.log("run", run);
        this.onStateChanged();
    }
    set start(value) {
        if (this._start !== value) {
            this._start = value;
            this.onStateChanged();
        }
    }
    get start() {
        return this._start;
    }
    get preserveRunValues() {
        return this._preserveRunValues;
    }
    set preserveRunValues(value) {
        this._preserveRunValues = value;
    }
    get interactionParamsSchema() {
        return this._interactionParamsSchema;
    }
    set interactionParamsSchema(schema) {
        if (this._interactionParamsSchema !== schema) {
            this._interactionParamsSchema = schema;
            this.onStateChanged();
        }
    }
    reset() {
        this._start = false;
        this._interactive = true;
        this._debug_mode = false;
        this._collection = undefined;
        this._preserveRunValues = false;
        this._model = '';
        this._environment = undefined;
        this._tool_names = [];
        this._interaction = undefined;
        this._data = undefined;
        this._interactionParamsSchema = null;
        this._inputValidator = undefined;
        this.model = undefined;
        this.environment = undefined;
        this.onStateChanged();
        if (location.hash) {
            const urlWithoutHash = window.location.origin + window.location.pathname + window.location.search;
            history.replaceState(null, '', urlWithoutHash);
            location.hash = '';
        }
    }
    validateInput() {
        if (!this._interactionParamsSchema) {
            return { isValid: true };
        }
        // If schema has changed or validator not initialized, recompile
        if (!this._inputValidator || this._inputValidator.schema !== this._interactionParamsSchema) {
            const ajv = new Ajv({ strict: false });
            this._inputValidator = {
                validate: ajv.compile(this._interactionParamsSchema),
                schema: this._interactionParamsSchema
            };
        }
        const prompt_data = this._data || {};
        const isValid = this._inputValidator.validate(prompt_data);
        if (!isValid) {
            const errorMessage = this._inputValidator.validate.errors
                ? this._inputValidator.validate.errors.map((err) => `${err.instancePath}: ${err.message}`).join(', ')
                : 'Invalid payload data';
            return { isValid: false, errorMessage };
        }
        return { isValid: true };
    }
}
export const PayloadContext = createContext(undefined);
export function PayloadBuilderProvider({ children }) {
    const { client } = useUserSession();
    const [builder, setBuilder] = useState();
    useEffect(() => {
        setBuilder(new PayloadBuilder(client, setBuilder));
    }, []);
    return builder && (_jsx(PayloadContext.Provider, { value: builder, children: children }));
}
export function usePayloadBuilder() {
    const ctx = useContext(PayloadContext);
    if (!ctx) {
        throw new Error('usePayloadBuilder must be used within a PayloadProvider');
    }
    return ctx;
}
//# sourceMappingURL=PayloadBuilder.js.map