"""Enhanced configuration system with Secret Manager integration."""

import os
import asyncio
from typing import Dict, Optional, Any
from functools import lru_cache
from pydantic_settings import BaseSettings

from .config import Settings as BaseConfig
from .logging import get_logger

logger = get_logger(__name__)


class SecretsConfig(BaseConfig):
    """Enhanced configuration that loads secrets from GCP Secret Manager."""
    
    def __init__(self, **kwargs):
        # Initialize with base configuration first
        super().__init__(**kwargs)
        
        # Flag to track if secrets have been loaded
        self._secrets_loaded = False
        self._secret_values: Dict[str, str] = {}
    
    async def load_secrets(self) -> None:
        """Load secrets from Secret Manager asynchronously."""
        if self._secrets_loaded:
            return
        
        try:
            # Only import here to avoid circular imports
            from app.services.secrets_manager import secrets_manager
            
            # Define which config fields should be loaded from secrets
            secret_mappings = {
                # Config field -> Secret Manager name
                "jwt_secret": "jwt-secret",
                "jwt_refresh_secret": "jwt-refresh-secret", 
                "mongodb_uri": "mongodb-url",
                "redis_url": "redis-url",
                "gemini_api_key": "gemini-api-key",
                "sendgrid_api_key": "sendgrid-api-key",
                "elevenlabs_api_key": "elevenlabs-api-key",
                "sentry_dsn": "sentry-dsn"
            }
            
            # Get all secrets in batch
            secret_names = list(secret_mappings.values())
            retrieved_secrets = await secrets_manager.get_secrets_batch(secret_names)
            
            # Map secrets back to config fields
            for config_field, secret_name in secret_mappings.items():
                if secret_name in retrieved_secrets:
                    self._secret_values[config_field] = retrieved_secrets[secret_name]
                    # Override the config value
                    setattr(self, config_field, retrieved_secrets[secret_name])
                    logger.debug(f"Loaded secret for {config_field}")
                else:
                    logger.warning(f"Secret {secret_name} not available, using environment/default")
            
            self._secrets_loaded = True
            logger.info(f"Successfully loaded {len(retrieved_secrets)} secrets from Secret Manager")
            
        except Exception as e:
            logger.warning(f"Failed to load secrets from Secret Manager: {e}")
            logger.warning("Falling back to environment variables")
            self._secrets_loaded = True  # Mark as loaded to prevent retries
    
    def get_secret_value(self, field_name: str) -> Optional[str]:
        """Get a secret value if it was loaded from Secret Manager."""
        return self._secret_values.get(field_name)
    
    async def refresh_secrets(self) -> None:
        """Force refresh secrets from Secret Manager."""
        self._secrets_loaded = False
        self._secret_values.clear()
        
        # Clear the secrets manager cache
        from app.services.secrets_manager import secrets_manager
        secrets_manager.clear_cache()
        
        await self.load_secrets()
    
    @property
    def is_production(self) -> bool:
        """Check if running in production environment."""
        return self.app_env == "prod"
    
    @property
    def is_development(self) -> bool:
        """Check if running in development environment."""
        return self.app_env == "dev"
    
    @property
    def google_cloud_project(self) -> str:
        """Get Google Cloud Project ID."""
        return self.gcp_project_id
    
    @property
    def jwt_refresh_secret(self) -> str:
        """Get JWT refresh secret (fallback to main secret if not set)."""
        return getattr(self, '_jwt_refresh_secret', self.jwt_secret)
    
    @jwt_refresh_secret.setter
    def jwt_refresh_secret(self, value: str) -> None:
        """Set JWT refresh secret."""
        self._jwt_refresh_secret = value


# Global configuration instance
_config_instance: Optional[SecretsConfig] = None


async def initialize_config() -> SecretsConfig:
    """Initialize configuration with secrets loading."""
    global _config_instance
    
    if _config_instance is None:
        _config_instance = SecretsConfig()
        await _config_instance.load_secrets()
    
    return _config_instance


def get_settings() -> SecretsConfig:
    """Get settings instance (synchronous)."""
    global _config_instance
    
    if _config_instance is None:
        # Initialize without secrets for backwards compatibility
        _config_instance = SecretsConfig()
        logger.warning("Settings accessed before async initialization - secrets not loaded")
    
    return _config_instance


@lru_cache()
def get_settings_cached() -> SecretsConfig:
    """Get cached settings instance."""
    return get_settings()


# Backwards compatibility
settings = get_settings()