"""
ModelRouter Extension - Adds Provider Fallback Support
This extends the existing ModelRouter with automatic provider cycling
"""
import logging
from typing import Any, Optional
from .provider_fallback import get_provider_fallback_service, ProviderFallbackService

logger = logging.getLogger(__name__)


class ModelRouterWithFallback:
    """
    Wrapper that adds provider fallback to ModelRouter
    """
    
    def __init__(self, model_router):
        """
        Args:
            model_router: The existing ModelRouter instance
        """
        self.model_router = model_router
        self.fallback_service = get_provider_fallback_service()
        
    async def chat_completion_with_fallback(
        self,
        messages: list,
        model: Optional[str] = None,
        **kwargs
    ) -> Optional[Any]:
        """
        Try chat completion with automatic provider fallback.
        
        Args:
            messages: Chat messages
            model: Specific model to use (optional - uses provider default if None)
            **kwargs: Additional completion parameters
            
        Returns:
            Response from first successful provider, or None if all failed
        """
        logger.info(f"Attempting chat completion with fallback across {len(self.fallback_service.providers)} providers")
        
        # Try with fallback system
        response, attempts = await self.fallback_service.complete_with_fallback(
            messages=messages,
            fallback_model=model,
            **kwargs
        )
        
        # Log summary
        successful_attempts = [a for a in attempts if a.status.value == "success"]
        failed_attempts = [a for a in attempts if a.status.value != "success"]
        
        logger.info(f"Provider attempts: {len(successful_attempts)} successful, {len(failed_attempts)} failed")
        
        # Log details for failed attempts
        for attempt in failed_attempts:
            logger.warning(
                f"  ✗ {attempt.provider_name}: {attempt.status.value} "
                f"({attempt.latency_seconds:.2f}s)"
            )
            if attempt.error_message:
                logger.debug(f"    Error: {attempt.error_message[:200]}")
        
        if response:
            logger.info(f"✓ Chat completion succeeded via provider fallback")
            return response
        
        # All fallback attempts failed - try original model_router as last resort
        logger.warning("All fallback providers failed, trying original model_router")
        try:
            return await self._try_original_router(messages, model, **kwargs)
        except Exception as e:
            logger.error(f"Original model_router also failed: {e}")
            return None
    
    async def _try_original_router(
        self,
        messages: list,
        model: Optional[str] = None,
        **kwargs
    ) -> Optional[Any]:
        """Try the original model_router as final fallback"""
        try:
            # This will use the existing model_router.chat_completion method
            # which uses the configured profiles from models.yaml
            return await self.model_router.chat_completion(
                messages=messages,
                model=model,
                **kwargs
            )
        except Exception as e:
            logger.error(f"Original model_router failed: {e}")
            return None
    
    def list_providers(self) -> list[dict]:
        """List all configured providers with their status"""
        return self.fallback_service.list_providers()
    
    def enable_provider(self, name: str) -> bool:
        """Enable a specific provider"""
        return self.fallback_service.enable_provider(name)
    
    def disable_provider(self, name: str) -> bool:
        """Disable a specific provider"""
        return self.fallback_service.disable_provider(name)


def add_fallback_to_router(model_router) -> ModelRouterWithFallback:
    """
    Add fallback capability to an existing ModelRouter instance.
    
    Args:
        model_router: The existing ModelRouter instance
        
    Returns:
        ModelRouterWithFallback wrapper with fallback capability
    """
    return ModelRouterWithFallback(model_router)
