import asyncio
import time
from typing import List, Dict, Any
from datetime import datetime
import logging
from urllib.parse import quote_plus

from ...shared.selenium_base.selenium_manager import SeleniumManager
from ...shared.kafka_client.kafka_client import SearchKafkaClient
from ...shared.common_models.search_models import SearchResult, SearchResponse
from ..core.config import settings

logger = logging.getLogger(__name__)

class DuckDuckGoSearchService:
    def __init__(self):
        self.kafka_client = SearchKafkaClient(
            bootstrap_servers=settings.KAFKA_BOOTSTRAP_SERVERS,
            consumer_group=settings.KAFKA_CONSUMER_GROUP
        )
    
    async def process_search_task(self, message: Dict[str, Any]):
        """Process a DuckDuckGo search task"""
        try:
            task_id = message.get("id")
            keywords = message.get("keywords", [])
            
            logger.info(f"Processing DuckDuckGo search task: {task_id}")
            
            start_time = time.time()
            results = await self.search_duckduckgo(keywords)
            processing_time = time.time() - start_time
            
            response = SearchResponse(
                task_id=task_id,
                platform="duckduckgo",
                keywords=keywords,
                results=results,
                total_results=len(results),
                processing_time=processing_time,
                timestamp=datetime.utcnow()
            )
            
            await self.kafka_client.send_search_result(
                task_id=task_id,
                platform="duckduckgo",
                results=response.dict()
            )
            
            logger.info(f"DuckDuckGo search completed: {task_id}, found {len(results)} results")
            
        except Exception as e:
            logger.error(f"Error processing DuckDuckGo search task: {e}")
            await self.kafka_client.send_error_result(
                task_id=message.get("id", "unknown"),
                platform="duckduckgo",
                error=str(e)
            )
    
    async def search_duckduckgo(self, keywords: List[str], max_results: int = 20) -> List[SearchResult]:
        """Perform DuckDuckGo search"""
        results = []
        
        async with SeleniumManager(headless=True).driver_context() as selenium:
            try:
                query = " ".join(keywords)
                encoded_query = quote_plus(query)
                search_url = f"https://duckduckgo.com/?q={encoded_query}"
                
                logger.info(f"Searching DuckDuckGo for: {query}")
                
                await selenium.navigate_to(search_url, wait_for_element="#links")
                await selenium.wait_for_page_load()
                await asyncio.sleep(2)
                
                # Load more results by scrolling
                for _ in range(3):
                    await selenium.scroll_page(1000)
                    await asyncio.sleep(1)
                
                # Extract search results
                result_elements = await selenium.find_elements("#links .result")
                
                for element in result_elements[:max_results]:
                    try:
                        result = await self._extract_search_result(element)
                        if result:
                            results.append(result)
                    except Exception as e:
                        logger.warning(f"Error extracting result: {e}")
                        continue
                
                logger.info(f"Extracted {len(results)} results from DuckDuckGo")
                
            except Exception as e:
                logger.error(f"Error during DuckDuckGo search: {e}")
                raise
        
        return results
    
    async def _extract_search_result(self, element) -> SearchResult:
        """Extract search result from element"""
        try:
            # Extract title and URL
            title_element = element.find_element("css selector", ".result__title a")
            title = title_element.text if title_element else "No title"
            url = title_element.get_attribute("href") if title_element else ""
            
            # Extract description
            description_element = element.find_element("css selector", ".result__snippet")
            description = description_element.text if description_element else ""
            
            # Extract display URL
            display_url_element = element.find_element("css selector", ".result__url")
            display_url = display_url_element.text if display_url_element else ""
            
            return SearchResult(
                title=title,
                url=url,
                description=description,
                snippet=description,
                source="duckduckgo",
                metadata={
                    "search_engine": "duckduckgo",
                    "display_url": display_url,
                    "extracted_at": datetime.utcnow().isoformat()
                }
            )
            
        except Exception as e:
            logger.warning(f"Error extracting search result: {e}")
            return None
