from jose import jwt
from datetime import datetime, timedelta
from typing import Dict, Optional
from fastapi.security import OAuth2PasswordBearer
from fastapi import Depends, HTTPException
from ..db.dependency import get_db
from motor.motor_asyncio import AsyncIOMotorDatabase
from .http_return_helper import returnException,returnSuccess
# from your_project.database import get_db 


# Your existing constants
SECRET_KEY = "contec@#6892025"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_HOURS = 1  # Default expiry time for the token


# OAuth2 password bearer for extracting token
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")


# Single function that decodes the token and returns the user data
async def check_valid_token(token: str = Depends(oauth2_scheme),db: AsyncIOMotorDatabase = Depends(get_db)) -> Dict:
    try:
        # If authentication is required, check if the token is missing
        is_auth_required=True
        if is_auth_required:
        # Decode the token
            payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
            username: str = payload.get("sub")  # 'sub' contains the username

            if username is None:
                return returnException("Token is invalid or expired")
            
            # Fetch user from MongoDB
            users_collection = db["users"]
            user = await users_collection.find_one({"username": username})
            username: str = payload.get("sub")  # Get username (sub field)
            email: str = payload.get("email")
            role: str = payload.get("role")
            status: str = payload.get("status")
           
            user_data = {
                "token": token,
                "username": username,
                "email": email,
                "role": role,
                "status": status
            }

            return user_data
        else:
            # If authentication is not required, return mock data or skip checks
            return {
                "token": "mock_token",  # Mock token or a default value
                "username": "test_user",  # Mock username
                "email": "test@gmail.com",# Mock email
                "role": "admin",  # Mock role
                "status": "active"  # Mock status
            }

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Internal Server Error: {str(e)}")


def create_access_token(user: dict, expires_delta: Optional[timedelta] = None) -> str:
    # Prepare data to include in the token, excluding sensitive info like password
    to_encode = {
        "sub": user["username"],  
        "email": user["email"],
        "role": user["role"],
        "status": user["status"],
        "created_on": user["created_on"].isoformat(),  
        "exp": datetime.utcnow() + (expires_delta if expires_delta else timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS)),
    }

    # Generate and return the JWT token
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt