import os
from typing import List, Dict, Any

from dejavu.reranker.base import BaseReranker

try:
    from zeroentropy import ZeroEntropy
    ZERO_ENTROPY_AVAILABLE = True
except ImportError:
    ZERO_ENTROPY_AVAILABLE = False


class ZeroEntropyReranker(BaseReranker):
    """Zero Entropy-based reranker implementation."""
    
    def __init__(self, config):
        """
        Initialize Zero Entropy reranker.
        
        Args:
            config: ZeroEntropyRerankerConfig object with configuration parameters
        """
        if not ZERO_ENTROPY_AVAILABLE:
            raise ImportError("zeroentropy package is required for ZeroEntropyReranker. Install with: pip install zeroentropy")
        
        self.config = config
        self.api_key = config.api_key or os.getenv("ZERO_ENTROPY_API_KEY")
        if not self.api_key:
            raise ValueError("Zero Entropy API key is required. Set ZERO_ENTROPY_API_KEY environment variable or pass api_key in config.")
            
        self.model = config.model or "zerank-1"
        
        # Initialize Zero Entropy client
        if self.api_key:
            self.client = ZeroEntropy(api_key=self.api_key)
        else:
            self.client = ZeroEntropy()  # Will use ZERO_ENTROPY_API_KEY from environment
        
    def rerank(self, query: str, documents: List[Dict[str, Any]], top_k: int = None) -> List[Dict[str, Any]]:
        """
        Rerank documents using Zero Entropy's rerank API.
        
        Args:
            query: The search query
            documents: List of documents to rerank
            top_k: Number of top documents to return
            
        Returns:
            List of reranked documents with rerank_score
        """
        if not documents:
            return documents
            
        # Extract text content for reranking
        doc_texts = []
        for doc in documents:
            if 'memory' in doc:
                doc_texts.append(doc['memory'])
            elif 'text' in doc:
                doc_texts.append(doc['text'])  
            elif 'content' in doc:
                doc_texts.append(doc['content'])
            else:
                doc_texts.append(str(doc))
        
        try:
            # Call Zero Entropy rerank API
            response = self.client.models.rerank(
                model=self.model,
                query=query,
                documents=doc_texts,
            )
            
            # Create reranked results
            reranked_docs = []
            for result in response.results:
                original_doc = documents[result.index].copy()
                original_doc['rerank_score'] = result.relevance_score
                reranked_docs.append(original_doc)
            
            # Sort by relevance score in descending order
            reranked_docs.sort(key=lambda x: x['rerank_score'], reverse=True)
            
            # Apply top_k limit
            if top_k:
                reranked_docs = reranked_docs[:top_k]
            elif self.config.top_k:
                reranked_docs = reranked_docs[:self.config.top_k]
                
            return reranked_docs

        except Exception:
            # Fallback to original order if reranking fails
            for doc in documents:
                doc['rerank_score'] = 0.0
            return documents[:top_k] if top_k else documents