import TextExtractor from './textExtractor.js'
import FuzzySearchEngine from './fuzzySearchEngine.js'
import HighlightRenderer from './highlightRenderer.js'

class SearchCoordinator {
  constructor() {
    this.extractor = TextExtractor
    this.searchEngine = FuzzySearchEngine
    this.renderer = HighlightRenderer

    this.isSearching = false
    this.searchStats = {
      totalTime: 0,
      extractionTime: 0,
      searchTime: 0,
      renderTime: 0,
      resultCount: 0
    }

    console.log('🚀 SearchCoordinator: initialized with TextExtractor, FuzzySearchEngine, and HighlightRenderer')
  }

  async execute(params) {
    const { keyword, fileType, container, targetPage } = params || {}

    console.log('🚀 SearchCoordinator.execute: starting search process')

    try {
      const startTime = performance.now()

      if (!container) {
        console.error('❌ SearchCoordinator.execute: document container is required')
        return {
          success: false,
          message: '文档容器不存在'
        }
      }

      if (this.isSearching) {
        console.warn('⚠️ SearchCoordinator.execute: previous search still running, clearing highlights')
        this.renderer.clearAll()
      }

      this.isSearching = true
      this.resetStats()
      console.log('🔒 SearchCoordinator.execute: search lock acquired')

      const extractionStart = performance.now()
      let documents = await this.withRetry(
        () => this.extractor.extract(fileType, container),
        3,
        200
      )
      const extractionEnd = performance.now()
      this.searchStats.extractionTime = extractionEnd - extractionStart

      if (!documents || documents.length === 0) {
        console.error('❌ SearchCoordinator.execute: failed to extract document content')
        return {
          success: false,
          message: '无法提取文档内容',
          stats: this.getFormattedStats()
        }
      }

      console.log(`📄 SearchCoordinator.execute: extracted ${documents.length} text segments in ${this.searchStats.extractionTime.toFixed(2)}ms`)

      let filteredDocuments = documents

      if (targetPage && targetPage > 1) {
        console.log(`📄 SearchCoordinator.execute: filtering to page ${targetPage}`)
        filteredDocuments = documents.filter(doc =>
          doc.location?.page === targetPage ||
          doc.page === targetPage
        )

        if (filteredDocuments.length === 0) {
          console.warn('⚠️ SearchCoordinator.execute: no content on target page, using all pages')
          filteredDocuments = documents
        } else {
          console.log(`📄 SearchCoordinator.execute: found ${filteredDocuments.length} segments on page ${targetPage}`)
        }
      }

      const initSuccess = this.searchEngine.initIndex(filteredDocuments)
      if (!initSuccess) {
        console.error('❌ SearchCoordinator.execute: failed to initialize search index')
        return {
          success: false,
          message: '搜索引擎初始化失败',
          stats: this.getFormattedStats()
        }
      }

      const searchStart = performance.now()
      let results = this.searchEngine.search(keyword, { limit: 30 })
      const searchEnd = performance.now()
      this.searchStats.searchTime = searchEnd - searchStart

      if (!results || results.length === 0) {
        console.log(`⚠️ SearchCoordinator: 未找到匹配内容 "${keyword.substring(0, 30)}${keyword.length > 30 ? '...' : ''}"`)
        return {
          success: false,
          message: `未找到"${keyword}"相关内容`,
          stats: this.getFormattedStats()
        }
      }

      console.log(`🔍 SearchCoordinator.execute: found ${results.length} matches in ${this.searchStats.searchTime.toFixed(2)}ms`)

      if (results.length > 0) {
        const top3 = results.slice(0, 3)
        top3.forEach((result, idx) => {
          const score = result.score !== undefined ? result.score.toFixed(4) : 'N/A'
          const preview = result.matchedText?.substring(0, 50) || result.text?.substring(0, 50) || 'N/A'
          console.log(`   Top ${idx + 1}: Score=${score} | Preview="${preview}..."`)
        })
      }

      const renderStart = performance.now()
      const renderCount = this.renderer.renderAll(results)
      const renderEnd = performance.now()
      this.searchStats.renderTime = renderEnd - renderStart
      this.searchStats.resultCount = renderCount

      console.log(`✨ SearchCoordinator.execute: rendered ${renderCount} highlights in ${this.searchStats.renderTime.toFixed(2)}ms`)

      const endTime = performance.now()
      this.searchStats.totalTime = endTime - startTime

      const formattedStats = this.getFormattedStats()

      console.log(`✅ SearchCoordinator.execute: completed successfully`)
      console.log(`   📊 Total Time: ${formattedStats.totalTimeFormatted}`)
      console.log(`   📄 Extraction: ${formattedStats.extractionFormatted}`)
      console.log(`   🔍 Search: ${formattedStats.searchFormatted}`)
      console.log(`   ✨ Render: ${formattedStats.renderFormatted}`)
      console.log(`   🎯 Results: ${renderCount}`)

      return {
        success: true,
        resultCount: renderCount,
        stats: formattedStats
      }

    } catch (error) {
      console.error('❌ SearchCoordinator.execute: fatal error during execution', error)
      return {
        success: false,
        message: error.message || '搜索过程中发生未知错误',
        stats: this.getFormattedStats()
      }
    } finally {
      this.isSearching = false
      console.log('🔓 SearchCoordinator.execute: search lock released')
    }
  }

  async withRetry(fn, maxRetries, delayMs) {
    let lastError

    for (let i = 0; i < maxRetries; i++) {
      try {
        const result = await fn()
        return result
      } catch (error) {
        lastError = error
        console.warn(`⚠️ SearchCoordinator.withRetry: attempt ${i + 1}/${maxRetries} failed - ${error.message?.substring(0, 100)}`)

        if (i < maxRetries - 1) {
          await new Promise(resolve => setTimeout(resolve, delayMs))
        }
      }
    }

    throw lastError
  }

  nextHighlight() {
    return this.renderer.next()
  }

  prevHighlight() {
    return this.renderer.prev()
  }

  clearAllHighlights() {
    return this.renderer.clearAll()
  }

  get currentStats() {
    return { ...this.searchStats }
  }

  get isCurrentlySearching() {
    return this.isSearching
  }

  resetStats() {
    this.searchStats = {
      totalTime: 0,
      extractionTime: 0,
      searchTime: 0,
      renderTime: 0,
      resultCount: 0
    }
  }

  getFormattedStats() {
    return {
      ...this.searchStats,
      totalTimeFormatted: `${(this.searchStats.totalTime / 1000).toFixed(2)}s`,
      extractionFormatted: `${(this.searchStats.extractionTime / 1000).toFixed(0)}ms`,
      searchFormatted: `${(this.searchStats.searchTime / 1000).toFixed(0)}ms`,
      renderFormatted: `${(this.searchStats.renderTime / 1000).toFixed(0)}ms`
    }
  }

  getSearchEngineStats() {
    return this.searchEngine.getStats()
  }

  clearSearchIndex() {
    return this.searchEngine.clear()
  }

  isReady() {
    return this.searchEngine.isReady()
  }
}

export default new SearchCoordinator()
