from fastapi import HTTPException
from app.modules.user.user_service import UserService
from app.modules.otp.otp_service import OtpService
from app.utils.jwt import create_access_token
import secrets


class UserController:

    def __init__(self):
        self.user_service = UserService()
        self.otp_service = OtpService()

    def generate_otp(self):
        return f"{secrets.randbelow(10000):04d}"

    async def register(self, request):
        try:
            otp = self.generate_otp()

            await self.otp_service.add_otp(
                phone=request.phone,
                otpCode=otp
            )

            return {
                "success": True,
                "message": "OTP sent to your phone"
            }

        except Exception as e:
            raise HTTPException(
                status_code=500,
                detail=str(e)
            )

    async def verify_otp(self, request):
        try:
            otp_record = await self.otp_service.get_active_otp_by_phone(
                request.phone
            )

            if not otp_record:
                raise HTTPException(
                    status_code=400,
                    detail="OTP not found"
                )

            if otp_record["otpCode"] != request.otpCode:
                raise HTTPException(
                    status_code=400,
                    detail="Invalid OTP"
                )

            existing_user = await self.user_service.get_user_by_phone(
                request.phone
            )

            if existing_user:
                raise HTTPException(
                    status_code=400,
                    detail="User already exists"
                )

            user = await self.user_service.register_user(
                request.phone,
                request.password
            )

            token = create_access_token({
                "phone": user["phone"],
                "_id": str(user["_id"])
            })

            await self.otp_service.expire_otp(
                str(otp_record["_id"])
            )

            return {
                "success": True,
                "message": "OTP verified successfully",
                "token_type": "Bearer",
                "access_token": token,
                "user": user
            }

        except HTTPException:
            raise

        except Exception as e:
            raise HTTPException(
                status_code=500,
                detail=f"Internal Server Error: {str(e)}"
            )
        
    async def login(self, request):
        try:
            result = await self.user_service.login_user(
                request.phone,
                request.password
            )

            if not result["success"]:
                raise HTTPException(
                    status_code=401,
                    detail=result["message"]
                )

            user = result["user"]

            token = create_access_token({
                "phone": user["phone"],
                "_id": str(user["_id"])
            })

            return {
                "success": True,
                "message": "Login successful",
                "token_type": "Bearer",
                "access_token": token,
                "user": {
                    "_id": str(user["_id"]),
                    "phone": user["phone"]
                }
            }

        except Exception as e:
            raise HTTPException(
                status_code=500,
                detail=f"Internal Server Error: {str(e)}"
            )