from typing import List from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from sqlalchemy import func from app.db.session import get_db from app.core.deps import get_current_admin_user, get_current_super_admin_user from app.core.security import get_password_hash from app.models.user import User, UserRole from app.models.gym import Gym from app.models.membership import GymMembership from app.models.subscription import Subscription from app.models.transaction import Transaction, TransactionStatus from app.schemas.user import User as UserSchema, AdminInvite router = APIRouter() @router.get("/users", response_model=List[UserSchema]) def get_all_users( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_admin_user), ): users = db.query(User).offset(skip).limit(limit).all() return users @router.get("/users/{user_id}", response_model=UserSchema) def get_user_by_id( user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_admin_user), ): user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") return user @router.get("/users/{user_id}/subscriptions") def get_user_subscriptions( user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_admin_user), ): user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") subscriptions = db.query(Subscription).filter(Subscription.user_id == user_id).all() return subscriptions @router.get("/users/{user_id}/transactions") def get_user_transactions( user_id: int, db: Session = Depends(get_db), current_user: User = Depends( get_current_super_admin_user ), # Only super admin can view financial data ): user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") transactions = db.query(Transaction).filter(Transaction.user_id == user_id).all() return transactions @router.get("/stats/overview") def get_overview_stats( db: Session = Depends(get_db), current_user: User = Depends(get_current_admin_user) ): total_users = ( db.query(func.count(User.id)).filter(User.role == UserRole.USER).scalar() ) total_gyms = db.query(func.count(Gym.id)).filter(Gym.is_active).scalar() total_memberships = db.query(func.count(GymMembership.id)).scalar() active_subscriptions = ( db.query(func.count(Subscription.id)) .filter(Subscription.status == "active") .scalar() ) return { "total_users": total_users, "total_gyms": total_gyms, "total_memberships": total_memberships, "active_subscriptions": active_subscriptions, } @router.get("/stats/financial") def get_financial_stats( db: Session = Depends(get_db), current_user: User = Depends( get_current_super_admin_user ), # Only super admin can view financial data ): total_revenue = ( db.query(func.sum(Transaction.amount)) .filter(Transaction.status == TransactionStatus.COMPLETED) .scalar() or 0 ) pending_revenue = ( db.query(func.sum(Transaction.amount)) .filter(Transaction.status == TransactionStatus.PENDING) .scalar() or 0 ) failed_transactions = ( db.query(func.count(Transaction.id)) .filter(Transaction.status == TransactionStatus.FAILED) .scalar() ) return { "total_revenue": total_revenue, "pending_revenue": pending_revenue, "failed_transactions": failed_transactions, } @router.get("/transactions") def get_all_transactions( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends( get_current_super_admin_user ), # Only super admin can view all transactions ): transactions = db.query(Transaction).offset(skip).limit(limit).all() return transactions @router.post("/invite-admin") def invite_admin( admin_data: AdminInvite, db: Session = Depends(get_db), current_user: User = Depends( get_current_super_admin_user ), # Only super admin can invite admins ): existing_user = db.query(User).filter(User.email == admin_data.email).first() if existing_user: raise HTTPException( status_code=400, detail="User with this email already exists" ) if admin_data.role == UserRole.SUPER_ADMIN: raise HTTPException(status_code=400, detail="Cannot invite super admin") # Generate a temporary password (in production, send via email) temp_password = ( "TempPass123!" # In production, generate random password and send via email ) hashed_password = get_password_hash(temp_password) new_admin = User( email=admin_data.email, full_name=admin_data.full_name, role=admin_data.role, hashed_password=hashed_password, invited_by=current_user.id, ) db.add(new_admin) db.commit() db.refresh(new_admin) return { "message": "Admin invited successfully", "admin_id": new_admin.id, "temporary_password": temp_password, # In production, don't return this } @router.delete("/remove-admin/{admin_id}") def remove_admin( admin_id: int, db: Session = Depends(get_db), current_user: User = Depends( get_current_super_admin_user ), # Only super admin can remove admins ): admin = ( db.query(User) .filter( User.id == admin_id, User.role.in_([UserRole.ADMIN, UserRole.SUPER_ADMIN]) ) .first() ) if not admin: raise HTTPException(status_code=404, detail="Admin not found") if admin.role == UserRole.SUPER_ADMIN: raise HTTPException(status_code=400, detail="Cannot remove super admin") admin.is_active = False db.commit() return {"message": "Admin removed successfully"} @router.get("/admins") def get_all_admins( db: Session = Depends(get_db), current_user: User = Depends(get_current_super_admin_user), ): admins = ( db.query(User) .filter(User.role.in_([UserRole.ADMIN, UserRole.SUPER_ADMIN])) .all() ) return admins