"""
Authentication Middleware
JWT validation and request authentication
"""
from typing import Optional
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import JSONResponse
import logging

from app.services.auth_service import AuthService

logger = logging.getLogger(__name__)


class AuthMiddleware(BaseHTTPMiddleware):
    """
    Middleware to validate JWT tokens and set user in request state.
    This allows rate limiting and other middleware to access user info.
    """
    
    # Paths that don't require authentication
    PUBLIC_PATHS = {
        "/",
        "/health",
        "/docs",
        "/redoc",
        "/openapi.json",
        "/api/v1/health",
        "/api/v1/auth/register",
        "/api/v1/auth/login",
        "/api/v1/auth/send-otp",
        "/api/v1/auth/verify-otp",
        "/api/v1/auth/refresh-token",
        "/api/v1/auth/social-login",
    }
    
    async def dispatch(self, request: Request, call_next):
        # Skip authentication for public paths
        if request.url.path in self.PUBLIC_PATHS:
            return await call_next(request)
        
        # Skip WebSocket requests (handled separately)
        if request.url.path.startswith("/ws/"):
            return await call_next(request)
        
        # Try to extract and validate token
        auth_header = request.headers.get("Authorization")
        
        if auth_header and auth_header.startswith("Bearer "):
            token = auth_header.split(" ")[1]
            payload = AuthService.decode_token(token)
            
            if payload and payload.get("type") == "access":
                # Set user info in request state for other middleware/handlers
                request.state.user_id = int(payload.get("sub", 0))
                request.state.user_role = payload.get("role")
        
        # Continue processing (actual auth is handled by dependencies)
        return await call_next(request)
