/**
 * @file 文本选择检测
 * @description 监听网页文本选择事件
 */

import { logger } from './logger.js';
import { createSaladIcon } from './components/SaladIcon.js';
import { DictPanel } from './components/DictPanel.js';
import { ConfigManager, isSelectionEnabled } from '../shared/config.js';
import { messaging } from '../shared/messaging.js';

let currentIcon = null;
let currentPanel = null;

/**
 * 获取当前选中的文本
 * @returns {string} 选中的文本
 */
export function getSelectedText() {
  const selection = window.getSelection();
  return selection ? selection.toString().trim() : '';
}

/**
 * 获取选中文本的坐标信息
 * @returns {Object|null} {x, y, width, height, left, top, right, bottom} 或 null
 */
export function getSelectionCoords() {
  const selection = window.getSelection();
  
  if (!selection || selection.rangeCount === 0) {
    return null;
  }

  const range = selection.getRangeAt(0);
  const rects = range.getClientRects();
  
  if (rects.length === 0) {
    return null;
  }

  // 获取第一个矩形（单行）或整个选区的矩形（多行取首行）
  const firstRect = rects[0];
  
  // 计算整个选区的包围矩形
  let minX = firstRect.left;
  let minY = firstRect.top;
  let maxX = firstRect.right;
  let maxY = firstRect.bottom;

  for (const rect of rects) {
    minX = Math.min(minX, rect.left);
    minY = Math.min(minY, rect.top);
    maxX = Math.max(maxX, rect.right);
    maxY = Math.max(maxY, rect.bottom);
  }

  return {
    // 首行位置（用于图标定位）
    x: firstRect.left,
    y: firstRect.top,
    width: firstRect.width,
    height: firstRect.height,
    left: firstRect.left,
    top: firstRect.top,
    right: firstRect.right,
    bottom: firstRect.bottom,
    // 整个选区的包围矩形
    boundingX: minX,
    boundingY: minY,
    boundingWidth: maxX - minX,
    boundingHeight: maxY - minY
  };
}

/**
 * 检查是否有有效文本被选中
 * @returns {boolean}
 */
export function hasSelection() {
  const text = getSelectedText();
  return text.length > 0;
}

/**
 * 处理鼠标抬起事件
 * @param {MouseEvent} event
 */
function handleMouseUp(event) {
  // 如果点击的是当前图标元素，则直接返回
  if (currentIcon && (currentIcon.element == event.target || currentIcon.element.contains(event.target))) {
    return;
  }

  // 如果点击的是当前面板元素，则直接返回
  if (currentPanel && (currentPanel.element == event.target || currentPanel.element.contains(event.target))) {
    return;
  }
  
  // 延迟执行，等待选区完成
  setTimeout(async () => {
    // 检查划词功能是否启用
    const enabled = await isSelectionEnabled();
    if (!enabled) {
      logger.info('Selection is disabled, skipping icon display');
      return;
    }
    
    const selectedText = getSelectedText();
    
    if (selectedText.length > 0) {
      const coords = getSelectionCoords();
      
      logger.info('Text selected:', selectedText);
      console.log('[SaladDict] Selected text:', selectedText);
      
      if (coords) {
        console.log('[SaladDict] Selection coords:', {
          x: coords.x,
          y: coords.y,
          width: coords.width,
          height: coords.height
        });
        
        // 显示沙拉图标在选中文本右上角
        showSaladIcon(coords.x + coords.width, coords.y);
      }
    }
  }, 10);
}

/**
 * 显示沙拉图标
 * @param {number} x - X坐标
 * @param {number} y - Y坐标
 */
function showSaladIcon(x, y) {
  // 隐藏旧图标和面板
  if (currentIcon) {
    currentIcon.destroy();
    currentIcon = null;
  }
  if (currentPanel) {
    currentPanel.destroy();
    currentPanel = null;
  }
  
  // 创建新图标，传入点击回调
  currentIcon = createSaladIcon(x, y, {
    onClick: async (event) => {
      logger.info('Icon clicked, showing panel');
      
      // 获取选中的文本
      const selectedText = getSelectedText();
      
      // 图标消失
      if (currentIcon) {
        currentIcon.destroy();
        currentIcon = null;
      }
      
      // 显示面板在图标右下方
      const panelX = x + 24; // 图标宽度
      const panelY = y + 24; // 图标高度
      currentPanel = new DictPanel();
      currentPanel.show(panelX, panelY);
      console.log('[SaladDict] Panel shown at:', panelX, panelY);
      
      // 执行词典查询
      if (selectedText) {
        // 先显示 loading
        currentPanel.showLoading();
        
        // 设置超时处理
        const timeoutMs = 5000;
        const timeoutPromise = new Promise((_, reject) => {
          setTimeout(() => reject(new Error('TIMEOUT')), timeoutMs);
        });
        
        try {
          console.log('[SaladDict] Searching for:', selectedText);
          
          // 竞速：查询 vs 超时
          const response = await Promise.race([
            messaging.sendToBackground('DICT.SEARCH', { word: selectedText }),
            timeoutPromise
          ]);
          
          console.log('[SaladDict] Search response:', response);
          
          // 显示查询结果
          if (response?.results && response.results.length > 0) {
            // 显示所有词典结果
            currentPanel.renderMultipleResults(response.results);
            logger.info('Search results rendered:', response.results.length, 'dictionaries');
          } else {
            currentPanel.renderResult({
              word: selectedText,
              phonetic: '',
              meanings: [{ partOfSpeech: 'n.', definitions: ['暂无释义'] }],
              examples: []
            });
            logger.warn('No search results for:', selectedText);
          }
        } catch (error) {
          console.error('[SaladDict] Search failed:', error);
          
          if (error.message === 'TIMEOUT') {
            currentPanel.showTimeout();
            logger.warn('Search timeout for:', selectedText);
          } else {
            currentPanel.renderResult({
              word: selectedText,
              phonetic: '',
              meanings: [{ partOfSpeech: 'n.', definitions: ['查询失败，请重试'] }],
              examples: []
            });
          }
        }
      }
    }
  });
  
  console.log('[SaladDict] Icon shown at:', x, y);
}

/**
 * 处理页面点击事件（用于隐藏图标和面板）
 * @param {MouseEvent} event
 */
function handleDocumentClick(event) {
  // 如果点击的不是图标元素，则隐藏图标
  if (currentIcon && currentIcon.element !== event.target && !currentIcon.element.contains(event.target)) {
    currentIcon.destroy();
    currentIcon = null;
    logger.info('Icon hidden by document click');
  }
  
  // 如果点击的不是面板元素，则隐藏面板
  if (currentPanel && currentPanel.element !== event.target && !currentPanel.element.contains(event.target)) {
    currentPanel.destroy();
    currentPanel = null;
    logger.info('Panel hidden by document click');
  }
}

/**
 * 处理键盘事件
 * @param {KeyboardEvent} event
 */
function handleKeyDown(event) {
  // ESC 键关闭面板
  if (event.key === 'Escape' && currentPanel) {
    currentPanel.destroy();
    currentPanel = null;
    logger.info('Panel hidden by ESC key');
  }
}

let unbindConfigListener = null;

/**
 * 处理配置变更
 * @param {Object} newConfig
 */
function handleConfigChange(newConfig) {
  const enabled = newConfig?.general?.enableSelection ?? true;
  
  logger.info('Config changed, selection enabled:', enabled);
  
  // 如果禁用划词，隐藏当前图标和面板
  if (!enabled) {
    if (currentIcon) {
      currentIcon.destroy();
      currentIcon = null;
    }
    if (currentPanel) {
      currentPanel.destroy();
      currentPanel = null;
    }
  }
}

/**
 * 初始化文本选择监听
 */
export function initSelectionListener() {
  logger.info('Initializing selection listener');
  
  document.addEventListener('mouseup', handleMouseUp);
  document.addEventListener('keydown', handleKeyDown);
  
  // 延迟添加点击监听，避免与 mouseup 冲突
  setTimeout(() => {
    document.addEventListener('click', handleDocumentClick);
  }, 100);
  
  // 监听配置变更
  unbindConfigListener = ConfigManager.onChange(handleConfigChange);
  
  logger.info('Selection listener initialized');
}

/**
 * 销毁文本选择监听
 */
export function destroySelectionListener() {
  document.removeEventListener('mouseup', handleMouseUp);
  document.removeEventListener('click', handleDocumentClick);
  document.removeEventListener('keydown', handleKeyDown);
  
  // 取消配置监听
  if (unbindConfigListener) {
    unbindConfigListener();
    unbindConfigListener = null;
  }
  
  logger.info('Selection listener destroyed');
}
