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 _array_without_holes(arr) {
    if (Array.isArray(arr)) return _array_like_to_array(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 _non_iterable_spread() {
    throw new TypeError("Invalid attempt to spread 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 _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_consumable_array(arr) {
    return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
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 { Editor, Element, Node, Path } from "slate";
import { EditorUtils } from "../utils/editorUtils";
// 预编译正则表达式，避免重复创建
var HTML_REG = /<[a-z]+[\s"'=:;()\w\-[\]/.]*\/?>(.*<\/[a-z]+>:?)?/g;
var LINK_REG = /(https?|ftp):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/gi;
var FOOTNOTE_REG = /\[\^[^\]]+\]/g;
var TABLE_ROW_REG = /^\|([^|]+\|)+$/;
/** 至少一个非 } 字符，避免匹配 {{}}、{{ 等不完整表达式 */ var JINJA_VARIABLE_REG = /\{\{[^}]+\}\}/g;
/** 至少一个非 % 字符，避免匹配 {%%} */ var JINJA_TAG_REG = /\{%[^%]+%\}/g;
/** 单行内注释，避免跨多行高亮造成大段误匹配（编辑器场景） */ var JINJA_COMMENT_REG = /\{#[^\n]*?#\}/g;
export var cacheTextNode = new WeakMap();
export var clearInlineKatex = function clearInlineKatex(editor) {
    var inlineMath = Array.from(Editor.nodes(editor, {
        match: function match(n) {
            return n.type === 'inline-katex';
        },
        at: []
    }));
    inlineMath.forEach(function(c) {
        return cacheTextNode.delete(c[0]);
    });
};
var PARAGRAPH_TYPES = new Set([
    'paragraph',
    'table-cell',
    'head'
]);
var highlightNodes = new Set([
    'paragraph',
    'table-cell',
    'table',
    'code',
    'head',
    'inline-katex'
]);
// 创建 range 对象的工厂函数，复用 path 数组
var createRange = function createRange(path, childIndex, offset, length) {
    var props = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : {};
    var childPath = path.concat(childIndex);
    return _object_spread({
        anchor: {
            path: childPath,
            offset: offset
        },
        focus: {
            path: childPath,
            offset: offset + length
        }
    }, props);
};
/** 创建可跨子节点的 range（用于 Jinja 等可能被 inline code 分割的匹配） */ var createRangeSpanningChildren = function createRangeSpanningChildren(path, children, globalStart, globalEnd) {
    var props = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : {};
    var offset = 0;
    var anchorPath = null;
    var anchorOffset = 0;
    var focusPath = null;
    var focusOffset = 0;
    for(var i = 0; i < children.length; i++){
        var _ref;
        var _children_i;
        var text = (_ref = (_children_i = children[i]) === null || _children_i === void 0 ? void 0 : _children_i.text) !== null && _ref !== void 0 ? _ref : '';
        var len = text.length;
        var childStart = offset;
        var childEnd = offset + len;
        if (globalStart < childEnd && anchorPath === null) {
            anchorPath = path.concat(i);
            anchorOffset = Math.max(0, globalStart - childStart);
        }
        if (globalEnd <= childEnd && focusPath === null) {
            focusPath = path.concat(i);
            focusOffset = Math.min(len, globalEnd - childStart);
            break;
        }
        offset = childEnd;
    }
    if (anchorPath && focusPath) {
        return _object_spread({
            anchor: {
                path: anchorPath,
                offset: anchorOffset
            },
            focus: {
                path: focusPath,
                offset: focusOffset
            }
        }, props);
    }
    return null;
};
// 处理文本节点的匹配逻辑
var processTextMatches = function processTextMatches(text, path, childIndex) {
    var ranges = [];
    // 匹配 footnote reference
    var match;
    FOOTNOTE_REG.lastIndex = 0;
    while((match = FOOTNOTE_REG.exec(text)) !== null){
        var index = match.index;
        if (typeof index === 'number') {
            ranges.push(createRange(path, childIndex, index, match[0].length, {
                fnc: true,
                fnd: false
            }));
        }
    }
    // 匹配 HTML
    HTML_REG.lastIndex = 0;
    while((match = HTML_REG.exec(text)) !== null){
        var index1 = match.index;
        if (typeof index1 === 'number') {
            ranges.push(createRange(path, childIndex, index1, match[0].length, {
                html: true
            }));
        }
    }
    return ranges;
};
// 处理链接匹配
var processLinkMatches = function processLinkMatches(text, path, childIndex) {
    var ranges = [];
    var match;
    LINK_REG.lastIndex = 0;
    while((match = LINK_REG.exec(text)) !== null){
        var index = match.index;
        if (typeof index === 'number') {
            ranges.push(createRange(path, childIndex, index, match[0].length, {
                link: match[0]
            }));
        }
    }
    return ranges;
};
/** 在整段文本上匹配 Jinja，支持被 inline code 分割的语法（如 {% if `x` %}） */ var processJinjaMatchesOnFullText = function processJinjaMatchesOnFullText(fullText, path, children) {
    var ranges = [];
    var collect = function collect(reg, prop) {
        reg.lastIndex = 0;
        var match;
        while((match = reg.exec(fullText)) !== null){
            var start = match.index;
            var matched = match[0];
            if (typeof start !== 'number' || !matched) continue;
            var end = start + matched.length;
            var range = createRangeSpanningChildren(path, children, start, end, _define_property({}, prop, true));
            if (range) ranges.push(range);
        }
    };
    collect(JINJA_VARIABLE_REG, 'jinjaVariable');
    collect(JINJA_TAG_REG, 'jinjaTag');
    collect(JINJA_COMMENT_REG, 'jinjaComment');
    return ranges;
};
export function useHighlight(store, jinjaEnabled) {
    return function(param) {
        var _param = _sliced_to_array(param, 2), node = _param[0], path = _param[1];
        // 快速路径：非元素节点或不在高亮节点列表中
        if (!Element.isElement(node) || !highlightNodes.has(node.type)) {
            return [];
        }
        var ranges = (store === null || store === void 0 ? void 0 : store.highlightCache.get(node)) || [];
        var cacheText = cacheTextNode.get(node);
        var isCached = cacheText && Path.equals(cacheText.path, path);
        // 处理 paragraph 和 table-cell
        if (PARAGRAPH_TYPES.has(node.type)) {
            if (isCached) {
                var _ranges;
                (_ranges = ranges).push.apply(_ranges, _to_consumable_array(cacheText.range));
            } else {
                var _ranges1;
                var allTextRanges = [];
                var children = node.children;
                var childrenLength = children.length;
                var fullText = Node.string(node);
                for(var i = 0; i < childrenLength; i++){
                    var child = children[i];
                    // 处理 footnote 和 HTML
                    if (child.text && !EditorUtils.isDirtLeaf(child)) {
                        var _allTextRanges;
                        (_allTextRanges = allTextRanges).push.apply(_allTextRanges, _to_consumable_array(processTextMatches(child.text, path, i)));
                    }
                    // 处理链接
                    if (child.text && !child.url && !child.docId && !child.hash) {
                        var _allTextRanges1;
                        (_allTextRanges1 = allTextRanges).push.apply(_allTextRanges1, _to_consumable_array(processLinkMatches(child.text, path, i)));
                    }
                }
                // Jinja 在整段文本上匹配，支持 {% if `x` %} 等被 inline code 分割的语法
                if (jinjaEnabled && fullText) {
                    var _allTextRanges2;
                    (_allTextRanges2 = allTextRanges).push.apply(_allTextRanges2, _to_consumable_array(processJinjaMatchesOnFullText(fullText, path, children)));
                }
                // 统一缓存
                cacheTextNode.set(node, {
                    path: path,
                    range: allTextRanges
                });
                (_ranges1 = ranges).push.apply(_ranges1, _to_consumable_array(allTextRanges));
            }
        }
        // 处理特殊段落（代码块或表格行）
        if (node.type === 'paragraph' && node.children.length === 1 && !EditorUtils.isDirtLeaf(node.children[0])) {
            if (isCached) {
                var _ranges2;
                (_ranges2 = ranges).push.apply(_ranges2, _to_consumable_array(cacheText.range));
            } else {
                var str = Node.string(node);
                var strLength = str.length;
                if (str.startsWith('```')) {
                    var range = createRange(path, 0, 0, 3, {
                        color: '#a3a3a3'
                    });
                    ranges.push(range);
                    cacheTextNode.set(node, {
                        path: path,
                        range: [
                            range
                        ]
                    });
                } else if (TABLE_ROW_REG.test(str)) {
                    var range1 = createRange(path, 0, 0, strLength, {
                        color: '#a3a3a3'
                    });
                    ranges.push(range1);
                    cacheTextNode.set(node, {
                        path: path,
                        range: [
                            range1
                        ]
                    });
                }
            }
        }
        return ranges;
    };
}
