"""
Authentication utilities for password hashing and JWT token management.
"""

import logging
from datetime import datetime, timedelta
from typing import Optional

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

from config import settings

logger = logging.getLogger(__name__)

# Password hashing context
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """Verify password against its hash."""
    try:
        result = pwd_context.verify(plain_password, hashed_password)
        logger.debug("🔐 Password verification completed")
        return result
    except Exception as e:
        logger.error(f"❌ Password verification error: {e}")
        return False


def get_password_hash(password: str) -> str:
    """Generate password hash."""
    try:
        hashed = pwd_context.hash(password)
        logger.debug("🔐 Password hash created successfully")
        return hashed
    except Exception as e:
        logger.error(f"❌ Password hashing error: {e}")
        raise


def create_access_token(
    data: dict, 
    expires_delta: Optional[timedelta] = None
) -> str:
    """Create JWT access token."""
    try:
        to_encode = data.copy()
        
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(
                minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
            )
        
        to_encode.update({"exp": expire})
        encoded_jwt = jwt.encode(
            to_encode, 
            settings.SECRET_KEY, 
            algorithm=settings.ALGORITHM
        )
        
        user_id = data.get('sub', 'unknown')
        logger.debug(f"🎫 JWT token created for user ID: {user_id}")
        return encoded_jwt
        
    except Exception as e:
        logger.error(f"❌ JWT token creation error: {e}")
        raise


def verify_token(token: str) -> Optional[dict]:
    """Verify and decode JWT token."""
    try:
        payload = jwt.decode(
            token, 
            settings.SECRET_KEY, 
            algorithms=[settings.ALGORITHM]
        )
        user_id = payload.get('sub', 'unknown')
        logger.debug(f"✅ JWT token valid for user ID: {user_id}")
        return payload
        
    except JWTError as e:
        logger.warning(f"❌ Invalid JWT token: {e}")
        return None
    except Exception as e:
        logger.error(f"❌ Unexpected JWT token verification error: {e}")
        return None


def get_token_expiration() -> datetime:
    """Get token expiration time."""
    expiration = datetime.utcnow() + timedelta(
        minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
    )
    logger.debug(f"⏰ Token expiration time: {expiration}")
    return expiration 