"""
External API Key Validation via mana-core-auth

When EXTERNAL_AUTH_ENABLED=true, API keys are validated against the
central mana-core-auth service. This allows users to create and manage
API keys from the mana.how web interface.

Results are cached for 5 minutes to reduce load on the auth service.
"""

import os
import time
import logging
import httpx
from typing import Optional
from dataclasses import dataclass

logger = logging.getLogger(__name__)

# Configuration
EXTERNAL_AUTH_ENABLED = os.getenv("EXTERNAL_AUTH_ENABLED", "false").lower() == "true"
MANA_CORE_AUTH_URL = os.getenv("MANA_CORE_AUTH_URL", "http://localhost:3001")
API_KEY_CACHE_TTL = int(os.getenv("API_KEY_CACHE_TTL", "300"))  # 5 minutes
EXTERNAL_AUTH_TIMEOUT = float(os.getenv("EXTERNAL_AUTH_TIMEOUT", "5.0"))  # seconds


@dataclass
class ExternalValidationResult:
    """Result from external API key validation."""
    valid: bool
    user_id: Optional[str] = None
    scopes: Optional[list] = None
    rate_limit_requests: int = 60
    rate_limit_window: int = 60
    error: Optional[str] = None
    cached_at: float = 0.0


# In-memory cache for validation results
# Key: API key, Value: ExternalValidationResult
_validation_cache: dict[str, ExternalValidationResult] = {}


def is_external_auth_enabled() -> bool:
    """Check if external authentication is enabled."""
    return EXTERNAL_AUTH_ENABLED


def _get_cached_result(api_key: str) -> Optional[ExternalValidationResult]:
    """Get cached validation result if still valid."""
    result = _validation_cache.get(api_key)
    if result and (time.time() - result.cached_at) < API_KEY_CACHE_TTL:
        return result
    return None


def _cache_result(api_key: str, result: ExternalValidationResult):
    """Cache a validation result."""
    result.cached_at = time.time()
    _validation_cache[api_key] = result

    # Clean up old entries periodically (keep cache size manageable)
    if len(_validation_cache) > 1000:
        now = time.time()
        expired_keys = [
            k for k, v in _validation_cache.items()
            if (now - v.cached_at) >= API_KEY_CACHE_TTL
        ]
        for k in expired_keys:
            del _validation_cache[k]


async def validate_api_key_external(api_key: str, scope: str) -> Optional[ExternalValidationResult]:
    """
    Validate an API key against mana-core-auth service.

    Args:
        api_key: The API key to validate (e.g., "sk_live_...")
        scope: The required scope (e.g., "stt" or "tts")

    Returns:
        ExternalValidationResult if external auth is enabled and the key was validated.
        None if external auth is disabled or the service is unavailable (fallback to local).
    """
    if not EXTERNAL_AUTH_ENABLED:
        return None

    # Check cache first
    cached = _get_cached_result(api_key)
    if cached:
        logger.debug(f"Using cached validation result for key prefix: {api_key[:12]}...")
        # Check scope against cached result
        if cached.valid and cached.scopes and scope not in cached.scopes:
            return ExternalValidationResult(
                valid=False,
                error=f"API key does not have scope: {scope}",
            )
        return cached

    # Call mana-core-auth validation endpoint
    try:
        async with httpx.AsyncClient(timeout=EXTERNAL_AUTH_TIMEOUT) as client:
            response = await client.post(
                f"{MANA_CORE_AUTH_URL}/api/v1/api-keys/validate",
                json={"apiKey": api_key, "scope": scope},
            )

            if response.status_code == 200:
                data = response.json()
                result = ExternalValidationResult(
                    valid=data.get("valid", False),
                    user_id=data.get("userId"),
                    scopes=data.get("scopes", []),
                    rate_limit_requests=data.get("rateLimit", {}).get("requests", 60),
                    rate_limit_window=data.get("rateLimit", {}).get("window", 60),
                    error=data.get("error"),
                )
                _cache_result(api_key, result)
                return result
            else:
                logger.warning(
                    f"External auth returned status {response.status_code}: {response.text}"
                )
                # Don't cache errors - allow retry
                return ExternalValidationResult(
                    valid=False,
                    error=f"Auth service returned {response.status_code}",
                )

    except httpx.TimeoutException:
        logger.warning("External auth service timeout - falling back to local auth")
        return None
    except httpx.ConnectError:
        logger.warning("Cannot connect to external auth service - falling back to local auth")
        return None
    except Exception as e:
        logger.error(f"External auth error: {e}")
        return None


def clear_cache():
    """Clear the validation cache (for testing or runtime updates)."""
    global _validation_cache
    _validation_cache.clear()
    logger.info("External auth cache cleared")
