from fastapi import APIRouter, Depends, HTTPException, status from app.core.deps import get_current_user from app.core.supabase_client import supabase, supabase_admin from app.schemas.users import UserMe, UserUpdateMe, ChangePasswordIn router = APIRouter(prefix="/users", tags=["users"]) @router.get("/me", response_model=UserMe) def get_me(current_user: dict = Depends(get_current_user)): """Devuelve el perfil del usuario autenticado (datos públicos + email/phone de auth).""" user_id = current_user["user_id"] try: public_row = ( supabase_admin.table("users") .select("id, name, role, created_at") .eq("id", user_id) .maybe_single() .execute() ) public_data = public_row.data or {} except Exception as e: raise HTTPException(status_code=500, detail=f"Error al leer perfil: {e}") email = current_user.get("email") phone = None try: resp = supabase_admin.auth.admin.get_user_by_id(user_id) auth_user = getattr(resp, "user", None) or resp email = getattr(auth_user, "email", email) phone = getattr(auth_user, "phone", None) except Exception: pass return UserMe( id=user_id, email=email, phone=phone, name=public_data.get("name"), role=public_data.get("role") or current_user["role"], created_at=(public_data.get("created_at") and str(public_data["created_at"])) or None, ) @router.patch("/me", status_code=204) def update_me( body: UserUpdateMe, current_user: dict = Depends(get_current_user), ): """Actualiza nombre / email / teléfono del usuario autenticado.""" user_id = current_user["user_id"] if body.name is not None: try: supabase_admin.table("users").update({"name": body.name}).eq( "id", user_id ).execute() except Exception as e: raise HTTPException(status_code=500, detail=f"Error al actualizar nombre: {e}") auth_payload: dict = {} if body.email is not None: auth_payload["email"] = str(body.email) if body.phone is not None: auth_payload["phone"] = body.phone if auth_payload: try: supabase_admin.auth.admin.update_user_by_id(user_id, auth_payload) except Exception as e: raise HTTPException( status_code=500, detail=f"Error al actualizar credenciales: {e}" ) mirror: dict = {} if "email" in auth_payload: mirror["email"] = auth_payload["email"] if "phone" in auth_payload: mirror["phone"] = auth_payload["phone"] if mirror: try: supabase_admin.table("users").update(mirror).eq("id", user_id).execute() except Exception: pass return @router.post("/me/change-password", status_code=204) def change_password( body: ChangePasswordIn, current_user: dict = Depends(get_current_user), ): """Cambia la contraseña verificando primero la actual con signInWithPassword.""" if body.current_password == body.new_password: raise HTTPException( status_code=400, detail="La nueva contraseña debe ser distinta de la actual" ) email = current_user.get("email") if not email: raise HTTPException(status_code=400, detail="Usuario sin email asociado") try: supabase.auth.sign_in_with_password( {"email": email, "password": body.current_password} ) except Exception: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Contraseña actual incorrecta", ) try: supabase_admin.auth.admin.update_user_by_id( current_user["user_id"], {"password": body.new_password} ) except Exception as e: raise HTTPException( status_code=500, detail=f"Error al actualizar contraseña: {e}" ) return