from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session

from app.database import get_db
from app.dependencies import require_admin_token
from app.models import User, UserRole
from app.schemas import Message, UpdateUserRequest, UserCreate, UserIdRequest, UserPublic
from app.security import hash_password

router = APIRouter(prefix="/users", tags=["admin-users"])


def _fetch_users(db: Session, skip: int, limit: int) -> list[User]:
    return db.query(User).order_by(User.id).offset(skip).limit(limit).all()


@router.get(
    "/list-users",
    response_model=list[UserPublic],
    summary="List users (paginated)",
)
@router.get(
    "/get-all-users",
    response_model=list[UserPublic],
    summary="Get all users (paginated, same as list-users)",
)
def list_users(
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=500),
):
    return _fetch_users(db, skip, limit)


@router.get(
    "/get-user",
    response_model=UserPublic,
    summary="Get one user by id (query: user_id)",
)
@router.get(
    "/get-user-data",
    response_model=UserPublic,
    summary="Get one user by id (query: user_id, alias)",
)
def get_user(
    user_id: int = Query(..., ge=1, description="User primary key"),
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    u = db.get(User, user_id)
    if not u:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    return u


@router.post("/create-user", response_model=UserPublic, status_code=status.HTTP_201_CREATED)
def create_user(body: UserCreate, db: Session = Depends(get_db), _: User = Depends(require_admin_token)):
    if db.query(User).filter(User.email == body.email).first():
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Email already registered")
    u = User(
        email=str(body.email),
        full_name=body.full_name,
        hashed_password=hash_password(body.password),
        role=UserRole.admin if body.role.value == "admin" else UserRole.user,
        is_active=body.is_active,
    )
    db.add(u)
    db.commit()
    db.refresh(u)
    return u


@router.post("/update-user", response_model=UserPublic)
def update_user(
    body: UpdateUserRequest,
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    u = db.get(User, body.user_id)
    if not u:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    if body.email is not None and body.email != u.email:
        if db.query(User).filter(User.email == body.email).first():
            raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Email in use")
        u.email = str(body.email)
    if body.full_name is not None:
        u.full_name = body.full_name
    if body.is_active is not None:
        u.is_active = body.is_active
    if body.password:
        u.hashed_password = hash_password(body.password)
    if body.role is not None:
        u.role = UserRole.admin if body.role.value == "admin" else UserRole.user
    db.commit()
    db.refresh(u)
    return u


@router.post("/delete-user", response_model=Message)
def delete_user(body: UserIdRequest, db: Session = Depends(get_db), admin: User = Depends(require_admin_token)):
    if body.user_id == admin.id:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot delete yourself")
    u = db.get(User, body.user_id)
    if not u:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    db.delete(u)
    db.commit()
    return Message(message="User deleted")
