"""Ultra-fast Bing scraper using optimized Selenium."""

import logging
import random
import time
from typing import List, Optional
from urllib.parse import urlencode, unquote
from selenium.webdriver.common.by import By
import re
import base64

from .fast_selenium_base import FastSeleniumBase
from src.models.schemas import SearchResult

logger = logging.getLogger(__name__)

class BingFastScraper(FastSeleniumBase):
    """Ultra-fast Bing scraper with Selenium optimizations."""
    
    def __init__(self, headless: bool = True):
        super().__init__("bing", headless, fast_mode=True)
        self.base_url = "https://www.bing.com"
    
    def search(self, query: str, max_results: int = 10) -> List[SearchResult]:
        """Fast Bing search."""
        results = []
        
        try:
            # Direct search URL
            search_url = f"https://www.bing.com/search?q={urlencode({'': query})[1:]}&count={max_results}"
            
            if not self._fast_navigate(search_url):
                logger.error("Failed to navigate to Bing")
                return results
            
            # Quick consent handling
            self._handle_consent_fast()
            
            # Extract results
            results = self._extract_results_fast(max_results)
            
            logger.info(f"Bing: Found {len(results)} results for '{query}'")
            
        except Exception as e:
            logger.error(f"Bing search error: {e}")
            if self._handle_blocking():
                logger.warning("Bing search blocked")
        
        return results
    
    def _handle_consent_fast(self):
        """Fast Bing consent handling."""
        try:
            consent_selectors = ['#bnp_btn_accept', 'button[id*="accept"]', '.ms-Button--primary']
            
            for selector in consent_selectors:
                consent_btn = self._fast_find_element(selector, timeout=2)
                if consent_btn:
                    consent_btn.click()
                    time.sleep(0.5)
                    break
        except:
            pass
    
    def _extract_results_fast(self, max_results: int) -> List[SearchResult]:
        """Fast Bing result extraction."""
        results = []
        
        try:
            # Bing result selectors
            result_selectors = ['.b_algo', 'li.b_algo', '.b_result']
            
            containers = []
            for selector in result_selectors:
                containers = self._fast_find_elements(selector, timeout=8)
                if containers:
                    break
            
            if not containers:
                logger.warning("No Bing result containers found")
                return results
            
            # Fast extraction
            for i, container in enumerate(containers[:max_results]):
                try:
                    result = self._extract_single_result_fast(container, i + 1)
                    if result:
                        results.append(result)
                except Exception as e:
                    logger.debug(f"Error extracting Bing result {i}: {e}")
                    continue
            
        except Exception as e:
            logger.error(f"Error extracting Bing results: {e}")
        
        return results
    
    def _extract_single_result_fast(self, container, position: int) -> Optional[SearchResult]:
        """Fast single Bing result extraction."""
        try:
            title = ""
            url = ""
            description = ""
            
            # Quick title and URL extraction
            title_selectors = ['h2 a', 'h3 a', '.b_title a']
            for selector in title_selectors:
                try:
                    title_elem = container.find_element(By.CSS_SELECTOR, selector)
                    title = self._get_text_fast(title_elem)
                    url = self._get_attribute_fast(title_elem, 'href')
                    if title and url:
                        break
                except:
                    continue
            
            # Quick description extraction
            desc_selectors = ['.b_caption p', '.b_snippet', '.b_lineclamp2']
            for selector in desc_selectors:
                try:
                    desc_elem = container.find_element(By.CSS_SELECTOR, selector)
                    description = self._get_text_fast(desc_elem)
                    if description:
                        break
                except:
                    continue
            
            if not title and not url:
                return None
            
            # Clean the URL - FIXED VERSION
            url = self._clean_bing_url(url)
            
            return self._create_result(title or url, url, description, position)
            
        except Exception as e:
            logger.debug(f"Error extracting single Bing result: {e}")
            return None
    
    def _clean_bing_url(self, url: str) -> str:
        """Clean Bing URLs from redirects - ENHANCED VERSION."""
        if not url:
            return ""
        
        try:
            # Handle various Bing redirect patterns
            if 'bing.com/ck/a' in url or 'r.msn.com' in url:
                # Try to extract the real URL from redirect
                match = re.search(r'u=([^&]+)', url)
                if match:
                    encoded_url = unquote(match.group(1))
                    
                    # Handle base64 encoded URLs
                    if encoded_url.startswith('a1aHR0'):
                        try:
                            # Add padding if needed
                            missing_padding = len(encoded_url) % 4
                            if missing_padding:
                                encoded_url += '=' * (4 - missing_padding)
                            
                            decoded = base64.b64decode(encoded_url).decode('utf-8')
                            if decoded.startswith('http'):
                                return decoded
                        except Exception as e:
                            logger.debug(f"Base64 decoding failed: {e}")
                    
                    # Return the unquoted URL if not base64
                    if encoded_url.startswith('http'):
                        return encoded_url
            
            # Handle direct Bing URLs
            if url.startswith('http'):
                return url
            
            # Handle relative URLs
            if url.startswith('/'):
                return f"https://www.bing.com{url}"
            
            return url
            
        except Exception as e:
            logger.error(f"Error cleaning Bing URL: {e}")
            return url
