'use client';
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { defaultOptions } from '../../elements/CodeEditor/constants.js';
import { CodeEditor } from '../../elements/CodeEditor/index.js';
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js';
import { useField } from '../../forms/useField/index.js';
import { withCondition } from '../../forms/withCondition/index.js';
import { FieldDescription } from '../FieldDescription/index.js';
import { FieldError } from '../FieldError/index.js';
import { FieldLabel } from '../FieldLabel/index.js';
import { mergeFieldStyles } from '../mergeFieldStyles.js';
import { fieldBaseClass } from '../shared/index.js';
import './index.scss';
const baseClass = 'json-field';
const JSONFieldComponent = (props)=>{
    const { field, field: { admin: { className, description, editorOptions, maxHeight } = {}, jsonSchema, label, localized, required }, path: pathFromProps, readOnly, validate } = props;
    const { insertSpaces = defaultOptions.insertSpaces, tabSize = defaultOptions.tabSize } = editorOptions || {};
    const formatJSON = useCallback((value)=>{
        if (value === undefined) {
            return undefined;
        }
        if (value === null) {
            return '';
        }
        return insertSpaces ? JSON.stringify(value, null, tabSize) : JSON.stringify(value, null, '\t');
    }, [
        tabSize,
        insertSpaces
    ]);
    const [jsonError, setJsonError] = useState();
    const inputChangeFromRef = React.useRef('formState');
    const [recalculatedHeightAt, setRecalculatedHeightAt] = useState(Date.now());
    const memoizedValidate = useCallback((value, options)=>{
        if (typeof validate === 'function') {
            return validate(value, {
                ...options,
                jsonError,
                required
            });
        }
    }, [
        validate,
        required,
        jsonError
    ]);
    const { customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {}, disabled, initialValue, path, setValue, showError, value } = useField({
        potentiallyStalePath: pathFromProps,
        validate: memoizedValidate
    });
    const stringValueRef = React.useRef(formatJSON(value ?? initialValue));
    const handleMount = useCallback((editor, monaco)=>{
        if (!jsonSchema) {
            return;
        }
        monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
            enableSchemaRequest: true,
            schemas: [
                ...monaco.languages.json.jsonDefaults.diagnosticsOptions.schemas || [],
                jsonSchema
            ],
            validate: true
        });
        const uri = jsonSchema.uri;
        const newUri = uri.includes('?') ? `${uri}&${crypto.randomUUID ? crypto.randomUUID() : uuidv4()}` : `${uri}?${crypto.randomUUID ? crypto.randomUUID() : uuidv4()}`;
        editor.setModel(monaco.editor.createModel(formatJSON(value) || '', 'json', monaco.Uri.parse(newUri)));
    }, [
        jsonSchema,
        formatJSON,
        value
    ]);
    const handleChange = useCallback((val)=>{
        if (readOnly || disabled) {
            return;
        }
        inputChangeFromRef.current = 'internalEditor';
        try {
            setValue(val ? JSON.parse(val) : null);
            stringValueRef.current = val;
            setJsonError(undefined);
        } catch (e) {
            setValue(val ? val : null);
            stringValueRef.current = val;
            setJsonError(e);
        }
    }, [
        readOnly,
        disabled,
        setValue
    ]);
    useEffect(()=>{
        if (inputChangeFromRef.current === 'formState') {
            const newStringValue = formatJSON(value ?? initialValue);
            if (newStringValue !== stringValueRef.current) {
                stringValueRef.current = newStringValue;
                setRecalculatedHeightAt(Date.now());
            }
        }
        inputChangeFromRef.current = 'formState';
    }, [
        initialValue,
        path,
        formatJSON,
        value
    ]);
    const styles = useMemo(()=>mergeFieldStyles(field), [
        field
    ]);
    return /*#__PURE__*/ _jsxDEV("div", {
        className: [
            fieldBaseClass,
            baseClass,
            className,
            showError && 'error',
            (readOnly || disabled) && 'read-only'
        ].filter(Boolean).join(' '),
        style: styles,
        children: [
            /*#__PURE__*/ _jsxDEV(RenderCustomComponent, {
                CustomComponent: Label,
                Fallback: /*#__PURE__*/ _jsxDEV(FieldLabel, {
                    label: label,
                    localized: localized,
                    path: path,
                    required: required
                }, void 0, false, {
                    fileName: "src/fields/JSON/index.tsx",
                    lineNumber: 158,
                    columnNumber: 11
                }, void 0)
            }, void 0, false, {
                fileName: "src/fields/JSON/index.tsx",
                lineNumber: 155,
                columnNumber: 7
            }, this),
            /*#__PURE__*/ _jsxDEV("div", {
                className: `${fieldBaseClass}__wrap`,
                children: [
                    /*#__PURE__*/ _jsxDEV(RenderCustomComponent, {
                        CustomComponent: Error,
                        Fallback: /*#__PURE__*/ _jsxDEV(FieldError, {
                            message: jsonError,
                            path: path,
                            showError: showError
                        }, void 0, false, {
                            fileName: "src/fields/JSON/index.tsx",
                            lineNumber: 164,
                            columnNumber: 21
                        }, void 0)
                    }, void 0, false, {
                        fileName: "src/fields/JSON/index.tsx",
                        lineNumber: 162,
                        columnNumber: 9
                    }, this),
                    BeforeInput,
                    /*#__PURE__*/ _jsxDEV(CodeEditor, {
                        defaultLanguage: "json",
                        maxHeight: maxHeight,
                        onChange: handleChange,
                        onMount: handleMount,
                        options: editorOptions,
                        readOnly: readOnly || disabled,
                        recalculatedHeightAt: recalculatedHeightAt,
                        value: stringValueRef.current,
                        wrapperProps: {
                            id: `field-${path?.replace(/\./g, '__')}`
                        }
                    }, void 0, false, {
                        fileName: "src/fields/JSON/index.tsx",
                        lineNumber: 167,
                        columnNumber: 9
                    }, this),
                    AfterInput
                ]
            }, void 0, true, {
                fileName: "src/fields/JSON/index.tsx",
                lineNumber: 161,
                columnNumber: 7
            }, this),
            /*#__PURE__*/ _jsxDEV(RenderCustomComponent, {
                CustomComponent: Description,
                Fallback: /*#__PURE__*/ _jsxDEV(FieldDescription, {
                    description: description,
                    path: path
                }, void 0, false, {
                    fileName: "src/fields/JSON/index.tsx",
                    lineNumber: 184,
                    columnNumber: 19
                }, void 0)
            }, void 0, false, {
                fileName: "src/fields/JSON/index.tsx",
                lineNumber: 182,
                columnNumber: 7
            }, this)
        ]
    }, void 0, true, {
        fileName: "src/fields/JSON/index.tsx",
        lineNumber: 143,
        columnNumber: 5
    }, this);
};
export const JSONField = withCondition(JSONFieldComponent);

//# sourceMappingURL=index.js.map