from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app import crud, models, schemas, security
from app.database import get_db


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


@router.post("/register", response_model=schemas.UserRead, status_code=status.HTTP_201_CREATED)
def register(user_in:schemas.UserCreate, db:Session = Depends(get_db)) -> models.User:
    """Register a new user."""
    if crud.get_user_by_username(db, user_in.username):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Username already registered")
    if crud.get_user_by_email(db, user_in.email):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Email already registered")
    return crud.create_user(db, user_in.username, user_in.email, security.get_password_hash(user_in.password))


@router.post("/token", response_model=schemas.Token)
def login_for_access_token(form_data:OAuth2PasswordRequestForm = Depends(), db:Session = Depends(get_db)) -> schemas.Token:
    """Authenticate a user and return a JWT access token."""
    user = security.authenticate_user(db, form_data.username, form_data.password)
    if user is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token = security.create_access_token(data={"sub": user.username})
    return schemas.Token(access_token=access_token)


@router.get("/me", response_model=schemas.UserRead)
def read_users_me(current_user:models.User = Depends(security.get_current_active_user)) -> models.User:
    """Return the currently authenticated user."""
    return current_user


@router.get("/users", response_model=list[schemas.UserRead])
def list_users(
    db:Session = Depends(get_db),
    _current_user:models.User = Depends(security.get_current_admin_user),
    ) -> list[models.User]:
    """Return all registered users. Admin-only."""
    return crud.get_users(db)
