import uuid
from fastapi import APIRouter, Depends, HTTPException, Response, Request
from fastapi.responses import RedirectResponse, JSONResponse
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

from services.database import get_async_session
from services.auth_service import AuthService
from api.middlewares.rate_limit_middleware import limiter

AUTH_ROUTER = APIRouter(prefix="/api/v1/auth", tags=["Auth"])

auth_service = AuthService()


class DevLoginRequest(BaseModel):
    email: str
    password: str


@AUTH_ROUTER.get("/dev-status")
async def dev_status():
    """Check if dev auth mode is enabled."""
    return {"dev_mode": auth_service.is_dev_mode}


@AUTH_ROUTER.get("/login")
@limiter.limit("5/minute")
async def login(request: Request):
    """Redirect to Azure AD login, or return dev mode info."""
    if auth_service.is_dev_mode:
        return JSONResponse(
            status_code=200,
            content={
                "dev_mode": True,
                "message": "Use POST /api/v1/auth/dev-login with email and password",
            },
        )
    try:
        url = auth_service.get_authorization_url()
        return RedirectResponse(url=url)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to generate login URL: {e}")


@AUTH_ROUTER.get("/callback")
async def callback(
    code: str = "",
    error: str = "",
    error_description: str = "",
    session: AsyncSession = Depends(get_async_session),
):
    """Azure AD OAuth callback."""
    if error:
        raise HTTPException(status_code=401, detail=error_description or error)

    if not code:
        raise HTTPException(status_code=400, detail="Missing authorization code")

    try:
        result = await auth_service.exchange_code_for_token(code)
        claims = result.get("id_token_claims", {})
        user = await auth_service.get_or_create_user(claims, session)
        token = auth_service.create_session_jwt(user)

        response = RedirectResponse(url="/dashboard", status_code=302)
        response.set_cookie(
            key="session_token",
            value=token,
            httponly=True,
            secure=False,  # Set True in production with HTTPS
            samesite="lax",
            max_age=86400,  # 24 hours
        )
        return response
    except ValueError as e:
        raise HTTPException(status_code=401, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Authentication failed: {e}")


@AUTH_ROUTER.post("/dev-login")
@limiter.limit("3/minute")
async def dev_login(
    request: Request,
    body: DevLoginRequest,
    session: AsyncSession = Depends(get_async_session),
):
    """Dev-mode login with email and password. Only available when Azure AD is not configured."""
    if not auth_service.is_dev_mode:
        raise HTTPException(status_code=404, detail="Dev login not available")

    user = await auth_service.dev_login(body.email, body.password, session)
    if not user:
        raise HTTPException(status_code=401, detail="Invalid credentials")

    token = auth_service.create_session_jwt(user)

    response = JSONResponse(
        content={
            "id": str(user.id),
            "email": user.email,
            "display_name": user.display_name,
            "role": user.role,
        }
    )
    response.set_cookie(
        key="session_token",
        value=token,
        httponly=True,
        secure=False,
        samesite="lax",
        max_age=86400,
    )
    return response


@AUTH_ROUTER.get("/me")
async def get_current_user_info(
    request: Request,
    session: AsyncSession = Depends(get_async_session),
):
    """Return current authenticated user info."""
    user = getattr(request.state, "user", None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")

    from services.access_service import get_accessible_client_ids

    client_ids = await get_accessible_client_ids(user, session)
    primary_client_id = str(client_ids[0]) if client_ids else None

    return {
        "id": str(user.id),
        "email": user.email,
        "displayName": user.display_name,
        "role": user.role,
        "clientId": primary_client_id,
    }


@AUTH_ROUTER.post("/logout")
async def logout():
    """Clear session cookie."""
    response = JSONResponse(content={"message": "Logged out"})
    response.delete_cookie("session_token")
    return response
