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 _iterable_to_array(iter) {
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
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 _object_without_properties(source, excluded) {
    if (source == null) return {};
    var target = {}, sourceKeys, key, i;
    if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
        sourceKeys = Reflect.ownKeys(source);
        for(i = 0; i < sourceKeys.length; i++){
            key = sourceKeys[i];
            if (excluded.indexOf(key) >= 0) continue;
            if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
            target[key] = source[key];
        }
        return target;
    }
    target = _object_without_properties_loose(source, excluded);
    if (Object.getOwnPropertySymbols) {
        sourceKeys = Object.getOwnPropertySymbols(source);
        for(i = 0; i < sourceKeys.length; i++){
            key = sourceKeys[i];
            if (excluded.indexOf(key) >= 0) continue;
            if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
            target[key] = source[key];
        }
    }
    return target;
}
function _object_without_properties_loose(source, excluded) {
    if (source == null) return {};
    var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
    for(i = 0; i < sourceKeys.length; i++){
        key = sourceKeys[i];
        if (excluded.indexOf(key) >= 0) continue;
        if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
        target[key] = 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 _to_array(arr) {
    return _array_with_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _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 dayjs from "dayjs";
import React, { useEffect, useMemo } from "react";
import { useSlate } from "slate-react";
import { ErrorBoundary } from "../../MarkdownEditor/editor/elements/ErrorBoundary";
import { useEditorStore } from "../../MarkdownEditor/editor/store";
import { DragHandle } from "../../MarkdownEditor/editor/tools/DragHandle";
import { useMEditor } from "../../MarkdownEditor/hooks/editor";
import { ChartRender } from "./ChartRender";
import { getDataHash } from "./utils";
/**
 * @fileoverview 图表插件主入口文件
 *
 * 该文件提供了完整的图表功能，包括：
 * - 多种图表类型的组件（饼图、柱状图、折线图、面积图等）
 * - 图表渲染和配置功能
 * - 数据处理和格式化工具
 * - 图表属性工具栏
 * - 图表标记和容器组件
 *
 * @author md-editor
 * @version 1.0.0
 * @since 2024
 */ // 图表属性工具栏
export { ChartAttrToolBar } from "./ChartAttrToolBar";
// 图表标记组件
export * from "./ChartMark";
// 图表渲染组件
export { ChartRender } from "./ChartRender";
// 图表组件导出
export { default as AreaChart } from "./AreaChart";
export { default as BarChart } from "./BarChart";
export { default as ChartStatistic } from "./ChartStatistic";
export { default as DonutChart } from "./DonutChart";
export { default as FunnelChart } from "./FunnelChart";
export { default as LineChart } from "./LineChart";
export { default as RadarChart } from "./RadarChart";
export { default as ScatterChart } from "./ScatterChart";
// 工具与常量导出
export { defaultColorList } from "./const";
export { debounce as chartDebounce, stringFormatNumber } from "./utils";
// 复用组件与类型导出
export { ChartFilter, ChartToolBar, downloadChart } from "./components";
/**
 * 转化数字，将字符串转化为数字，即使非标准数字也可以转化
 * @param {string} val - 要转换的字符串
 * @param {any} locale - 本地化配置
 * @returns {number|NaN} 转换后的数字或NaN
 */ function reverseFormatNumber(val, locale) {
    var group = new Intl.NumberFormat(locale).format(1111).replace(/1/g, '');
    var decimal = new Intl.NumberFormat(locale).format(1.1).replace(/1/g, '');
    var reversedVal = val.replace(new RegExp('\\' + group, 'g'), '');
    reversedVal = reversedVal.replace(new RegExp('\\' + decimal, 'g'), '.');
    return Number.isNaN(reversedVal) ? NaN : Number(reversedVal);
}
/**
 * 验证并格式化日期字符串
 * @param {string} dateString - 日期字符串
 * @returns {string} 格式化后的日期字符串
 */ function isValidDate(dateString) {
    var defaultDateFormats = [
        'YYYY-MM-DD',
        'YYYY-MM-DD HH:mm:ss',
        'YYYY/MM/DD',
        'YYYY/MM/DD HH:mm:ss',
        'DD/MM/YYYY',
        'DD/MM/YYYY HH:mm:ss',
        'MMMM D, YYYY',
        'MMMM D, YYYY h:mm A',
        'MMM D, YYYY',
        'MMM D, YYYY h:mm A',
        'ddd, MMM D, YYYY h:mm A'
    ];
    for(var i = 0; i < defaultDateFormats.length; i++){
        if (dayjs(dateString, defaultDateFormats[i]).isValid()) {
            return dayjs(dateString).format(defaultDateFormats[i]);
        }
    }
    if (dayjs(dateString).isValid()) {
        return dayjs(dateString).format('YYYY-MM-DD');
    }
    return dateString;
}
/**
 * 转化数字，转化不成功继续用string
 * @param {string} value - 要转换的值
 * @returns {number|string} 转换后的数字或原字符串
 */ var numberString = function(value) {
    if (!value) return value;
    try {
        if (typeof value === 'number') return value;
        if (typeof value === 'string') {
            var formattedValue = reverseFormatNumber(value, 'en-US');
            if (!isNaN(formattedValue)) return formattedValue;
            return isValidDate(value);
        }
        return value;
    } catch (error) {
        return value;
    }
};
/**
 * 按类别分组数据
 * @param {any[]} data - 数据数组
 * @param {any} key - 分组键
 * @returns {Object} 分组后的数据对象
 */ var groupByCategory = function(data, key) {
    return data.reduce(function(group, product) {
        var _group_category;
        var category = product[key];
        group[category] = (_group_category = group[category]) !== null && _group_category !== void 0 ? _group_category : [];
        group[category].push(product);
        return group;
    }, {});
};
/**
 * ChartElement 组件 - 图表元素组件
 *
 * 该组件用于在Markdown编辑器中渲染图表，支持多种图表类型和数据处理。
 * 提供图表配置、数据转换、错误处理等功能。
 *
 * @component
 * @description 图表元素组件，在编辑器中渲染各种类型的图表
 * @param {RenderElementProps} props - 组件属性
 * @param {Object} props.element - 图表元素数据
 * @param {Object} props.attributes - 元素属性
 * @param {React.ReactNode} props.children - 子元素
 *
 * @example
 * ```tsx
 * <ChartElement
 *   element={chartElement}
 *   attributes={attributes}
 *   children={children}
 * />
 * ```
 *
 * @returns {React.ReactElement} 渲染的图表元素组件
 *
 * @remarks
 * - 支持多种图表类型（饼图、柱状图、折线图、面积图等）
 * - 提供数据格式转换功能
 * - 支持日期和数字格式化
 * - 使用ErrorBoundary处理渲染错误
 * - 提供拖拽手柄功能
 * - 支持图表配置和自定义
 * - 集成编辑器状态管理
 * - 提供响应式布局
 */ export var ChartElement = function(props) {
    var _node_otherProps, _node_otherProps1, _node_otherProps2, _node_otherProps3, _node_otherProps4, _node_otherProps5, _node_otherProps_columns, _node_otherProps6;
    var _useEditorStore = useEditorStore(), store = _useEditorStore.store, readonly = _useEditorStore.readonly, markdownContainerRef = _useEditorStore.markdownContainerRef, rootContainer = _useEditorStore.rootContainer;
    var editor = useSlate();
    var node = props.element, attributes = props.attributes, children = props.children;
    // 使用更高效的依赖项比较，避免 JSON.stringify 的性能开销
    var dataSourceHash = useMemo(function() {
        var _node_otherProps;
        return getDataHash(((_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.dataSource) || []);
    }, [
        (_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.dataSource
    ]);
    var chartData = useMemo(function() {
        var _node_otherProps;
        var dataSource = ((_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.dataSource) || [];
        if (dataSource.length === 0) {
            return [];
        }
        // 获取第一行的 keys 作为参考
        var firstRowKeys = Object.keys(dataSource[0]).sort();
        // 处理数据并过滤掉最后一行（如果它的 keys 和第一行不同）
        var processed = dataSource.map(function(item) {
            return _object_spread_props(_object_spread({}, item), {
                column_list: Object.keys(item)
            });
        });
        // 检查最后一行是否完整
        if (processed.length > 1) {
            var lastRow = processed[processed.length - 1];
            var lastRowKeys = Object.keys(lastRow).filter(function(key) {
                return key !== 'column_list';
            }).sort();
            // 如果最后一行的 keys 和第一行不同，丢弃最后一行
            if (lastRowKeys.length !== firstRowKeys.length || !lastRowKeys.every(function(key, index) {
                return key === firstRowKeys[index];
            })) {
                return processed.slice(0, -1);
            }
        }
        return processed;
    }, [
        dataSourceHash,
        (_node_otherProps1 = node.otherProps) === null || _node_otherProps1 === void 0 ? void 0 : _node_otherProps1.dataSource
    ]);
    var columns = ((_node_otherProps2 = node.otherProps) === null || _node_otherProps2 === void 0 ? void 0 : _node_otherProps2.columns) || [];
    // 检查图表是否未闭合
    var isUnclosed = (node === null || node === void 0 ? void 0 : (_node_otherProps3 = node.otherProps) === null || _node_otherProps3 === void 0 ? void 0 : _node_otherProps3.finished) === false;
    // 获取编辑器更新函数
    var _useMEditor = _sliced_to_array(useMEditor(node), 2), update = _useMEditor[1];
    // 判断是否是最后一个节点
    var isLastNode = useMemo(function() {
        try {
            return store.isLatestNode(node);
        } catch (unused) {
            return false;
        }
    }, [
        store,
        node
    ]);
    // 如果不是最后一个节点，且未闭合，立即设置为完成
    useEffect(function() {
        if (isUnclosed && !readonly && !isLastNode) {
            var _node_otherProps;
            // 检查 finished 是否仍然是 false（可能已经被其他逻辑更新）
            if ((node === null || node === void 0 ? void 0 : (_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.finished) === false) {
                update({
                    otherProps: _object_spread_props(_object_spread({}, node === null || node === void 0 ? void 0 : node.otherProps), {
                        finished: true
                    })
                }, node);
            }
        }
    }, [
        isUnclosed,
        readonly,
        isLastNode,
        node,
        update
    ]);
    // 5 秒超时机制：如果是最后一个节点且未闭合，5 秒后自动设置为完成
    useEffect(function() {
        if (isUnclosed && !readonly && isLastNode) {
            var timer = setTimeout(function() {
                var _node_otherProps;
                // 检查 finished 是否仍然是 false（可能已经被其他逻辑更新）
                if ((node === null || node === void 0 ? void 0 : (_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.finished) === false) {
                    update({
                        otherProps: _object_spread_props(_object_spread({}, node === null || node === void 0 ? void 0 : node.otherProps), {
                            finished: true
                        })
                    }, node);
                }
            }, 5000); // 5 秒超时
            return function() {
                clearTimeout(timer);
            };
        }
    }, [
        isUnclosed,
        readonly,
        isLastNode,
        node,
        update
    ]);
    var _React_useState = _sliced_to_array(React.useState(2), 2), columnLength = _React_useState[0], setColumnLength = _React_useState[1];
    var config = [
        ((_node_otherProps4 = node.otherProps) === null || _node_otherProps4 === void 0 ? void 0 : _node_otherProps4.config) || node.otherProps
    ].flat(1);
    var htmlRef = React.useRef(null);
    var _React_useState1 = _sliced_to_array(React.useState(256), 2), minWidth = _React_useState1[0], setMinWidth = _React_useState1[1];
    useEffect(function() {
        var updateWidth = function() {
            var _rootContainer_current, _htmlRef_current_parentElement, _htmlRef_current;
            var width = Math.max((rootContainer === null || rootContainer === void 0 ? void 0 : (_rootContainer_current = rootContainer.current) === null || _rootContainer_current === void 0 ? void 0 : _rootContainer_current.clientWidth) || ((_htmlRef_current = htmlRef.current) === null || _htmlRef_current === void 0 ? void 0 : (_htmlRef_current_parentElement = _htmlRef_current.parentElement) === null || _htmlRef_current_parentElement === void 0 ? void 0 : _htmlRef_current_parentElement.clientWidth) || 256, 256);
            setMinWidth(width || 256);
            setColumnLength(Math.min(Math.floor(width / 256), config.length));
        };
        updateWidth();
        window.addEventListener('resize', updateWidth);
        return function() {
            return window.removeEventListener('resize', updateWidth);
        };
    }, [
        config.length
    ]);
    return useMemo(function() {
        return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({
            "data-drag-el": true
        }, attributes), {
            "data-be": 'chart',
            style: {
                flex: 1,
                minWidth: 0,
                width: '100%',
                maxWidth: '100%',
                margin: '1em 0',
                overflow: 'hidden'
            },
            ref: htmlRef,
            onDragStart: function(e) {
                return store.dragStart(e, markdownContainerRef.current);
            }
        }), /*#__PURE__*/ React.createElement(DragHandle, null), /*#__PURE__*/ React.createElement("div", {
            "data-chart-box": true,
            style: {
                display: 'flex',
                flexDirection: 'column',
                borderRadius: '0.5em'
            }
        }, /*#__PURE__*/ React.createElement(ErrorBoundary, {
            fallback: /*#__PURE__*/ React.createElement("table", null, /*#__PURE__*/ React.createElement("tbody", null, children))
        }, /*#__PURE__*/ React.createElement("div", {
            style: {
                position: 'relative'
            }
        }, /*#__PURE__*/ React.createElement("div", {
            style: {
                position: 'absolute',
                top: 0,
                left: 0,
                right: 0,
                bottom: 0,
                zIndex: 1,
                width: '100%',
                opacity: 0,
                height: '100%',
                overflow: 'hidden',
                pointerEvents: 'none'
            }
        }, children), /*#__PURE__*/ React.createElement("div", {
            style: {
                display: 'flex',
                flexWrap: 'wrap',
                flexDirection: minWidth < 400 ? 'column' : 'row',
                gap: 8,
                userSelect: 'none'
            },
            contentEditable: false,
            onClick: function(e) {
                e.stopPropagation();
            },
            onKeyDown: function(e) {
                e.stopPropagation();
            }
        }, config.map(function(_0, _1) {
            var _ref = [
                _0,
                _1
            ], _ref1 = _to_array(_ref), _ref2 = _ref1[0], _rest = _ref1.slice(1), chartType = _ref2.chartType, x = _ref2.x, y = _ref2.y, rest = _object_without_properties(_ref2, [
                "chartType",
                "x",
                "y"
            ]), _rest1 = _sliced_to_array(_rest, 1), index = _rest1[0];
            var _htmlRef_current;
            var height = Math.min(400, ((_htmlRef_current = htmlRef.current) === null || _htmlRef_current === void 0 ? void 0 : _htmlRef_current.clientWidth) || 400);
            if (typeof window === 'undefined' || typeof document === 'undefined') {
                return /*#__PURE__*/ React.createElement("div", {
                    key: index,
                    style: {
                        margin: 'auto',
                        position: 'relative',
                        zIndex: 9
                    }
                });
            }
            chartData = chartData.map(function(item) {
                var _obj;
                return _object_spread_props(_object_spread({}, item), (_obj = {}, _define_property(_obj, x, numberString(item[x])), _define_property(_obj, y, numberString(item[y])), _obj));
            }).sort(function(a, b) {
                if (dayjs(a[x]).isValid() && dayjs(b[x]).isValid()) {
                    return dayjs(a[x]).valueOf() - dayjs(b[x]).valueOf();
                }
                return 0;
            });
            var subgraphBy = rest === null || rest === void 0 ? void 0 : rest.subgraphBy;
            if (subgraphBy) {
                var groupData = groupByCategory(chartData, subgraphBy);
                return Object.keys(groupData).map(function(key, subIndex) {
                    var group = groupData[key];
                    if (!Array.isArray(group) || group.length < 1) {
                        return null;
                    }
                    var dom = /*#__PURE__*/ React.createElement(ChartRender, {
                        chartType: chartType,
                        chartData: group,
                        columnLength: columnLength,
                        onColumnLengthChange: setColumnLength,
                        isChartList: true,
                        config: {
                            height: height,
                            x: x,
                            y: y,
                            columns: columns,
                            index: index * 10 + subIndex,
                            rest: rest
                        },
                        title: key,
                        dataTime: rest === null || rest === void 0 ? void 0 : rest.dataTime,
                        groupBy: rest === null || rest === void 0 ? void 0 : rest.groupBy,
                        filterBy: rest === null || rest === void 0 ? void 0 : rest.filterBy,
                        colorLegend: rest === null || rest === void 0 ? void 0 : rest.colorLegend,
                        loading: isUnclosed
                    });
                    return dom;
                });
            }
            return /*#__PURE__*/ React.createElement(ChartRender, {
                key: index,
                columnLength: columnLength,
                onColumnLengthChange: setColumnLength,
                chartType: chartType,
                chartData: chartData,
                title: rest === null || rest === void 0 ? void 0 : rest.title,
                dataTime: rest === null || rest === void 0 ? void 0 : rest.dataTime,
                groupBy: rest === null || rest === void 0 ? void 0 : rest.groupBy,
                loading: isUnclosed,
                filterBy: rest === null || rest === void 0 ? void 0 : rest.filterBy,
                colorLegend: rest === null || rest === void 0 ? void 0 : rest.colorLegend,
                config: {
                    height: height,
                    x: x,
                    y: y,
                    columns: columns,
                    index: index,
                    rest: rest
                }
            });
        }).map(function(itemList, index) {
            if (Array.isArray(itemList)) {
                return itemList === null || itemList === void 0 ? void 0 : itemList.map(function(item, subIndex) {
                    if (!item) return null;
                    return /*#__PURE__*/ React.createElement("div", {
                        key: index + subIndex,
                        style: {
                            margin: 'auto',
                            minWidth: 0,
                            width: columnLength === 1 ? '100%' : "calc(".concat(100 / columnLength, "% - 8px)"),
                            maxWidth: '100%',
                            flex: 1,
                            userSelect: 'none'
                        },
                        contentEditable: false
                    }, item);
                });
            }
            return /*#__PURE__*/ React.createElement("div", {
                key: index,
                contentEditable: false,
                style: {
                    userSelect: 'none',
                    margin: 'auto',
                    minWidth: 0,
                    width: columnLength === 1 ? '100%' : "calc(".concat(100 / columnLength, "% - 8px)"),
                    maxWidth: '100%',
                    flex: 1
                },
                onClick: function(e) {
                    e.stopPropagation();
                }
            }, itemList);
        }))))));
    }, [
        attributes,
        // 使用更高效的依赖项比较
        dataSourceHash,
        (_node_otherProps5 = node.otherProps) === null || _node_otherProps5 === void 0 ? void 0 : _node_otherProps5.config,
        (_node_otherProps6 = node.otherProps) === null || _node_otherProps6 === void 0 ? void 0 : (_node_otherProps_columns = _node_otherProps6.columns) === null || _node_otherProps_columns === void 0 ? void 0 : _node_otherProps_columns.length,
        editor,
        columnLength,
        readonly,
        minWidth
    ]);
};
