"""
API Key Service

Handles encrypted API key management for users.

Usage:
    from apps.chatbot.services import APIKeyService
    
    # Store user's API key
    api_key = APIKeyService.create_api_key(
        user=user,
        provider="openai",
        api_key="sk-...",
        key_name="My OpenAI Key"
    )
"""

from typing import Optional, List
from uuid import UUID

from apps.chatbot.models import UserAPIKey
from apps.accounts.models import CustomUser


class APIKeyService:
    """Service for managing user API keys."""
    
    @staticmethod
    def create_api_key(
        user: CustomUser,
        provider: str,
        api_key: str,
        key_name: Optional[str] = None,
        is_default: bool = False
    ) -> UserAPIKey:
        """
        Create and encrypt user API key.
        
        Args:
            user: The user
            provider: Provider name (openai, anthropic, etc.)
            api_key: The actual API key (will be encrypted)
            key_name: User-friendly name
            is_default: Set as default key for provider
        
        Returns:
            Created UserAPIKey instance
        
        Example:
            api_key = APIKeyService.create_api_key(
                user=request.user,
                provider="openai",
                api_key="sk-proj-...",
                key_name="My OpenAI Key",
                is_default=True
            )
        """
        # If setting as default, unset other defaults
        if is_default:
            UserAPIKey.objects.filter(
                user=user,
                provider=provider,
                is_default=True
            ).update(is_default=False)
        
        # Create key
        user_api_key = UserAPIKey.objects.create(
            user=user,
            provider=provider,
            key_name=key_name or f"{provider.title()} Key",
            is_default=is_default
        )
        
        # Encrypt and save
        user_api_key.encrypt_api_key(api_key)
        user_api_key.save()
        
        return user_api_key
    
    @staticmethod
    def get_user_keys(
        user: CustomUser,
        provider: Optional[str] = None
    ) -> List[UserAPIKey]:
        """
        Get user's API keys.
        
        Args:
            user: The user
            provider: Filter by provider (optional)
        
        Returns:
            List of UserAPIKey instances
        """
        query = UserAPIKey.objects.filter(user=user, is_active=True)
        
        if provider:
            query = query.filter(provider=provider)
        
        return list(query.order_by('-is_default', '-created_at'))
    
    @staticmethod
    def get_default_key(
        user: CustomUser,
        provider: str
    ) -> Optional[UserAPIKey]:
        """
        Get user's default key for a provider.
        
        Args:
            user: The user
            provider: Provider name
        
        Returns:
            UserAPIKey instance or None
        """
        try:
            return UserAPIKey.objects.get(
                user=user,
                provider=provider,
                is_default=True,
                is_active=True
            )
        except UserAPIKey.DoesNotExist:
            # Try to get any active key
            try:
                return UserAPIKey.objects.filter(
                    user=user,
                    provider=provider,
                    is_active=True
                ).first()
            except:
                return None
    
    @staticmethod
    def get_decrypted_key(
        user: CustomUser,
        provider: str
    ) -> Optional[str]:
        """
        Get decrypted API key for provider.
        
        Args:
            user: The user
            provider: Provider name
        
        Returns:
            Decrypted API key or None
        
        Example:
            api_key = APIKeyService.get_decrypted_key(
                user=request.user,
                provider="openai"
            )
            
            if api_key:
                # Use key with OpenAI
                client = OpenAI(api_key=api_key)
        """
        user_api_key = APIKeyService.get_default_key(user, provider)
        
        if user_api_key:
            return user_api_key.decrypt_api_key()
        
        return None
    
    @staticmethod
    def validate_key(
        user: CustomUser,
        key_id: UUID
    ) -> Dict[str, Any]:
        """
        Validate an API key.
        
        Args:
            user: The user
            key_id: UserAPIKey ID
        
        Returns:
            Validation result dict
        """
        user_api_key = UserAPIKey.objects.get(id=key_id, user=user)
        result = user_api_key.validate_key()
        
        if result['valid']:
            user_api_key.is_validated = True
            user_api_key.save()
        
        return result
    
    @staticmethod
    def delete_key(
        user: CustomUser,
        key_id: UUID
    ) -> None:
        """
        Delete an API key.
        
        Args:
            user: The user
            key_id: UserAPIKey ID
        """
        UserAPIKey.objects.filter(
            id=key_id,
            user=user
        ).delete()
    
    @staticmethod
    def set_default_key(
        user: CustomUser,
        key_id: UUID
    ) -> UserAPIKey:
        """
        Set a key as default for its provider.
        
        Args:
            user: The user
            key_id: UserAPIKey ID
        
        Returns:
            Updated UserAPIKey instance
        """
        user_api_key = UserAPIKey.objects.get(id=key_id, user=user)
        
        # Unset other defaults
        UserAPIKey.objects.filter(
            user=user,
            provider=user_api_key.provider,
            is_default=True
        ).update(is_default=False)
        
        # Set as default
        user_api_key.is_default = True
        user_api_key.save()
        
        return user_api_key
