from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel

from app.auth.jwt_provider import JWTAuthProvider
from app.auth.rate_limiter import LoginRateLimiter, get_client_ip
from app.dependencies import get_jwt_auth

router = APIRouter(tags=["auth"])


class LoginRequest(BaseModel):
    username: str
    password: str


class TokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    expires_in: int


@router.post("/auth/token", response_model=TokenResponse)
async def login(
    request: Request,
    body: LoginRequest,
    auth: JWTAuthProvider = Depends(get_jwt_auth),
):
    limiter: LoginRateLimiter = request.app.state.login_rate_limiter
    ip: str = get_client_ip(request, request.app.state.login_trusted_networks)

    if limiter.is_blocked(ip):
        return JSONResponse(
            status_code=429,
            content={
                "detail": "Too many failed login attempts. Please try again later.",
                "code": "login_rate_limited",
            },
            headers={"Retry-After": str(limiter.cooldown_seconds)},
        )

    if not auth.verify_credentials(body.username, body.password):
        limiter.record_failure(ip)
        raise HTTPException(
            status_code=401,
            detail={"detail": "Invalid credentials", "code": "invalid_credentials"},
        )

    limiter.record_success(ip)
    token = auth.create_token()
    return TokenResponse(
        access_token=token,
        token_type="bearer",
        expires_in=auth._expiry_seconds,
    )
