import { useState, RefObject } from 'react';
import { useMemoizedFn } from 'ahooks';
import { MentionOption, PopoverPosition } from './types';
import { extractTextFromHTML, shouldShowMentionPopover, filterOptions } from './utils';
import { calculatePopoverPosition } from './usePopoverPosition';

interface UseMentionInputProps {
  value: string;
  options: MentionOption[];
  onChange?: (value: string) => void;
  onEnter?: (value: string) => void;
  popoverPlacement: 'auto' | 'top' | 'bottom';
  inputRef: RefObject<HTMLDivElement | null>;
  isComposingRef: RefObject<boolean>;
  getCursorTextPosition: () => number;
  setCursorTextPosition: (position: number) => void;
}

/**
 * 提及输入核心逻辑 Hook
 * 处理输入、提及插入、键盘事件等
 */
export function useMentionInput({
  value,
  options,
  onChange,
  onEnter,
  popoverPlacement,
  inputRef,
  isComposingRef,
  getCursorTextPosition,
  setCursorTextPosition,
}: UseMentionInputProps) {
  const [showPopover, setShowPopover] = useState(false);
  const [filteredOptions, setFilteredOptions] = useState<MentionOption[]>([]);
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [cursorPosition, setCursorPosition] = useState(0);
  const [popoverPosition, setPopoverPosition] = useState<PopoverPosition>({
    top: 0,
    left: 0,
    placement: 'bottom',
  });

  /**
   * 处理输入事件
   */
  const handleInput = useMemoizedFn(() => {
    if (!inputRef.current || isComposingRef.current) return;

    try {
      const position = getCursorTextPosition();
      setCursorPosition(position);

      // 获取纯文本内容
      const text = extractTextFromHTML(inputRef.current);

      // 检查是否触发提及
      const beforeCursor = text.slice(0, position);
      const lastAtIndex = beforeCursor.lastIndexOf('@');

      if (lastAtIndex !== -1) {
        const afterAt = beforeCursor.slice(lastAtIndex + 1);

        if (shouldShowMentionPopover(afterAt)) {
          const filtered = filterOptions(options, afterAt);
          setFilteredOptions(filtered);
          setShowPopover(filtered.length > 0);
          setSelectedIndex(0);

          // 计算弹窗位置
          try {
            const selection = window.getSelection();
            if (selection && selection.rangeCount > 0) {
              const range = selection.getRangeAt(0);
              const rect = range.getBoundingClientRect();
              const inputRect = inputRef.current.getBoundingClientRect();

              const newPosition = calculatePopoverPosition(rect, inputRect, popoverPlacement);
              setPopoverPosition(newPosition);
            }
          } catch (e) {
            console.warn('Failed to calculate popover position:', e);
          }
        } else {
          setShowPopover(false);
        }
      } else {
        setShowPopover(false);
      }

      onChange?.(text);
    } catch (e) {
      console.error('Error in handleInput:', e);
    }
  });

  /**
   * 插入提及
   */
  const insertMention = useMemoizedFn((option: MentionOption) => {
    if (!inputRef.current) return;

    const text = value;
    const position = cursorPosition;

    // 找到 @ 的位置
    const beforeCursor = text.slice(0, position);
    const lastAtIndex = beforeCursor.lastIndexOf('@');

    if (lastAtIndex !== -1) {
      const before = text.slice(0, lastAtIndex);
      const after = text.slice(position);
      const newValue = `${before}@{${option.value}|${option.label}}${after}`;

      onChange?.(newValue);

      // 更新显示并设置光标
      setTimeout(() => {
        const newPosition = before.length + `@{${option.value}|${option.label}}`.length;
        setCursorTextPosition(newPosition);
        inputRef.current?.focus();
      }, 0);
    }

    setShowPopover(false);
  });

  /**
   * 键盘事件处理
   */
  const handleKeyDown = useMemoizedFn((e: React.KeyboardEvent<HTMLDivElement>) => {
    // 处理弹出菜单显示时的键盘操作
    if (showPopover) {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        setSelectedIndex((prev) => (prev < filteredOptions.length - 1 ? prev + 1 : prev));
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        setSelectedIndex((prev) => (prev > 0 ? prev - 1 : prev));
      } else if (e.key === 'Enter') {
        e.preventDefault();
        if (filteredOptions[selectedIndex]) {
          insertMention(filteredOptions[selectedIndex]);
        }
      } else if (e.key === 'Escape') {
        e.preventDefault();
        setShowPopover(false);
      }
      return;
    }

    // 处理弹出菜单不显示时的键盘操作
    if (e.key === 'Enter' && !e.shiftKey) {
      // Enter 发送，Shift + Enter 换行
      e.preventDefault();
      onEnter?.(value);
    }
  });

  return {
    showPopover,
    filteredOptions,
    selectedIndex,
    setSelectedIndex,
    popoverPosition,
    setPopoverPosition,
    handleInput,
    insertMention,
    handleKeyDown,
  };
}

