function _array_like_to_array(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _array_with_holes(arr) {
    if (Array.isArray(arr)) return arr;
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
function _instanceof(left, right) {
    if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
        return !!right[Symbol.hasInstance](left);
    } else {
        return left instanceof right;
    }
}
function _iterable_to_array_limit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
        for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
            _arr.push(_s.value);
            if (i && _arr.length === i) break;
        }
    } catch (err) {
        _d = true;
        _e = err;
    } finally{
        try {
            if (!_n && _i["return"] != null) _i["return"]();
        } finally{
            if (_d) throw _e;
        }
    }
    return _arr;
}
function _non_iterable_rest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _object_spread(target) {
    for(var i = 1; i < arguments.length; i++){
        var source = arguments[i] != null ? arguments[i] : {};
        var ownKeys = Object.keys(source);
        if (typeof Object.getOwnPropertySymbols === "function") {
            ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
                return Object.getOwnPropertyDescriptor(source, sym).enumerable;
            }));
        }
        ownKeys.forEach(function(key) {
            _define_property(target, key, source[key]);
        });
    }
    return target;
}
function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);
    if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);
        if (enumerableOnly) {
            symbols = symbols.filter(function(sym) {
                return Object.getOwnPropertyDescriptor(object, sym).enumerable;
            });
        }
        keys.push.apply(keys, symbols);
    }
    return keys;
}
function _object_spread_props(target, source) {
    source = source != null ? source : {};
    if (Object.getOwnPropertyDescriptors) {
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
    } else {
        ownKeys(Object(source)).forEach(function(key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
        });
    }
    return target;
}
function _sliced_to_array(arr, i) {
    return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _unsupported_iterable_to_array(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _array_like_to_array(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
import { CircleDashed, Copy, Play } from "@sofa-design/icons";
import { Button, ConfigProvider, message } from "antd";
import classNames from "clsx";
import copy from "copy-to-clipboard";
import React, { forwardRef, memo, useCallback, useContext, useImperativeHandle, useMemo, useState } from "react";
import { I18nContext } from "../../I18n";
import { SchemaRenderer } from "../SchemaRenderer";
import { mdDataSchemaValidator } from "../validator";
import { AceEditorWrapper } from "./AceEditorWrapper";
import { useStyle } from "./style";
/**
 * Schema编辑器组件
 *
 * 提供schema的实时编辑和预览功能，底层使用AceEditor编辑schema中的HTML内容
 */ var SchemaEditorComponent = /*#__PURE__*/ forwardRef(function(param, ref) {
    var initialSchema = param.initialSchema, _param_initialValues = param.initialValues, initialValues = _param_initialValues === void 0 ? {} : _param_initialValues, _param_height = param.height, height = _param_height === void 0 ? 600 : _param_height, _param_readonly = param.readonly, readonly = _param_readonly === void 0 ? false : _param_readonly, onChange = param.onChange, _param_className = param.className, className = _param_className === void 0 ? '' : _param_className, _param_showPreview = param.showPreview, showPreview = _param_showPreview === void 0 ? true : _param_showPreview, previewConfig = param.previewConfig, htmlActions = param.htmlActions;
    // 使用 ConfigProvider 获取前缀类名
    var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
    var prefixCls = getPrefixCls('schema-editor');
    var _useStyle = useStyle(prefixCls), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
    var locale = useContext(I18nContext).locale;
    var _useState = _sliced_to_array(useState(function() {
        return initialSchema || {
            version: '1.0.0',
            name: locale['schemaEditor.untitledSchema'],
            description: '',
            component: {
                type: 'html',
                schema: '<div>Hello World</div>'
            }
        };
    }), 2), schema = _useState[0], setSchema = _useState[1];
    var _useState1 = _sliced_to_array(useState(initialValues || {}), 2), values = _useState1[0], setValues = _useState1[1];
    var _useState2 = _sliced_to_array(useState(''), 2), validationError = _useState2[0], setValidationError = _useState2[1];
    var _useState3 = _sliced_to_array(useState({}), 2), renderedSchema = _useState3[0], setRenderedSchema = _useState3[1];
    var _useState4 = _sliced_to_array(useState(false), 2), isSchemaRendered = _useState4[0], setIsSchemaRendered = _useState4[1];
    // 使用 ref 存储最新值，确保 ref 方法能立即获取到最新状态
    var schemaRef = React.useRef(schema);
    // 同步更新 ref 值
    React.useEffect(function() {
        schemaRef.current = schema;
    }, [
        schema
    ]);
    // 将schema转换为JSON字符串
    var schemaToJson = useCallback(function(schemaData) {
        try {
            return JSON.stringify(schemaData, null, 2);
        } catch (error) {
            console.error(locale['schemaEditor.schemaSerializationError'], error);
            return '{}';
        }
    }, [
        locale
    ]);
    // 将JSON字符串转换为schema对象
    var jsonToSchema = useCallback(function(jsonString) {
        try {
            return JSON.parse(jsonString);
        } catch (error) {
            console.error(locale['schemaEditor.schemaParseError'], error);
            return null;
        }
    }, [
        locale
    ]);
    // 从 schema 派生 htmlContent 和 schemaString
    var htmlContent = useMemo(function() {
        var _schema_component;
        return ((_schema_component = schema.component) === null || _schema_component === void 0 ? void 0 : _schema_component.schema) || '';
    }, [
        schema
    ]);
    var schemaString = useMemo(function() {
        return schemaToJson(schema);
    }, [
        schema,
        schemaToJson
    ]);
    // 验证schema
    var validateSchema = useCallback(function(schemaData) {
        try {
            var result = mdDataSchemaValidator.validate(schemaData);
            if (!result.valid) {
                var _result_errors;
                return ((_result_errors = result.errors) === null || _result_errors === void 0 ? void 0 : _result_errors.map(function(err) {
                    return err.message;
                }).join(', ')) || locale['schemaEditor.validationFailed'];
            }
            return '';
        } catch (error) {
            return _instanceof(error, Error) ? error.message : locale['schemaEditor.validationFailed'];
        }
    }, [
        locale
    ]);
    // 处理schema变更
    var handleSchemaChange = useCallback(function(newSchema) {
        setSchema(newSchema);
        setValidationError(validateSchema(newSchema));
        onChange === null || onChange === void 0 ? void 0 : onChange(newSchema, values);
    }, [
        values,
        onChange,
        validateSchema
    ]);
    // 处理HTML内容变更
    var handleHtmlChange = useCallback(function(newHtml) {
        var newSchema = _object_spread_props(_object_spread({}, schemaRef.current), {
            component: _object_spread_props(_object_spread({}, schemaRef.current.component), {
                schema: newHtml
            })
        });
        handleSchemaChange(newSchema);
    }, [
        handleSchemaChange
    ]);
    // 处理JSON编辑器变更
    var handleJsonChange = useCallback(function(newJsonString) {
        var newSchema = jsonToSchema(newJsonString);
        if (newSchema) {
            handleSchemaChange(newSchema);
        }
    }, [
        jsonToSchema,
        handleSchemaChange
    ]);
    // 处理运行按钮点击
    var handleRunClick = useCallback(function() {
        var currentSchema = schemaRef.current;
        setRenderedSchema(_object_spread({}, currentSchema));
        // 更新values状态，使用schema中的initialValues
        if (currentSchema.initialValues) {
            setValues(currentSchema.initialValues);
        }
        setIsSchemaRendered(true);
    }, []);
    // 复制函数
    var handleCopyContent = useCallback(function(content, type) {
        if (!content || !content.trim()) {
            message.warning(locale['schemaEditor.noContentToCopy']);
            return;
        }
        try {
            var ok = copy(content);
            if (ok) {
                message.success("".concat(type === 'html' ? 'HTML' : 'JSON').concat(locale['schemaEditor.copySuccess']));
            } else {
                message.error(locale['schemaEditor.copyFailed']);
            }
        } catch (error) {
            message.error(locale['schemaEditor.copyFailed']);
            console.error(locale['schemaEditor.copyFailed'], error);
        }
    }, [
        locale
    ]);
    // 处理复制HTML内容
    var handleCopyHtml = useCallback(function() {
        handleCopyContent(htmlContent, 'html');
    }, [
        htmlContent,
        handleCopyContent
    ]);
    // 处理复制JSON内容
    var handleCopyJson = useCallback(function() {
        handleCopyContent(schemaString, 'json');
    }, [
        schemaString,
        handleCopyContent
    ]);
    // 统一的设置内容方法，支持 HTML 或 JSON 字符串
    var setContent = useCallback(function(content, type) {
        if (type === 'html') {
            handleHtmlChange(content);
        } else {
            handleJsonChange(content);
        }
    }, [
        handleHtmlChange,
        handleJsonChange
    ]);
    // 暴露 ref 方法
    useImperativeHandle(ref, function() {
        return {
            setSchema: function setSchema(newSchema) {
                handleSchemaChange(newSchema);
                schemaRef.current = newSchema;
            },
            setHtmlContent: function setHtmlContent(newHtml) {
                setContent(newHtml, 'html');
            },
            setSchemaString: function setSchemaString(newJsonString) {
                setContent(newJsonString, 'json');
            },
            getSchema: function getSchema() {
                return schemaRef.current;
            },
            getHtmlContent: function getHtmlContent() {
                var _schemaRef_current_component;
                return ((_schemaRef_current_component = schemaRef.current.component) === null || _schemaRef_current_component === void 0 ? void 0 : _schemaRef_current_component.schema) || '';
            },
            getSchemaString: function getSchemaString() {
                return schemaToJson(schemaRef.current);
            },
            run: handleRunClick,
            copyHtml: handleCopyHtml,
            copyJson: handleCopyJson
        };
    }, [
        handleSchemaChange,
        setContent,
        handleRunClick,
        handleCopyHtml,
        handleCopyJson,
        schemaToJson
    ]);
    // 渲染预览区域
    var renderPreview = useMemo(function() {
        if (!showPreview) return null;
        return /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-preview"), hashId)
        }, /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-preview-header"), hashId)
        }, /*#__PURE__*/ React.createElement("h3", null, locale['schemaEditor.realtimePreview']), validationError && /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-error"), hashId)
        }, /*#__PURE__*/ React.createElement("span", null, "⚠️ ", validationError))), /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-preview-content"), hashId)
        }, isSchemaRendered ? /*#__PURE__*/ React.createElement(SchemaRenderer, {
            schema: renderedSchema,
            values: values,
            config: previewConfig,
            fallbackContent: /*#__PURE__*/ React.createElement("div", {
                className: classNames("".concat(prefixCls, "-fallback"), hashId)
            }, /*#__PURE__*/ React.createElement("p", null, locale['schemaEditor.previewLoadFailed']), /*#__PURE__*/ React.createElement("p", null, locale['schemaEditor.checkSchemaFormat']))
        }) : /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-preview-content-empty"), hashId)
        }, /*#__PURE__*/ React.createElement(CircleDashed, {
            style: {
                width: 80,
                height: 80
            }
        }), /*#__PURE__*/ React.createElement("p", null, locale['schemaEditor.inputSchemaToPreview']))));
    }, [
        showPreview,
        isSchemaRendered,
        renderedSchema,
        values,
        validationError,
        previewConfig,
        hashId,
        locale,
        prefixCls
    ]);
    // 渲染HTML编辑器
    var renderHtmlEditor = useMemo(function() {
        return /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-html"), hashId)
        }, /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-html-header"), hashId)
        }, /*#__PURE__*/ React.createElement("h3", null, locale['schemaEditor.htmlTemplate']), /*#__PURE__*/ React.createElement("div", {
            style: {
                display: 'flex'
            }
        }, /*#__PURE__*/ React.createElement(Button, {
            type: "text",
            icon: /*#__PURE__*/ React.createElement(Play, {
                style: {
                    width: 14,
                    height: 14
                }
            }),
            onClick: handleRunClick
        }, locale['schemaEditor.run']), /*#__PURE__*/ React.createElement(Button, {
            type: "text",
            icon: /*#__PURE__*/ React.createElement(Copy, {
                style: {
                    width: 14,
                    height: 14
                }
            }),
            onClick: handleCopyHtml
        }), htmlActions)), /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-html-content"), hashId)
        }, /*#__PURE__*/ React.createElement(AceEditorWrapper, {
            value: htmlContent,
            language: "html",
            onChange: handleHtmlChange,
            readonly: readonly
        })));
    }, [
        htmlContent,
        handleHtmlChange,
        readonly,
        hashId,
        locale,
        handleRunClick,
        handleCopyHtml,
        htmlActions,
        prefixCls
    ]);
    // 渲染JSON编辑器
    var renderJsonEditor = useMemo(function() {
        return /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-json"), hashId)
        }, /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-json-header"), hashId)
        }, /*#__PURE__*/ React.createElement("h3", null, locale['schemaEditor.schemaJson']), /*#__PURE__*/ React.createElement("div", {
            style: {
                display: 'flex'
            }
        }, /*#__PURE__*/ React.createElement(Button, {
            type: "text",
            icon: /*#__PURE__*/ React.createElement(Copy, {
                style: {
                    width: 14,
                    height: 14
                }
            }),
            onClick: handleCopyJson
        }))), /*#__PURE__*/ React.createElement("div", {
            className: classNames("".concat(prefixCls, "-json-content"), hashId)
        }, /*#__PURE__*/ React.createElement(AceEditorWrapper, {
            value: schemaString,
            language: "json",
            onChange: handleJsonChange,
            readonly: readonly
        })));
    }, [
        schemaString,
        handleJsonChange,
        readonly,
        hashId,
        locale,
        handleCopyJson,
        prefixCls
    ]);
    return wrapSSR(/*#__PURE__*/ React.createElement("div", {
        className: classNames(prefixCls, className, hashId),
        "data-testid": prefixCls,
        style: {
            height: typeof height === 'number' ? "".concat(height, "px") : height
        }
    }, /*#__PURE__*/ React.createElement("div", {
        className: classNames("".concat(prefixCls, "-container"), hashId)
    }, /*#__PURE__*/ React.createElement("div", {
        className: classNames("".concat(prefixCls, "-left"), hashId)
    }, renderPreview), /*#__PURE__*/ React.createElement("div", {
        className: classNames("".concat(prefixCls, "-right"), hashId)
    }, renderHtmlEditor, renderJsonEditor))));
});
SchemaEditorComponent.displayName = 'SchemaEditor';
// 使用 React.memo 优化性能，避免不必要的重新渲染
export var SchemaEditor = /*#__PURE__*/ memo(SchemaEditorComponent);
export default SchemaEditor;
