"""
Simplified API Key Authentication
Just ID, Name, and Key - as per director's requirement
"""
from fastapi import Request, HTTPException, status, Header
from sqlalchemy.orm import Session
from typing import Optional
import uuid
from datetime import datetime

from src.database.connection import get_db
from src.database.api_key_models import APIClient, APIRequestLog, AllowedDomain
from src.utils.logger import get_logger

logger = get_logger(__name__)


class SimpleAPIKeyValidator:
    """
    Simple API key validation - no complex fields
    """
    
    @staticmethod
    async def validate_api_key(
        api_key: str,
        db: Session
    ) -> APIClient:
        """
        Validate API key and return client
        """
        if not api_key:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="API key is required. Provide 'x-myrx-api_key' header",
                headers={"WWW-Authenticate": "ApiKey"}
            )
        
        # Hash the provided key
        key_hash = APIClient.hash_key(api_key)
        
        # Find client by hashed key
        client = db.query(APIClient).filter(
            APIClient.api_key == key_hash,
            APIClient.is_active == True
        ).first()
        
        if not client:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid or inactive API key",
                headers={"WWW-Authenticate": "ApiKey"}
            )
        
        # Check monthly limit (if set)
        if client.monthly_request_limit:
            current_month = datetime.utcnow().strftime("%Y-%m")
            monthly_usage = db.query(APIRequestLog).filter(
                APIRequestLog.client_id == client.client_id,
                APIRequestLog.year_month == current_month
            ).count()
            
            if monthly_usage >= client.monthly_request_limit:
                raise HTTPException(
                    status_code=status.HTTP_429_TOO_MANY_REQUESTS,
                    detail=f"Monthly request limit ({client.monthly_request_limit}) exceeded"
                )
        
        # Update usage
        client.increment_usage()
        db.commit()
        
        return client
    
    @staticmethod
    def validate_or_generate_request_id(request_id: Optional[str]) -> str:
        """
        Validate request ID or generate new one
        """
        if not request_id:
            return str(uuid.uuid4())
        
        try:
            uuid.UUID(request_id)
            return request_id
        except ValueError:
            # If invalid UUID, generate new one
            logger.warning(f"Invalid request_id format: {request_id}, generating new one")
            return str(uuid.uuid4())
    
    @staticmethod
    async def log_request(
        db: Session,
        request_id: str,
        client: APIClient,
        request: Request,
        status_code: int,
        response_time_ms: int,
        success: bool = True
    ):
        """
        Log request for analytics and billing
        """
        try:
            origin = request.headers.get("origin", "unknown")
            
            log = APIRequestLog(
                request_id=request_id,
                client_id=client.client_id,
                endpoint=str(request.url.path),
                method=request.method,
                origin=origin,
                status_code=status_code,
                response_time_ms=response_time_ms,
                success=success
            )
            
            db.add(log)
            
            # Update domain last_seen
            if origin != "unknown":
                domain = db.query(AllowedDomain).filter(
                    AllowedDomain.domain == origin,
                    AllowedDomain.client_id == client.client_id
                ).first()
                
                if domain:
                    domain.last_seen_at = datetime.utcnow()
                    domain.total_requests += 1
            
            db.commit()
            
        except Exception as e:
            logger.error(f"Failed to log request: {e}")
