import { jsx as _jsx } from "react/jsx-runtime";
import { mergePromptsSchema, supportsToolUse } from "@vertesia/common";
import { useUserSession } from "@vertesia/ui/session";
import Ajv from "ajv";
import { createContext, useContext, useEffect, useState } from "react";
export class PayloadBuilder {
    vertesia;
    updateState;
    _interactive = true;
    _debug_mode = false;
    _collection;
    _start = false;
    _preserveRunValues = false;
    payload;
    _interactionParamsSchema;
    _inputValidator;
    constructor(vertesia, updateState) {
        this.vertesia = vertesia;
        this.updateState = updateState;
        this.payload = {
            config: {
                model: '',
            },
            tool_names: [],
        };
    }
    onStateChanged() {
        const newInstance = this.clone();
        this.updateState(newInstance);
    }
    clone() {
        const builder = new PayloadBuilder(this.vertesia, this.updateState);
        builder._interactionParamsSchema = this._interactionParamsSchema;
        builder.payload = this.payload;
        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 ? "collection" : undefined;
    }
    get interaction() {
        return this.payload.interaction;
    }
    set interaction(interaction) {
        if (interaction?.id !== this.payload.interaction?.id) {
            this.payload.interaction = interaction;
            this._interactionParamsSchema = mergePromptsSchema(this.interaction);
            // Reset the validator when schema changes
            this._inputValidator = undefined;
            if (interaction && !this._preserveRunValues) {
                if (interaction.environment) {
                    if (typeof interaction.environment === 'string') {
                        this.vertesia.environments.retrieve(interaction.environment).then((environment) => this.environment = environment);
                    }
                    else {
                        this.payload.config.environment = interaction.environment;
                    }
                }
                if (interaction.model) {
                    this.payload.config.model = interaction.model;
                }
                else {
                    this.payload.config.model = this.environment?.default_model && supportsToolUse(this.environment.default_model, this.environment.provider)
                        ? this.environment.default_model : undefined;
                }
            }
            this.onStateChanged();
        }
    }
    get environment() {
        return this.payload.config.environment;
    }
    set environment(environment) {
        if (environment?.id !== this.payload.config.environment?.id) {
            this.payload.config.environment = environment;
            if (!this._preserveRunValues) {
                // First try to use the interaction model, then the environment default model
                const interactionModel = this.payload.interaction?.model;
                if (interactionModel && environment && supportsToolUse(interactionModel, environment.provider)) {
                    this.payload.config.model = interactionModel;
                }
                else {
                    this.payload.config.model = environment?.default_model && supportsToolUse(environment.default_model, environment.provider)
                        ? environment.default_model : undefined;
                }
            }
            this.onStateChanged();
        }
    }
    get model() {
        return this.payload.config.model;
    }
    set model(model) {
        if (model !== this.payload.config.model) {
            this.payload.config.model = model;
            this.onStateChanged();
        }
    }
    get tool_names() {
        return this.payload.tool_names;
    }
    set tool_names(tools) {
        this.payload.tool_names = tools;
        this.onStateChanged();
    }
    get data() {
        return this.payload.data;
    }
    set data(prompt_data) {
        this.payload.data = prompt_data;
        this.onStateChanged();
    }
    get config() {
        return this.payload.config;
    }
    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.payload = {
            config: {
                environment: undefined,
                model: '',
            },
            tool_names: [],
            interaction: undefined,
            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.payload.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