import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { basicSetup } from 'codemirror';
import { useMemo, useRef, useState } from 'react';
import { useUserSession } from '@vertesia/ui/session';
import { json } from '@codemirror/lang-json';
import { CodeMirrorEditor, SchemaEditor, useSchema } from '@vertesia/ui/widgets';
import { Button, useToast } from '@vertesia/ui/core';
import { Ajv } from "ajv";
const CODE_MIRROR_EXTENSIONS = [basicSetup, json()];
export function ObjectSchemaEditor({ objectType, onSchemaUpdate }) {
    const { store } = useUserSession();
    const toast = useToast();
    const [isUpdating, setUpdating] = useState(false);
    const schema = useSchema(objectType.object_schema);
    const editorRef = useRef(undefined);
    const [displayJson, setDisplayJson] = useState(false);
    const value = useMemo(() => {
        return jsonToContent(schema.schema);
    }, [schema]);
    const onSave = () => {
        if (displayJson) {
            if (!updateSchemaFromJson()) {
                return;
            }
        }
        setUpdating(true);
        store.types.update(objectType.id, { object_schema: schema.schema }).then(() => {
            onSchemaUpdate(schema);
            toast({
                status: 'success',
                title: 'Schema updated',
                description: 'The schema has been updated successfully',
                duration: 2000
            });
        }).catch((err) => {
            toast({
                status: 'error',
                title: 'Failed to update schema',
                description: err.message,
                duration: 5000
            });
        }).finally(() => {
            setUpdating(false);
        });
    };
    const handleOnSave = () => {
        if (displayJson) {
            if (!updateSchemaFromJson()) {
                return;
            }
        }
        setDisplayJson(prev => !prev);
    };
    const updateSchemaFromJson = () => {
        if (editorRef.current) {
            const value = editorRef.current.getValue();
            try {
                const newSchema = contentToJson(value);
                validateSchema(newSchema);
                schema.replaceSchema(newSchema);
            }
            catch (err) {
                toast({
                    status: 'error',
                    title: 'Invalid JSON Schema',
                    description: err.message,
                    duration: 5000
                });
                return false;
            }
        }
        return true;
    };
    return (_jsxs("div", { className: "mx-2 my-2 rounded-2xl border border-solid shadow-md border-spacing-2", children: [_jsxs("div", { className: "flex items-center rounded-t-md border-b gap-x-2 py-2 pl-4 pr-2", children: [_jsx("div", { className: "text-base font-semibold", children: "Schema Editor" }), _jsx("div", { children: _jsx(Button, { variant: "outline", size: "sm", onClick: handleOnSave, children: displayJson ? "Edit Schema" : "Edit Json" }) }), _jsx("div", { className: "ml-auto flex gap-x-2", children: _jsx(Button, { isLoading: isUpdating, variant: "outline", size: "sm", onClick: onSave, children: "Save Changes" }) })] }), _jsx("div", { className: "px-4 py-2", children: displayJson
                    ? _jsx(CodeMirrorEditor, { value: value, extensions: CODE_MIRROR_EXTENSIONS, editorRef: editorRef })
                    : _jsx(SchemaEditor, { schema: schema }) })] }));
}
function jsonToContent(json) {
    if (!json) {
        return '';
    }
    return JSON.stringify(json, null, 2);
}
function contentToJson(content) {
    if (!content?.trim()) {
        return undefined;
    }
    return JSON.parse(content.trim());
}
const validateSchema = (schema) => {
    try {
        const ajv = new Ajv({
            strict: false, // Enable strict mode to ensure all properties are validated
        });
        // Compile the schema. This implicitly validates the schema definition
        // against the JSON Schema draft that ajv supports by default.
        ajv.compile(schema);
    }
    catch (error) {
        throw new Error(`Invalid JSON Schema definition: ${error.message}`);
    }
};
//# sourceMappingURL=ObjectSchemaEditor.js.map