/* eslint-disable */
// enhanced-search-helper.js
// Enhanced search automation with multiple submission methods

if (window.__ENHANCED_SEARCH_HELPER_INITIALIZED__) {
  // Already initialized, skip
} else {
  window.__ENHANCED_SEARCH_HELPER_INITIALIZED__ = true;

  /**
   * Perform Google search with enhanced reliability
   * @param {string} selector - CSS selector for the search box
   * @param {string} query - Search query
   * @returns {Promise<Object>} - Result of the search operation
   */
  async function performGoogleSearch(selector, query) {
    try {
      console.log(`🔍 Attempting Google search with selector: ${selector}, query: ${query}`);

      // Find the search element
      const searchElement = document.querySelector(selector);
      if (!searchElement) {
        return {
          success: false,
          error: `Search element with selector "${selector}" not found`,
        };
      }

      // Focus and clear the search box
      searchElement.focus();
      await sleep(200);

      // Clear existing content
      searchElement.select();
      await sleep(100);

      // Fill the search box
      searchElement.value = query;

      // Trigger input events to ensure the page recognizes the input
      searchElement.dispatchEvent(new Event('input', { bubbles: true }));
      searchElement.dispatchEvent(new Event('change', { bubbles: true }));

      await sleep(500);

      // Try multiple submission methods
      const submissionSuccess = await submitGoogleSearch(searchElement, query);

      if (submissionSuccess) {
        console.log(`✅ Google search submitted successfully using selector: ${selector}`);
        return {
          success: true,
          selector,
          query,
          method: submissionSuccess.method,
        };
      } else {
        return {
          success: false,
          error: 'All submission methods failed',
        };
      }
    } catch (error) {
      console.error('Error in performGoogleSearch:', error);
      return {
        success: false,
        error: `Unexpected error: ${error.message}`,
      };
    }
  }

  /**
   * Try multiple methods to submit Google search
   * @param {Element} searchElement - The search input element
   * @param {string} query - Search query
   * @returns {Promise<Object|null>} - Success result or null
   */
  async function submitGoogleSearch(searchElement, query) {
    const methods = [
      {
        name: 'enter_key',
        action: async () => {
          console.log('🔄 Method 1: Trying Enter key');
          searchElement.focus();
          await sleep(200);

          const enterEvent = new KeyboardEvent('keydown', {
            key: 'Enter',
            code: 'Enter',
            keyCode: 13,
            which: 13,
            bubbles: true,
            cancelable: true,
          });

          searchElement.dispatchEvent(enterEvent);
          await sleep(1000);

          // Check if search was successful
          if (await checkSearchResultsLoaded()) {
            return { method: 'enter_key' };
          }
          return null;
        },
      },
      {
        name: 'search_button',
        action: async () => {
          console.log('🔄 Method 2: Trying search button');

          const buttonSelectors = [
            'input[value*="Google Search"]',
            'button[aria-label*="Google Search"]',
            'input[type="submit"][value*="Google Search"]',
            '.gNO89b', // Google Search button class
            'center input[type="submit"]:first-of-type',
            'button[type="submit"]',
            '[role="button"][aria-label*="search"]',
            '.Tg7LZd',
          ];

          for (const buttonSelector of buttonSelectors) {
            try {
              const button = document.querySelector(buttonSelector);
              if (button) {
                button.click();
                await sleep(1000);

                if (await checkSearchResultsLoaded()) {
                  return { method: 'search_button', selector: buttonSelector };
                }
              }
            } catch (e) {
              continue;
            }
          }
          return null;
        },
      },
      {
        name: 'form_submit',
        action: async () => {
          console.log('🔄 Method 3: Trying form submission');

          const form = searchElement.closest('form');
          if (form) {
            form.submit();
            await sleep(1000);

            if (await checkSearchResultsLoaded()) {
              return { method: 'form_submit' };
            }
          }
          return null;
        },
      },
      {
        name: 'double_enter',
        action: async () => {
          console.log('🔄 Method 4: Trying double Enter');
          searchElement.focus();
          await sleep(200);

          // First Enter
          const enterEvent1 = new KeyboardEvent('keydown', {
            key: 'Enter',
            code: 'Enter',
            keyCode: 13,
            which: 13,
            bubbles: true,
            cancelable: true,
          });
          searchElement.dispatchEvent(enterEvent1);
          await sleep(300);

          // Second Enter
          const enterEvent2 = new KeyboardEvent('keydown', {
            key: 'Enter',
            code: 'Enter',
            keyCode: 13,
            which: 13,
            bubbles: true,
            cancelable: true,
          });
          searchElement.dispatchEvent(enterEvent2);
          await sleep(1000);

          if (await checkSearchResultsLoaded()) {
            return { method: 'double_enter' };
          }
          return null;
        },
      },
    ];

    for (const method of methods) {
      try {
        const result = await method.action();
        if (result) {
          console.log(`✅ Submission method "${method.name}" successful`);
          return result;
        }
      } catch (error) {
        console.debug(`Submission method "${method.name}" failed:`, error);
        continue;
      }
    }

    console.warn('❌ All submission methods failed');
    return null;
  }

  /**
   * Check if Google search results have loaded
   * @returns {Promise<boolean>}
   */
  async function checkSearchResultsLoaded() {
    const resultIndicators = [
      '#search', // Main search results container
      '#rso', // Results container
      '.g', // Individual result
      '.tF2Cxc', // Modern Google result container
      '#result-stats', // Search statistics
      '.yuRUbf', // Result link container
    ];

    for (const indicator of resultIndicators) {
      const element = document.querySelector(indicator);
      if (element && element.children.length > 0) {
        return true;
      }
    }

    return false;
  }

  /**
   * Extract search results from the current page with intelligent selector discovery
   * @param {number} maxResults - Maximum number of results to extract
   * @returns {Promise<Object>} - Extracted results
   */
  async function extractSearchResults(maxResults = 10) {
    try {
      console.log('🔍 Starting intelligent search result extraction...');
      const results = [];

      // Try multiple selectors for Google search results
      const resultSelectors = [
        '.tF2Cxc', // Current Google search result container
        '.g', // Traditional Google search result
        '#rso .g', // Results container with .g class
        '.yuRUbf', // Google result link container
        '.rc', // Another Google result class
      ];

      let resultElements = [];
      let successfulSelector = null;

      // First try standard selectors
      for (const selector of resultSelectors) {
        resultElements = document.querySelectorAll(selector);
        if (resultElements.length > 0) {
          successfulSelector = selector;
          console.log(`✅ Found results with standard selector: ${selector}`);
          break;
        }
      }

      // If standard selectors fail, try intelligent discovery
      if (resultElements.length === 0) {
        console.log('🧠 Standard selectors failed, trying intelligent discovery...');
        const discoveryResult = await discoverSearchResultElements();
        resultElements = discoveryResult.elements;
        successfulSelector = discoveryResult.selector;
      }

      // Extract results from found elements
      for (let i = 0; i < Math.min(resultElements.length, maxResults); i++) {
        const element = resultElements[i];

        try {
          const extractedResult = extractResultFromElement(element, i + 1);
          if (extractedResult) {
            results.push(extractedResult);
          }
        } catch (e) {
          console.debug(`Error extracting result ${i}:`, e);
          continue;
        }
      }

      return {
        success: true,
        results,
        totalFound: results.length,
        selectorUsed: successfulSelector,
        method: resultElements.length > 0 ? 'extraction' : 'none',
      };
    } catch (error) {
      console.error('Error extracting search results:', error);
      return {
        success: false,
        error: error.message,
        results: [],
      };
    }
  }

  /**
   * Intelligent discovery of search result elements
   * @returns {Object} - Object with elements array and successful selector
   */
  async function discoverSearchResultElements() {
    console.log('🔬 Starting intelligent element discovery...');

    // Intelligent selectors based on common patterns
    const intelligentSelectors = [
      // Modern Google patterns (2024+)
      '[data-ved] h3',
      '[data-ved]:has(h3)',
      '[data-ved]:has(a[href*="http"])',
      '[jscontroller]:has(h3)',
      '[jscontroller]:has(a[href*="http"])',

      // Generic search result patterns
      'div[class*="result"]:has(h3)',
      'div[class*="search"]:has(h3)',
      'article:has(h3)',
      'li[class*="result"]:has(h3)',
      '[role="main"] div:has(h3)',

      // Link-based patterns
      'a[href*="http"]:has(h3)',
      'div:has(h3):has(a[href*="http"])',

      // Container patterns
      'div[class*="container"] > div:has(h3)',
      'div[id*="result"]:has(h3)',
      'div[id*="search"]:has(h3)',

      // Semantic patterns
      '[role="article"]:has(h3)',
      '[role="listitem"]:has(h3)',
      'div[aria-label*="result"]:has(h3)',

      // Fallback broad patterns
      'main div:has(h3)',
      '#main div:has(h3)',
      '.main div:has(h3)',
      'h3:has(+ div)',
      'div:has(h3)',
    ];

    for (const selector of intelligentSelectors) {
      try {
        const elements = document.querySelectorAll(selector);
        if (elements.length > 0) {
          // Validate that these look like search results
          const validElements = Array.from(elements).filter((el) =>
            validateSearchResultElement(el),
          );

          if (validElements.length > 0) {
            console.log(
              `✅ Found ${validElements.length} results with intelligent selector: ${selector}`,
            );
            return {
              elements: validElements,
              selector: `intelligent-${selector}`,
            };
          }
        }
      } catch (e) {
        console.debug(`Intelligent selector failed: ${selector}`, e);
        continue;
      }
    }

    // Final fallback - DOM structure analysis
    console.log('🔬 Trying DOM structure analysis...');
    return analyzeDOMForSearchResults();
  }

  /**
   * Validate that an element looks like a search result
   * @param {Element} element - Element to validate
   * @returns {boolean} - True if element looks like a search result
   */
  function validateSearchResultElement(element) {
    try {
      // Check for common search result indicators
      const hasHeading = element.querySelector('h1, h2, h3, h4, h5, h6');
      const hasLink = element.querySelector('a[href*="http"]');
      const hasText = element.textContent && element.textContent.trim().length > 50;

      // Must have at least heading and link, or substantial text
      return (hasHeading && hasLink) || hasText;
    } catch (e) {
      return false;
    }
  }

  /**
   * Analyze DOM structure to find search results using heuristics
   * @returns {Object} - Object with elements array and successful selector
   */
  function analyzeDOMForSearchResults() {
    console.log('🔬 Analyzing DOM structure for search results...');

    try {
      // Look for containers with multiple links (likely search results)
      const heuristicSelectors = [
        'div:has(a[href*="http"]):has(h3)',
        'li:has(a[href*="http"]):has(h3)',
        'article:has(a[href*="http"])',
        'main > div:has(h3)',
        '#main > div:has(h3)',
        '[role="main"] > div:has(h3)',
        'div:has(h3):has(a[href*="http"])',
        'section:has(h3):has(a[href*="http"])',
      ];

      for (const selector of heuristicSelectors) {
        try {
          const elements = document.querySelectorAll(selector);
          if (elements.length > 0) {
            const validElements = Array.from(elements).filter((el) =>
              validateSearchResultElement(el),
            );

            if (validElements.length > 0) {
              console.log(
                `✅ Found ${validElements.length} results with DOM analysis: ${selector}`,
              );
              return {
                elements: validElements,
                selector: `dom-analysis-${selector}`,
              };
            }
          }
        } catch (e) {
          console.debug(`DOM analysis selector failed: ${selector}`, e);
          continue;
        }
      }

      // Ultimate fallback - any elements with links
      const fallbackElements = document.querySelectorAll('a[href*="http"]');
      if (fallbackElements.length > 0) {
        console.log(`⚠️ Using fallback: found ${fallbackElements.length} link elements`);
        return {
          elements: Array.from(fallbackElements).slice(0, 10), // Limit to 10
          selector: 'fallback-links',
        };
      }

      console.warn('❌ DOM analysis failed to find any search results');
      return {
        elements: [],
        selector: null,
      };
    } catch (e) {
      console.error('Error in DOM analysis:', e);
      return {
        elements: [],
        selector: null,
      };
    }
  }

  /**
   * Extract result data from a single element
   * @param {Element} element - Element to extract from
   * @param {number} index - Result index
   * @returns {Object|null} - Extracted result or null
   */
  function extractResultFromElement(element, index) {
    try {
      // Try multiple patterns for title extraction
      const titleSelectors = ['h3', 'h2', 'h1', '.LC20lb', '.DKV0Md', 'a[href*="http"]'];
      let titleElement = null;

      for (const selector of titleSelectors) {
        titleElement = element.querySelector(selector);
        if (titleElement) break;
      }

      // Try multiple patterns for link extraction
      const linkElement =
        element.querySelector('a[href*="http"]') || (element.tagName === 'A' ? element : null);

      // Try multiple patterns for snippet extraction
      const snippetSelectors = ['.VwiC3b', '.s', '.st', 'p', 'div:not(:has(h1,h2,h3,h4,h5,h6))'];
      let snippetElement = null;

      for (const selector of snippetSelectors) {
        snippetElement = element.querySelector(selector);
        if (snippetElement && snippetElement.textContent.trim().length > 20) break;
      }

      // Extract data
      const title = titleElement?.textContent?.trim() || 'No title found';
      const url = linkElement?.href || '';
      const snippet = snippetElement?.textContent?.trim() || '';

      // Validate we have meaningful data
      if (title && title !== 'No title found' && url) {
        return {
          title,
          url,
          snippet,
          index,
        };
      }

      return null;
    } catch (e) {
      console.debug(`Error extracting from element:`, e);
      return null;
    }
  }

  /**
   * Sleep utility function
   * @param {number} ms - Milliseconds to sleep
   * @returns {Promise<void>}
   */
  function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  // Listen for messages from the extension
  chrome.runtime.onMessage.addListener((request, _sender, sendResponse) => {
    if (request.action === 'performGoogleSearch') {
      performGoogleSearch(request.selector, request.query)
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: `Unexpected error: ${error.message}`,
          });
        });
      return true; // Indicates async response
    } else if (request.action === 'extractSearchResults') {
      extractSearchResults(request.maxResults)
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: `Unexpected error: ${error.message}`,
            results: [],
          });
        });
      return true; // Indicates async response
    } else if (request.action === 'enhanced_search_ping') {
      sendResponse({ status: 'pong' });
      return false;
    }
  });
}
