/**
 * @file 有道词典实现
 * @description 有道词典的实现，通过 HTTP 请求获取数据
 */

import { DictionaryBase, createResult, createMeaning, createExample } from './base.js';

/**
 * 有道词典实现
 */
export class YoudaoDictionary extends DictionaryBase {
  constructor(config = {}) {
    super({
      name: '有道词典',
      icon: 'icons/youdao.png',
      languages: ['en', 'zh'],
      ...config
    });
  }

  /**
   * 查询单词
   * @param {string} word - 要查询的单词
   * @returns {Promise<DictionaryResult>} 查询结果
   */
  async search(word) {
    if (!word?.trim()) {
      throw new Error('查询单词不能为空');
    }

    const trimmedWord = word.trim();
    const url = `https://dict.youdao.com/result?word=${encodeURIComponent(trimmedWord)}&lang=en`;

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
          'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8'
        }
      });
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const html = await response.text();
      
      // 使用正则提取数据
      return this._parseHtml(html, trimmedWord, url);
    } catch (error) {
      console.error('[YoudaoDictionary] Search failed:', error);
      
      return createResult({
        word: trimmedWord,
        phonetic: '',
        meanings: [createMeaning('提示', ['查询失败，请检查网络连接'])],
        examples: [],
        url
      });
    }
  }

  /**
   * 解析有道词典 HTML（使用正则）
   * @private
   * @param {string} html - HTML 内容
   * @param {string} word - 查询的单词
   * @param {string} url - 查询 URL
   * @returns {DictionaryResult} 解析结果
   */
  _parseHtml(html, word, url) {
    return createResult({
      word,
      phonetic: this._extractPhonetic(html),
      meanings: this._extractMeanings(html),
      examples: this._extractExamples(html),
      url
    });
  }

  /**
   * 提取音标
   * @private
   * @param {string} html - HTML 内容
   * @returns {string} 音标
   */
  _extractPhonetic(html) {
    // 匹配音标格式
    const match = html.match(/\[[\u0250-\u02AEˈˌa-zA-Z]+\]/);
    if (match) {
      return match[0];
    }
    
    const match2 = html.match(/\/[\u0250-\u02AEˈˌa-zA-Z]+\//);
    if (match2) {
      return match2[0];
    }

    return '';
  }

  /**
   * 提取释义
   * @private
   * @param {string} html - HTML 内容
   * @returns {Array<Meaning>} 释义列表
   */
  _extractMeanings(html) {
    const meanings = [];
    
    // 尝试匹配常见的词典释义格式
    const posDefPattern = /<[^>]*class="[^"]*(?:pos|trans)[^"]*"[^>]*>([^<]+)<\/[^>]*>\s*<[^>]*class="[^"]*(?:def|chn)[^"]*"[^>]*>([^<]+)/gi;
    
    let match;
    while ((match = posDefPattern.exec(html)) !== null) {
      const partOfSpeech = match[1].trim();
      const definition = match[2].trim();
      if (partOfSpeech && definition) {
        meanings.push(createMeaning(partOfSpeech, [definition]));
      }
    }

    // 备选：直接匹配 "词性. 释义" 格式
    if (meanings.length === 0) {
      const simplePattern = /([a-z]+\.?)\s*([^<\n]{2,30})/gi;
      const seen = new Set();
      
      while ((match = simplePattern.exec(html)) !== null) {
        const partOfSpeech = match[1].trim();
        const definition = match[2].trim();
        
        if (!partOfSpeech.match(/^[a-z]+\.?$/i)) continue;
        if (definition.length < 2 || definition.length > 30) continue;
        if (seen.has(definition)) continue;
        
        seen.add(definition);
        meanings.push(createMeaning(partOfSpeech, [definition]));
        
        if (meanings.length >= 5) break;
      }
    }

    return meanings.length > 0 ? meanings : [createMeaning('n.', ['暂无释义'])];
  }

  /**
   * 提取例句
   * @private
   * @param {string} html - HTML 内容
   * @returns {Array<Example>} 例句列表
   */
  _extractExamples(html) {
    const examples = [];
    
    // 匹配例句模式
    const sentencePattern = /<[^>]*>([^<]{10,100}[a-zA-Z][^<]{0,50})<\/[^>]*>\s*<[^>]*>([^<]{5,50}[\u4e00-\u9fa5][^<]{0,50})<\/[^>]*>/gi;
    
    let match;
    const seen = new Set();
    
    while ((match = sentencePattern.exec(html)) !== null) {
      const sentence = match[1].trim();
      const translation = match[2].trim();
      
      if (seen.has(sentence)) continue;
      seen.add(sentence);
      
      if (sentence.length > 10 && sentence.length < 150 && sentence.includes(' ')) {
        examples.push(createExample(sentence, translation));
      }
      
      if (examples.length >= 2) break;
    }

    return examples;
  }
}

// 导出单例实例
export const youdaoDictionary = new YoudaoDictionary();
