"""
Middleware Module - Auth + Rate Limit
Simplified for fixing corruption.
"""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from fastapi import Request, FastAPI
from common.jwt_auth import decode_token
from config import DISABLE_AUTH

if TYPE_CHECKING:
    from fastapi import FastAPI

logger = logging.getLogger(__name__)

PUBLIC_PATHS = {"/", "/health", "/docs", "/openapi.json", "/redoc"}
PUBLIC_PATH_PREFIXES = ["/static", "/mock", "/api/test"]

class CuCuAuthMiddleware:
    def __init__(self, app):
        self.app = app

    async def __call__(self, scope, receive, send):
        if scope["type"] != "http":
            await self.app(scope, receive, send)
            return

        from fastapi import Request
        request = Request(scope)
        path = request.url.path
        method = request.method

        if DISABLE_AUTH:
            if "state" not in scope: scope["state"] = {}
            auth_header = request.headers.get("Authorization")
            mock_id = "testuser_local"
            if auth_header and auth_header.startswith("Bearer "):
                token = auth_header.replace("Bearer ", "")
                try:
                    payload = decode_token(token)
                    if payload and "sub" in payload:
                        mock_id = str(payload.get("sub"))
                except:
                    if len(token) < 50:
                        mock_id = token
            scope["state"]["user"] = {"sub": mock_id}
            scope["state"]["user_id"] = mock_id
            scope["state"]["is_authenticated"] = True
            await self.app(scope, receive, send)
            return

        # Normal mode
        if method == "OPTIONS":
            await self.app(scope, receive, send)
            return

        if path in PUBLIC_PATHS or any(path.startswith(prefix) for prefix in PUBLIC_PATH_PREFIXES):
            await self.app(scope, receive, send)
            return

        # Basic Auth Check for non-DISABLE_AUTH
        try:
            auth_header = request.headers.get("Authorization")
            if not auth_header or not auth_header.startswith("Bearer "):
                if "state" not in scope: scope["state"] = {}
                scope["state"]["user"] = None
                scope["state"]["user_id"] = None
                scope["state"]["is_authenticated"] = False
            else:
                token = auth_header.replace("Bearer ", "")
                try:
                    payload = decode_token(token)
                    if "state" not in scope: scope["state"] = {}
                    if payload and "sub" in payload:
                        scope["state"]["user"] = payload
                        scope["state"]["user_id"] = str(payload.get("sub"))
                        scope["state"]["is_authenticated"] = True
                    else:
                        scope["state"]["is_authenticated"] = False
                except:
                    if "state" not in scope: scope["state"] = {}
                    scope["state"]["is_authenticated"] = False
        except Exception as e:
            logger.error(f"Auth error: {e}")

        await self.app(scope, receive, send)

class MiddlewareManager:
    _instance = None
    _initialized = False
    
    def __new__(cls) -> MiddlewareManager:
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self) -> None:
        if MiddlewareManager._initialized:
            return
        self._auth_enabled = False
        MiddlewareManager._initialized = True
        logger.info("MiddlewareManager initialized")

    def setup(
        self,
        app: FastAPI,
        *,
        enable_auth: bool = True,
        enable_rate_limit: bool = False,
        enable_cors: bool = True,
        cors_origins: list[str] | None = None,
    ) -> None:
        if enable_cors:
            from fastapi.middleware.cors import CORSMiddleware
            app.add_middleware(
                CORSMiddleware,
                allow_origins=cors_origins or ["*"],
                allow_credentials=True,
                allow_methods=["*"],
                allow_headers=["*"],
            )
        if enable_auth:
            app.add_middleware(CuCuAuthMiddleware)
            self._auth_enabled = True

    @property
    def is_auth_enabled(self) -> bool:
        return self._auth_enabled

middleware_manager = MiddlewareManager()
