from jose import JWTError, jwt
from datetime import datetime, timedelta
from passlib.context import CryptContext

SECRET_KEY = "super-secret-key-change-this"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60

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


# -------------------
# SAFE PASSWORD HANDLING
# -------------------

def _safe_password(password: str) -> bytes:
    # Encode to UTF-8 and truncate to 72 bytes (hard bcrypt limit)
    # Returns bytes directly — no decode step, so re-encoding can never exceed 72 bytes
    return str(password).encode("utf-8")[:72]


# -------------------
# Password Hashing
# -------------------

def hash_password(password: str):
    b = _safe_password(password)
    return pwd_context.hash(b)          # passlib accepts bytes directly


def verify_password(plain: str, hashed: str):
    b = _safe_password(plain)
    return pwd_context.verify(b, hashed)  # passlib accepts bytes directly


# -------------------
# JWT Token
# -------------------

def create_access_token(data: dict):
    to_encode = data.copy()

    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})

    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)


def verify_token(token: str):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        return payload
    except JWTError:
        return None