from fastapi import HTTPException, Request, status
from jose import jwt, JWTError
from src.config import settings
from datetime import datetime, timedelta
from src.models.user_schema import UserLogin, ResetPasswordRequest
import pytz
from src.db.mongodb import opts_collection, users_collection
from passlib.context import CryptContext
from fastapi.security import HTTPBearer

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
security = HTTPBearer()

def has_password(password: str):
    return pwd_context.hash(password)

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def create_access_token(data: dict):
    to_encode = data.copy()
    india_tz = pytz.timezone("Asia/Kolkata")
    now = datetime.now(india_tz)
    expire = now + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
    return encoded_jwt

def login(user: UserLogin):
    db_user = users_collection.find_one({"email": user.email})
    if not db_user or not verify_password(user.password, db_user["password"]):
        raise HTTPException(status_code=401, detail="Invalid email or password")

    token = create_access_token({"email": user.email})
    return {"access_token": token, "token_type": "bearer"}


async def verify_token(request: Request):
    auth_header = request.headers.get("Authorization")
    if not auth_header or not auth_header.startswith("Bearer "):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Missing or invalid Authorization header"
        )

    token = auth_header.split(" ")[1]
    try:
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
        email = payload.get("email")
        if not email:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Token payload missing email"
            )
        return {"email": email}
    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired token"
        )

def update_password(request: ResetPasswordRequest):
    try:
        result = opts_collection.find_one({"email": request.email})
        if not result:
            raise HTTPException(status_code=404, detail="Please sent OTP.")

        if not result["verified"]:
            raise HTTPException(status_code=400, detail="first need to verify otp.")
        
        hashed_pw = has_password(request.new_password)
        result = users_collection.update_one(
            {"email": request.email},
            {"$set": {"password": hashed_pw}}
        )
        opts_collection.delete_one({"email": request.email})
        return {"message": "Password reset successful"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error on reset password: {str(e)}")
        