from fastapi import APIRouter, Depends, status, HTTPException from sqlalchemy.orm import Session from app.db.session import get_db from app.services.auth_service import AuthService from app.schemas.user import UserCreate from app.schemas.auth import ( LoginRequest, UserLoginRequest, EmployeeLoginRequest, TokenResponse, UserTokenResponse, EmployeeTokenResponse, RefreshTokenRequest, RefreshTokenResponse, CurrentUser ) from app.core.dependencies import get_current_user, get_current_user_optional from app.core.exceptions import AuthException import logging logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v1/auth", tags=["authentication"]) @router.post("/login") def login(login_request: LoginRequest, db: Session = Depends(get_db)): """ Universal login endpoint Supports both user (email) and employee (EmployeeID) authentication. - Set auth_type to "user" for email-based login - Set auth_type to "employee" for EmployeeID-based login - Set auth_type to "auto" (default) to auto-detect based on username format """ service = AuthService(db) try: result = service.authenticate_user( login_request.username, login_request.password ) return result except AuthException as e: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e)) @router.post("/refresh", response_model=RefreshTokenResponse) def refresh_access_token(refresh_request: RefreshTokenRequest, db: Session = Depends(get_db)): """ Refresh access token Generate a new access token using a valid refresh token. """ service = AuthService(db) try: result = service.refresh_token(refresh_request.refresh_token) return RefreshTokenResponse(**result) except AuthException as e: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e)) @router.get("/me", response_model=CurrentUser) def get_me(current_user: CurrentUser = Depends(get_current_user)): """ Get current user information Returns details about the currently authenticated user or employee. """ return current_user @router.post("/logout") def logout(): """ Logout endpoint Since JWTs are stateless, logout is handled on the client side by discarding tokens. This endpoint exists for API completeness and could be extended to maintain a blacklist of revoked tokens if needed. """ return {"message": "Successfully logged out"} @router.get("/validate") def validate_token(current_user: CurrentUser = Depends(get_current_user_optional)): """ Token validation endpoint Validates if the provided token is valid and returns user information. Returns null if no token or invalid token. """ if current_user: return {"valid": True, "user": current_user} else: return {"valid": False, "user": None}