from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from sqlalchemy.orm import Session from typing import List from datetime import datetime from app.core.database import get_db from app.core.security import decode_access_token, get_password_hash from app.models.user import User from app.schemas.admin import UserListResponse, UserUpdateRequest, PasswordChangeRequest router = APIRouter(prefix="/admin", tags=["admin"]) security = HTTPBearer() def get_current_superadmin( credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db) ) -> User: """Verifica se usuário é superadmin""" token = credentials.credentials payload = decode_access_token(token) if not payload: raise HTTPException(status_code=401, detail="Token inválido") user_id = payload.get("sub") user = db.query(User).filter(User.id == user_id).first() if not user or not user.is_superadmin: raise HTTPException( status_code=403, detail="Acesso negado. Apenas superadmin." ) return user @router.get("/users", response_model=List[UserListResponse]) async def list_all_users( admin: User = Depends(get_current_superadmin), db: Session = Depends(get_db) ): """Listar todos os usuários (apenas superadmin)""" users = db.query(User).order_by(User.created_at.desc()).all() return users @router.get("/stats") async def get_admin_stats( admin: User = Depends(get_current_superadmin), db: Session = Depends(get_db) ): """Estatísticas gerais do sistema""" from sqlalchemy import func from app.models.habit import Habit, HabitCompletion total_users = db.query(func.count(User.id)).scalar() active_users = db.query(func.count(User.id)).filter(User.is_active == True).scalar() total_habits = db.query(func.count(Habit.id)).scalar() total_completions = db.query(func.count(HabitCompletion.id)).scalar() return { "total_users": total_users, "active_users": active_users, "inactive_users": total_users - active_users, "total_habits": total_habits, "total_completions": total_completions } @router.patch("/users/{user_id}") async def update_user( user_id: str, data: UserUpdateRequest, admin: User = Depends(get_current_superadmin), db: Session = Depends(get_db) ): """Atualizar dados de usuário""" user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="Usuário não encontrado") # Atualizar campos if data.email is not None: # Verificar se email já existe existing = db.query(User).filter( User.email == data.email, User.id != user_id ).first() if existing: raise HTTPException(status_code=400, detail="Email já em uso") user.email = data.email if data.username is not None: # Verificar se username já existe existing = db.query(User).filter( User.username == data.username, User.id != user_id ).first() if existing: raise HTTPException(status_code=400, detail="Username já em uso") user.username = data.username if data.full_name is not None: user.full_name = data.full_name if data.is_active is not None: user.is_active = data.is_active if data.is_verified is not None: user.is_verified = data.is_verified db.commit() db.refresh(user) return {"message": "Usuário atualizado", "user": user} @router.delete("/users/{user_id}") async def delete_user( user_id: str, admin: User = Depends(get_current_superadmin), db: Session = Depends(get_db) ): """Deletar usuário (soft delete - apenas desativa)""" user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="Usuário não encontrado") if user.is_superadmin: raise HTTPException(status_code=403, detail="Não é possível deletar superadmin") user.is_active = False db.commit() return {"message": "Usuário desativado com sucesso"} @router.post("/users/{user_id}/reset-password") async def reset_user_password( user_id: str, data: PasswordChangeRequest, admin: User = Depends(get_current_superadmin), db: Session = Depends(get_db) ): """Resetar senha de usuário""" user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="Usuário não encontrado") user.password_hash = get_password_hash(data.new_password) db.commit() return {"message": "Senha alterada com sucesso"}