/**
 * Search functionality
 */
export class SearchManager {
  constructor(debounceMs = 300) {
    this.searchTimeout = null;
    this.SEARCH_DEBOUNCE_MS = debounceMs;
    this.init();
  }

  /**
   * Initialize search functionality with debouncing
   */
  init() {
    const searchBox = document.getElementById('searchBox');
    const searchResults = document.getElementById('searchResults');
    
    if (!searchBox || !searchResults) return;
    
    searchBox.addEventListener('input', (e) => {
      clearTimeout(this.searchTimeout);
      const query = e.target.value.trim();
      
      if (query.length === 0) {
        searchResults.style.display = 'none';
        return;
      }
      
      this.searchTimeout = setTimeout(() => {
        this.performSearch(query);
      }, this.SEARCH_DEBOUNCE_MS);
    });
    
    document.addEventListener('click', (e) => {
      if (!searchBox.contains(e.target) && !searchResults.contains(e.target)) {
        searchResults.style.display = 'none';
      }
    });
  }

  /**
   * Perform search across plot names
   */
  async performSearch(query) {
    const searchResults = document.getElementById('searchResults');
    if (!searchResults) return;
    
    searchResults.innerHTML = '<div style="padding: 1rem;">🔍 Searching...</div>';
    searchResults.style.display = 'block';
    
    try {
      const results = await this.searchPlots(query);
      this.displaySearchResults(results, query);
    } catch (error) {
      console.error('Search error:', error);
      searchResults.innerHTML = '<div style="padding: 1rem; color: red;">❌ Search failed</div>';
    }
  }

  /**
   * Search for plots matching the query
   */
  async searchPlots(query) {
    const results = [];
    const visited = new Set();
    const lowerQuery = query.toLowerCase();
    
    await this.searchInPage(window.location.pathname, lowerQuery, results, visited);
    await this.searchRecursive(window.location.pathname, lowerQuery, results, visited, 0, 5);
    
    return results.slice(0, 20);
  }

  /**
   * Search for plots in a specific page
   */
  async searchInPage(path, query, results, visited, maxResults = 50) {
    if (visited.has(path) || results.length >= maxResults) return;
    visited.add(path);
    
    try {
      const response = await fetch(path);
      const html = await response.text();
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, 'text/html');
      
      const items = doc.querySelectorAll('.grid-item');
      items.forEach(item => {
        const nameElement = item.querySelector('.plot-name');
        const imgElement = item.querySelector('img');
        const linkElement = item.querySelector('a');
        
        if (nameElement && imgElement && linkElement) {
          const name = nameElement.textContent.toLowerCase();
          if (name.includes(query)) {
            results.push({
              name: nameElement.textContent,
              path: path,
              href: linkElement.href,
              imgSrc: imgElement.src,
              relevance: this.calculateRelevance(name, query)
            });
          }
        }
      });
    } catch (error) {
      console.error('Error searching in', path, error);
    }
  }

  /**
   * Recursively search in subdirectories
   */
  async searchRecursive(path, query, results, visited, depth, maxDepth) {
    if (depth >= maxDepth || results.length >= 50) return;
    
    try {
      const response = await fetch(path);
      const html = await response.text();
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, 'text/html');
      
      const subdirs = doc.querySelectorAll('h2 + ul li a');
      for (const subdir of subdirs) {
        const href = subdir.getAttribute('href');
        if (href) {
          const baseUrl = path.replace(/\/[^\/]*$/, '/');
          const subPath = baseUrl + href;
          await this.searchInPage(subPath, query, results, visited);
          await this.searchRecursive(subPath, query, results, visited, depth + 1, maxDepth);
        }
      }
    } catch (error) {
      console.error('Error in recursive search:', error);
    }
  }

  /**
   * Calculate search relevance score
   */
  calculateRelevance(text, query) {
    const exactMatch = text === query;
    const startsWith = text.startsWith(query);
    const wordMatch = text.split(/\s+/).some(word => word.startsWith(query));
    
    if (exactMatch) return 100;
    if (startsWith) return 80;
    if (wordMatch) return 60;
    return 40;
  }

  /**
   * Display search results with highlighting
   */
  displaySearchResults(results, query) {
    const searchResults = document.getElementById('searchResults');
    if (!searchResults) return;
    
    if (results.length === 0) {
      searchResults.innerHTML = '<div style="padding: 1rem;">📭 No plots found</div>';
      return;
    }
    
    results.sort((a, b) => b.relevance - a.relevance);
    
    let html = '';
    results.forEach(result => {
      const highlightedName = this.highlightText(result.name, query);
      const relativePath = this.getRelativePath(result.path);
      
      html += `
        <div class="search-result-item" onclick="window.searchManager.openSearchResult('${result.href}')" title="${result.name}">
          <div style="display: flex; gap: 0.7rem; align-items: center;">
            <img src="${result.imgSrc}" style="width: 50px; height: 40px; object-fit: cover; border-radius: 4px;" />
            <div style="flex: 1; min-width: 0;">
              <div style="font-weight: 600; margin-bottom: 0.3rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                ${highlightedName}
              </div>
              <div style="font-size: 0.8rem; color: var(--breadcrumb-color); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                📍 ${relativePath}
              </div>
            </div>
          </div>
        </div>
      `;
    });
    
    searchResults.innerHTML = html;
  }

  /**
   * Highlight search query in text
   */
  highlightText(text, query) {
    const regex = new RegExp(`(${query})`, 'gi');
    return text.replace(regex, '<span class="search-highlight">$1</span>');
  }

  /**
   * Get relative path for display
   */
  getRelativePath(fullPath) {
    const parts = fullPath.split('/').filter(p => p !== '' && p !== 'index.html');
    return parts.length > 0 ? parts.join(' / ') : 'Root';
  }

  /**
   * Open search result and track it
   */
  openSearchResult(href) {
    if (window.recentPlotsManager) {
      window.recentPlotsManager.addToRecentPlots(href);
    }
    window.open(href, '_blank');
    document.getElementById('searchResults').style.display = 'none';
  }
}
