import logging from typing import Optional from datetime import datetime, timedelta from fastapi import APIRouter, HTTPException, Query, Depends, status, Body from fastapi.responses import JSONResponse #from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer #from jose import JWTError, jwt from app.services.customer_services import get_otp_from_cache, validate_email_mobile, verify_otp_and_save_customer from app.models.customer import CustomerRegister # Initialize router and logger router = APIRouter(prefix="/customer") logger = logging.getLogger(__name__) @router.post("/register") async def register_customer(user: CustomerRegister = Body(...)): """ API endpoint to register a new customer. Args: user (CustomerRegister): The details of the customer to register. Returns: dict: Confirmation message indicating email and SMS verification pending. """ try: logger.info("Registering a new customer with email: %s and mobile: %s", user.email, user.mobile) # Validate email and mobile format validation_result = await validate_email_mobile(user.email, user.mobile) if validation_result["status"] == "error": logger.error("Validation failed: %s", validation_result["errors"]) raise HTTPException(status_code=400, detail=validation_result["errors"]) return user.dict() except HTTPException as e: logger.error("Failed to register customer: %s", e.detail) raise e except Exception as e: logger.error("Unexpected error while registering customer: %s", e) raise HTTPException(status_code=500, detail="Failed to register customer") from e @router.post("/otp/verify") async def customer_otp_verification(user: CustomerRegister = Body(...)): """ API endpoint to validate OTPs and save the complete customer object. Args: user (CustomerRegister): The complete customer object including email, mobile, and OTPs. Returns: dict: Confirmation message indicating success or failure. """ try: logger.info("Verifying OTPs and registering customer with email: %s and mobile: %s", user.email, user.mobile) # Verify OTPs and save customer result = await verify_otp_and_save_customer(user) if result["status"] == "error": raise HTTPException(status_code=400, detail=result["errors"]) return {"message": "Customer successfully registered and verified."} except HTTPException as e: logger.error("Failed to verify and register customer: %s", e.detail) raise e except Exception as e: logger.error("Unexpected error while verifying and registering customer: %s", e) raise HTTPException(status_code=500, detail="Failed to verify and register customer") from e @router.get("/otp/get") async def get_otps(key: str = Query(..., description="The email or mobile number to retrieve the OTP for")): """ API endpoint to retrieve the email or SMS OTP from Redis cache. Args: key (str): The email or mobile number to retrieve the OTP for. Returns: dict: The OTP data if found, or an error message if not found. """ try: logger.info("Retrieving OTP for key: %s", key) # Retrieve OTP from Redis otp_data = await get_otp_from_cache(key) if not otp_data: raise HTTPException(status_code=404, detail="OTP not found or expired") return {"key": key, "otp_data": otp_data} except HTTPException as e: logger.error("Failed to retrieve OTP for key %s: %s", key, e.detail) raise e except Exception as e: logger.error("Unexpected error while retrieving OTP for key %s: %s", key, e) raise HTTPException(status_code=500, detail="Failed to retrieve OTP") from e