#auth_controller.py
from fastapi import Depends, HTTPException, Security
from sqlalchemy.orm import Session
from src.utils.db import get_db
from src.apps.auth.services import verify_password, decode_access_token
from src.apps.users.models import User
from fastapi.security import OAuth2PasswordBearer
from src.apps.auth.services import validate_reset_token_entry
from src.apps.auth.schemas import ForgotPasswordRequest, PasswordResetResponse, PasswordReset
from src.apps.auth.services import generate_reset_token_entry, send_reset_email, verify_reset_token
from src.apps.auth.services import hash_password
from src.apps.auth.models import UserSession


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")


def get_current_user(token: str = Security(oauth2_scheme), db: Session = Depends(get_db)):
    """Retrieve the current user based on the JWT token."""
    
    payload = decode_access_token(token)
    if not payload:
        raise HTTPException(
            status_code=401,
            detail={"status": False, "code": 401, "message": "Invalid token"}
        )

    # ✅ Check if token exists in session
    session_exists = db.query(UserSession).filter(UserSession.token == token).first()
    if not session_exists:
        raise HTTPException(
            status_code=401,
            detail={"status": False, "code": 401, "message": "Invalid or expired session"}
        )

    user = db.query(User).filter(User.email == payload["sub"]).first()
    if not user:
        raise HTTPException(
            status_code=401,
            detail={"status": False, "code": 401, "message": "User not found"}
        )

    return user



def get_current_admin(user: User = Depends(get_current_user)):
    """Ensure that the user is an admin."""
    if user.role != "admin":
        raise HTTPException(status_code=403, detail="Admins only")
    return user



####################################################################################################




# Controller function to handle the forgot password request
async def forgot_password(request: ForgotPasswordRequest, db: Session = Depends(get_db)) -> PasswordResetResponse:
    # Check if user exists based on provided email
    user = db.query(User).filter(User.email == request.email).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Generate and store reset token
    reset_token = generate_reset_token_entry(user.user_id, db)

    # Debug: Print the generated token
    print(f"Generated reset token: {reset_token.token}")  # <-- Check this in console
    
    # Construct reset link
    reset_link = f"http://localhost:8000/reset-password?token={reset_token.token}"
    print(f"Password Reset Link: {reset_link}")  # <-- Also check this in console

    # Send email (if applicable)
    try:
        send_reset_email(user.email, reset_link)
    except Exception as e:
        raise HTTPException(status_code=500, detail="Failed to send reset email")

    return PasswordResetResponse(message="Password reset link has been sent to your email.")



# Controller function to handle the reset password request
async def reset_password(request: PasswordReset, db: Session = Depends(get_db)) -> PasswordResetResponse:
    # Validate the provided reset token
    reset_token = validate_reset_token_entry(request.token, db)
    if not reset_token:
        # If the token is invalid or expired, raise an error
        raise HTTPException(status_code=400, detail="Invalid or expired reset token")
    
    # Find the user using the user ID from the reset token
    user = db.query(User).filter(User.id == request.user_id).first()
    if not user:
        # If the user is not found, raise an error
        raise HTTPException(status_code=404, detail="User not found")
    
    # Hash the new password and update the user's password
    hashed_password = hash_password(request.new_password)
    user.password = hashed_password
    db.commit()

    # Return a success response
    return PasswordResetResponse(message="Your password has been reset successfully.")

