from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select
from sqlalchemy.orm import Session

from app.db.session import get_db
from app.models.org import User
from app.schemas.database import (
    AuthChangePasswordRequest,
    AuthLoginRequest,
    AuthResetPasswordRequest,
    AuthSession,
    LoginUser,
)
from app.services.auth import (
    build_login_user,
    get_current_auth_context,
    hash_password,
    login_with_password,
    require_system_admin,
    verify_password,
)

router = APIRouter()


@router.post("/login", response_model=AuthSession)
def login(payload: AuthLoginRequest, db: Session = Depends(get_db)) -> AuthSession:
    return login_with_password(db, payload.username, payload.password)


@router.get("/me", response_model=LoginUser)
def profile(context=Depends(get_current_auth_context)) -> LoginUser:
    return build_login_user(context)


@router.post("/password/change")
def change_password(
    payload: AuthChangePasswordRequest,
    context=Depends(get_current_auth_context),
    db: Session = Depends(get_db),
) -> dict[str, str]:
    user = db.get(User, context.user.id)
    if not user:
        raise HTTPException(status_code=404, detail="当前用户不存在")
    if not verify_password(payload.old_password, user.password_hash):
        raise HTTPException(status_code=400, detail="原密码不正确")
    if verify_password(payload.new_password, user.password_hash):
        raise HTTPException(status_code=400, detail="新密码不能与原密码相同")

    user.password_hash = hash_password(payload.new_password)
    db.add(user)
    db.commit()
    return {"message": "密码已修改"}


@router.post("/password/reset")
def reset_password(
    payload: AuthResetPasswordRequest,
    context=Depends(require_system_admin),
    db: Session = Depends(get_db),
) -> dict[str, str]:
    user = db.scalar(select(User).where(User.username == payload.username))
    if not user:
        raise HTTPException(status_code=404, detail="账号不存在")

    user.password_hash = hash_password(payload.new_password)
    db.add(user)
    db.commit()
    return {"message": f"账号 {payload.username} 密码已重置"}
