import { RefObject } from 'react';
import { useMemoizedFn } from 'ahooks';

/**
 * 光标位置管理 Hook
 * 处理 contentEditable 元素中的光标位置获取和设置
 */
export function useCursorPosition(inputRef: RefObject<HTMLDivElement | null>) {
  /**
   * 获取光标位置对应的文本位置
   */
  const getCursorTextPosition = useMemoizedFn(() => {
    try {
      const selection = window.getSelection();
      if (!selection || selection.rangeCount === 0 || !inputRef.current) return 0;

      const range = selection.getRangeAt(0);

      // 检查选区是否在输入框内
      if (!inputRef.current.contains(range.commonAncestorContainer)) {
        return 0;
      }

      const preCaretRange = range.cloneRange();
      preCaretRange.selectNodeContents(inputRef.current);
      preCaretRange.setEnd(range.endContainer, range.endOffset);

      const tempDiv = document.createElement('div');
      tempDiv.appendChild(preCaretRange.cloneContents());

      // 处理提及元素
      const mentions = tempDiv.querySelectorAll('[data-mention]');
      mentions.forEach((mention) => {
        const value = mention.getAttribute('data-mention');
        const label = mention.textContent?.replace('@', '') || '';
        mention.textContent = `@{${value}|${label}}`;
      });

      return tempDiv.textContent?.length || 0;
    } catch (e) {
      console.warn('Failed to get cursor text position:', e);
      return 0;
    }
  });

  /**
   * 设置光标位置
   */
  const setCursorTextPosition = useMemoizedFn((position: number) => {
    if (!inputRef.current) return;

    try {
      const range = document.createRange();
      const selection = window.getSelection();
      if (!selection) return;

      let currentPos = 0;
      let targetNode: Node | null = null;
      let targetOffset = 0;

      const traverse = (node: Node): boolean => {
        if (node.nodeType === Node.TEXT_NODE) {
          const textLength = node.textContent?.length || 0;
          if (currentPos + textLength >= position) {
            targetNode = node;
            targetOffset = position - currentPos;
            return true;
          }
          currentPos += textLength;
        } else if (node.nodeType === Node.ELEMENT_NODE) {
          const element = node as HTMLElement;
          if (element.hasAttribute('data-mention')) {
            const mentionValue = element.getAttribute('data-mention') || '';
            const mentionLabel = element.textContent?.replace('@', '') || '';
            const mentionLength = `@{${mentionValue}|${mentionLabel}}`.length;
            if (currentPos + mentionLength >= position) {
              // 将光标放在提及标签之后
              targetNode = node.parentNode;
              if (targetNode && node.parentNode) {
                const siblings = Array.from(node.parentNode.childNodes);
                targetOffset = siblings.indexOf(node as ChildNode) + 1;
              }
              return true;
            }
            currentPos += mentionLength;
          } else {
            for (let i = 0; i < node.childNodes.length; i++) {
              if (traverse(node.childNodes[i])) return true;
            }
          }
        }
        return false;
      };

      traverse(inputRef.current);

      if (targetNode) {
        try {
          range.setStart(targetNode, targetOffset);
          range.collapse(true);
          selection.removeAllRanges();
          selection.addRange(range);
        } catch (e) {
          console.warn('Failed to set range:', e);
          // 如果设置失败，尝试将光标放在末尾
          try {
            range.selectNodeContents(inputRef.current);
            range.collapse(false);
            selection.removeAllRanges();
            selection.addRange(range);
          } catch (fallbackError) {
            console.error('Failed to set cursor position (fallback):', fallbackError);
          }
        }
      }
    } catch (e) {
      console.error('Failed to set cursor position:', e);
    }
  });

  return {
    getCursorTextPosition,
    setCursorTextPosition,
  };
}

