"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const warning_1 = __importDefault(require("../compoments/warning"));
const useCursor = (options) => {
    const getSelection = (0, react_1.useCallback)(() => {
        if (typeof window === 'undefined') {
            return null;
        }
        return window.getSelection();
    }, []);
    const getRange = (0, react_1.useCallback)(() => {
        const selection = getSelection();
        if (!selection) {
            return { range: null, selection };
        }
        try {
            const range = selection.getRangeAt(0) || document.createRange();
            return { range, selection };
        }
        catch (_error) {
            // 当没有选中范围时创建新的 Range
            const range = document.createRange();
            return { range, selection };
        }
    }, [getSelection]);
    const setRange = (0, react_1.useCallback)((range, selection) => {
        if (!range || !selection) {
            return;
        }
        try {
            selection.removeAllRanges();
            selection.addRange(range);
        }
        catch (error) {
            (0, warning_1.default)(false, 'Sender', `Failed to set range: ${error}`);
        }
    }, []);
    const removeAllRanges = (0, react_1.useCallback)(() => {
        const selection = getSelection();
        if (!selection) {
            return;
        }
        try {
            selection.removeAllRanges();
        }
        catch (error) {
            (0, warning_1.default)(false, 'Sender', `Failed to remove all ranges: ${error}`);
        }
    }, [getSelection]);
    const focus = (0, react_1.useCallback)((targetNode, preventScroll = false) => {
        if (!targetNode || typeof targetNode.focus !== 'function') {
            return;
        }
        try {
            targetNode.focus({ preventScroll });
        }
        catch (error) {
            (0, warning_1.default)(false, 'Sender', `Failed to focus element: ${error}`);
        }
    }, []);
    const setEndCursor = (0, react_1.useCallback)((targetNode, preventScroll) => {
        if (!targetNode) {
            return;
        }
        focus(targetNode, preventScroll);
        const { range, selection } = getRange();
        if (range && selection) {
            try {
                range.selectNodeContents(targetNode);
                range.collapse(false);
                setRange(range, selection);
            }
            catch (error) {
                (0, warning_1.default)(false, 'Sender', `Failed to set end cursor: ${error}`);
            }
        }
    }, [focus, getRange, setRange]);
    const setStartCursor = (0, react_1.useCallback)((targetNode, preventScroll) => {
        if (!targetNode) {
            return;
        }
        focus(targetNode, preventScroll);
        const { range, selection } = getRange();
        if (range && selection) {
            try {
                range.selectNodeContents(targetNode);
                range.collapse(true);
                setRange(range, selection);
            }
            catch (error) {
                (0, warning_1.default)(false, 'Sender', `Failed to set start cursor: ${error}`);
            }
        }
    }, [focus, getRange, setRange]);
    const setAllSelectCursor = (0, react_1.useCallback)((targetNode, skillDom, preventScroll) => {
        if (!targetNode) {
            return;
        }
        focus(targetNode, preventScroll);
        const { range, selection } = getRange();
        if (range && selection) {
            try {
                range.selectNodeContents(targetNode);
                if (skillDom) {
                    range.setStart(targetNode, 1);
                }
                setRange(range, selection);
            }
            catch (error) {
                (0, warning_1.default)(false, 'Sender', `Failed to select all content: ${error}`);
            }
        }
    }, [focus, getRange, setRange]);
    const setCursorPosition = (0, react_1.useCallback)((targetNode, editableNode, position, preventScroll) => {
        if (!targetNode || typeof position !== 'number' || position < 0 || !editableNode) {
            return { range: null, selection: null };
        }
        focus(editableNode, preventScroll);
        const { range, selection } = getRange();
        if (range && selection) {
            try {
                const maxPosition = Math.min(position, targetNode.childNodes.length);
                range.setStart(targetNode, maxPosition);
                range.setEnd(targetNode, maxPosition);
                range.collapse(false);
                setRange(range, selection);
            }
            catch (error) {
                (0, warning_1.default)(false, 'Sender', `Failed to set cursor position:: ${error}`);
            }
        }
        return {
            range,
            selection,
        };
    }, [focus, getRange, setRange]);
    const setSlotFocus = (0, react_1.useCallback)((editableRef, key, preventScroll = false) => {
        if (!options || !(editableRef === null || editableRef === void 0 ? void 0 : editableRef.current))
            return;
        const { getSlotDom, slotConfigMap } = options;
        const getFocusableElement = (slotKey) => {
            var _a;
            const slotDom = getSlotDom(slotKey);
            if (!slotDom)
                return null;
            const slotConfig = slotConfigMap.get(slotKey);
            if (!slotConfig)
                return null;
            // 处理 input 类型的 slot
            if (slotConfig.type === 'input') {
                return slotDom.querySelector('input');
            }
            // 处理 content 类型的 slot（排除占位符节点）
            const nodeType = ((_a = slotDom === null || slotDom === void 0 ? void 0 : slotDom.getAttribute) === null || _a === void 0 ? void 0 : _a.call(slotDom, 'data-node-type')) || '';
            if (slotConfig.type === 'content' && nodeType !== 'nbsp') {
                return slotDom;
            }
            return null;
        };
        const findFocusableSlot = (targetKey) => {
            var _a;
            const editor = editableRef.current;
            if (!editor)
                return null;
            // 如果指定了 key，直接查找对应的 slot
            if (targetKey) {
                return getFocusableElement(targetKey);
            }
            // 否则查找第一个可聚焦的 slot
            for (const node of Array.from(editor.childNodes)) {
                const slotKey = (_a = node === null || node === void 0 ? void 0 : node.getAttribute) === null || _a === void 0 ? void 0 : _a.call(node, 'data-slot-key');
                if (slotKey) {
                    const focusableElement = getFocusableElement(slotKey);
                    if (focusableElement) {
                        return focusableElement;
                    }
                }
            }
            return null;
        };
        const targetElement = findFocusableSlot(key);
        if (!targetElement)
            return;
        if (targetElement.nodeName === 'INPUT') {
            targetElement.focus({ preventScroll });
        }
        else {
            setCursorPosition(targetElement, editableRef.current, 0, preventScroll);
        }
    }, [options, setCursorPosition]);
    const setAfterNodeFocus = (0, react_1.useCallback)((targetNode, editableNode, range, selection, preventScroll) => {
        if (!range || !selection)
            return;
        focus(editableNode, preventScroll);
        range === null || range === void 0 ? void 0 : range.setStartAfter(targetNode);
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
    }, [focus]);
    const getTextBeforeCursor = (0, react_1.useCallback)((targetNode) => {
        // 快速路径：空节点直接返回
        if (!targetNode) {
            return { value: '', startContainer: null, startOffset: 0 };
        }
        const selection = getSelection();
        if (!selection || selection.rangeCount === 0) {
            return { value: '', startContainer: null, startOffset: 0 };
        }
        try {
            const range = selection.getRangeAt(0);
            // 验证光标位置是否在目标节点内
            if (!targetNode.contains(range.startContainer)) {
                return { value: '', startContainer: null, startOffset: 0 };
            }
            const clone = range.cloneRange();
            clone.selectNodeContents(targetNode);
            clone.setEnd(range.startContainer, range.startOffset);
            // 清理并返回结果
            const value = clone.toString().replace(/\u200B/g, ''); // 移除零宽空格
            return {
                value,
                startContainer: range.startContainer,
                startOffset: range.startOffset,
            };
        }
        catch (error) {
            (0, warning_1.default)(false, 'Sender', `Failed to get text before cursor: ${error}`);
            return { value: '', startContainer: null, startOffset: 0 };
        }
    }, [getSelection]);
    /**
     * 获取插入位置信息
     * @param position - 插入位置类型：'cursor' | 'end' | 'start'
     * @returns 包含插入类型和对应 range 的对象
     */
    const getInsertPosition = (0, react_1.useCallback)((position, editableRef, lastSelectionRef) => {
        if (position === 'start' || position === 'end') {
            return { type: position, selection: getSelection() };
        }
        let range = null;
        let selection = null;
        if (lastSelectionRef === null || lastSelectionRef === void 0 ? void 0 : lastSelectionRef.current) {
            range = lastSelectionRef.current;
            selection = getSelection();
        }
        else {
            const rangeResult = getRange();
            range = rangeResult.range;
            selection = rangeResult.selection;
        }
        if (!range || !selection) {
            return { type: 'end', selection };
        }
        const editableDom = editableRef === null || editableRef === void 0 ? void 0 : editableRef.current;
        if (!editableDom) {
            return { type: 'end', selection };
        }
        const container = range.endContainer.nodeType === Node.TEXT_NODE
            ? range.endContainer.parentElement
            : range.endContainer;
        if (!container) {
            return { type: 'end', selection };
        }
        if (options === null || options === void 0 ? void 0 : options.getNodeInfo) {
            const { slotKey, slotConfig } = options.getNodeInfo(container) || {};
            if (slotKey) {
                return {
                    type: 'slot',
                    slotKey: slotConfig === null || slotConfig === void 0 ? void 0 : slotConfig.key,
                    slotType: slotConfig === null || slotConfig === void 0 ? void 0 : slotConfig.type,
                    range,
                    selection,
                };
            }
        }
        const isInEditableBox = editableDom.contains(range.endContainer);
        if (isInEditableBox) {
            return { type: 'box', range, selection };
        }
        return { type: 'end', selection };
    }, [options, getRange, getSelection]);
    /**
     * 获取末尾插入范围
     */
    const getEndRange = (0, react_1.useCallback)((editableDom) => {
        const lastNode = editableDom.childNodes[editableDom.childNodes.length - 1];
        const targetIndex = (lastNode === null || lastNode === void 0 ? void 0 : lastNode.nodeType) === Node.TEXT_NODE && lastNode.textContent === '\n'
            ? editableDom.childNodes.length - 1
            : editableDom.childNodes.length;
        const result = setCursorPosition(editableDom, editableDom, targetIndex);
        return result.range || document.createRange();
    }, [setCursorPosition]);
    /**
     * 获取开头插入范围
     */
    const getStartRange = (0, react_1.useCallback)((editableDom) => {
        var _a;
        const startIndex = ((_a = options === null || options === void 0 ? void 0 : options.getEditorValue) === null || _a === void 0 ? void 0 : _a.call(options).skill) ? 1 : 0;
        const result = setCursorPosition(editableDom, editableDom, startIndex);
        return result.range || document.createRange();
    }, [setCursorPosition, options]);
    const getCleanedText = (0, react_1.useCallback)((ori) => {
        return ori
            .replace(/\u200B/g, '') // 移除零宽空格
            .replace(/\n/g, '')
            .replace(/^\n+|\n+$/g, ''); // 移除开头和结尾的换行
    }, []);
    const copySelectionString = (0, react_1.useCallback)(async () => {
        try {
            const selection = getSelection();
            if (!selection) {
                return false;
            }
            const selectingString = selection.toString();
            if (!selectingString) {
                return false;
            }
            const cleanedText = getCleanedText(selectingString);
            await navigator.clipboard.writeText(cleanedText);
            return true;
        }
        catch (error) {
            (0, warning_1.default)(false, 'Sender', `Failed to copy selection: ${error}`);
            return false;
        }
    }, [getSelection, getCleanedText]);
    return {
        setEndCursor,
        setStartCursor,
        setAllSelectCursor,
        setCursorPosition,
        setAfterNodeFocus,
        setSlotFocus,
        getTextBeforeCursor,
        getSelection,
        removeAllRanges,
        getRange,
        getInsertPosition,
        getEndRange,
        getStartRange,
        copySelectionString,
        getCleanedText,
    };
};
exports.default = useCursor;
