"""JWT authentication utilities."""
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from passlib.context import CryptContext
from shared.config import settings
from shared.schemas import TokenData

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


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """Verify a password against its hash.
    
    Args:
        plain_password: Plain text password
        hashed_password: Hashed password
        
    Returns:
        True if password matches
    """
    return pwd_context.verify(plain_password, hashed_password)


def get_password_hash(password: str) -> str:
    """Hash a password.
    
    Args:
        password: Plain text password
        
    Returns:
        Hashed password
    """
    return pwd_context.hash(password)


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
    """Create JWT access token.
    
    Args:
        data: Data to encode in token
        expires_delta: Token expiration time
        
    Returns:
        Encoded JWT token
    """
    to_encode = data.copy()
    
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(hours=settings.jwt_expiration_hours)
    
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.jwt_secret, algorithm=settings.jwt_algorithm)
    
    return encoded_jwt


def verify_token(token: str) -> Optional[TokenData]:
    """Verify and decode JWT token.
    
    Args:
        token: JWT token to verify
        
    Returns:
        TokenData if valid, None otherwise
    """
    try:
        payload = jwt.decode(token, settings.jwt_secret, algorithms=[settings.jwt_algorithm])
        user_id: str = payload.get("sub")
        
        if user_id is None:
            return None
            
        return TokenData(user_id=user_id)
    except JWTError:
        return None


def generate_api_key() -> str:
    """Generate a random API key.
    
    Returns:
        API key string
    """
    import secrets
    return f"ak_{secrets.token_urlsafe(32)}"


def create_refresh_token() -> str:
    """Generate a secure refresh token.
    
    Returns:
        Refresh token string
    """
    import secrets
    return secrets.token_urlsafe(64)


def verify_refresh_token(token: str, stored_token: str, expires_at: datetime, is_revoked: bool) -> bool:
    """Verify a refresh token.
    
    Args:
        token: Token to verify
        stored_token: Stored token hash
        expires_at: Token expiration time
        is_revoked: Whether token is revoked
        
    Returns:
        True if valid
    """
    if is_revoked:
        return False
    
    if datetime.utcnow() > expires_at:
        return False
    
    return token == stored_token
