from __future__ import annotations

from fastapi import APIRouter, HTTPException, Request, Response, status

from api.schemas.auth import CreateAuthUserBody, LoginBody, UpdateAuthUserBody
from api.services.auth import (
    SESSION_COOKIE_NAME,
    DuplicateUsernameError,
    InvalidCredentialsError,
    authenticate,
    create_user,
    delete_user,
    list_users,
    revoke_session,
    update_user,
)
from supply_infra.config import get_infra_settings

router = APIRouter(prefix="/api", tags=["authentication"])


@router.post("/auth/login")
def login(body: LoginBody, request: Request, response: Response) -> dict:
    try:
        user, token = authenticate(
            username=body.username,
            password=body.password,
            ip_address=request.client.host if request.client else None,
            user_agent=request.headers.get("user-agent"),
        )
    except InvalidCredentialsError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
        ) from None

    settings = get_infra_settings()
    response.set_cookie(
        key=SESSION_COOKIE_NAME,
        value=token,
        max_age=settings.auth_session_hours * 60 * 60,
        httponly=True,
        secure=settings.auth_cookie_secure,
        samesite="lax",
        path="/",
    )
    return {"user": user}


@router.get("/auth/me")
def me(request: Request) -> dict:
    return {"user": request.state.current_user}


@router.post("/auth/logout")
def logout(request: Request, response: Response) -> dict[str, bool]:
    token = request.cookies.get(SESSION_COOKIE_NAME)
    if token:
        revoke_session(token)
    response.delete_cookie(
        key=SESSION_COOKIE_NAME,
        path="/",
        secure=get_infra_settings().auth_cookie_secure,
        httponly=True,
        samesite="lax",
    )
    return {"ok": True}


@router.get("/admin/users")
def admin_users() -> dict:
    return {"items": list_users()}


@router.post("/admin/users", status_code=201)
def admin_create_user(body: CreateAuthUserBody) -> dict:
    try:
        return create_user(
            username=body.username,
            password=body.password,
            display_name=body.display_name,
            role=body.role,
        )
    except DuplicateUsernameError:
        raise HTTPException(status_code=409, detail="用户名已存在") from None


@router.patch("/admin/users/{user_id}")
def admin_update_user(
    user_id: int,
    body: UpdateAuthUserBody,
    request: Request,
) -> dict:
    current_user = request.state.current_user
    if current_user["id"] == user_id and (
        (body.role is not None and body.role != current_user["role"])
        or body.status == "disabled"
        or body.password is not None
    ):
        raise HTTPException(status_code=409, detail="不能降级、禁用或重置当前登录账号")

    result = update_user(
        user_id,
        display_name=body.display_name,
        role=body.role,
        status=body.status,
        password=body.password,
    )
    if result is None:
        raise HTTPException(status_code=404, detail="用户不存在")
    return result


@router.delete("/admin/users/{user_id}", status_code=204)
def admin_delete_user(user_id: int, request: Request) -> Response:
    if request.state.current_user["id"] == user_id:
        raise HTTPException(status_code=409, detail="不能删除当前登录账号")
    if not delete_user(user_id):
        raise HTTPException(status_code=404, detail="用户不存在")
    return Response(status_code=204)
