"""
FastAPI dependencies for authentication and authorization.
"""

import logging
from typing import Optional

from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.orm import Session

from auth_utils import verify_token
from database import get_db
from models import User

logger = logging.getLogger(__name__)

# Bearer token scheme
security = HTTPBearer()


def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    db: Session = Depends(get_db)
) -> User:
    """Get current user from JWT token."""
    token = credentials.credentials
    payload = verify_token(token)
    
    if payload is None:
        logger.warning("❌ Access attempt with invalid token")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    user_id: Optional[int] = payload.get("sub")
    if user_id is None:
        logger.warning("❌ Access attempt with token without user_id")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        logger.warning(f"❌ Access attempt by non-existent user ID: {user_id}")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not found",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    logger.debug(f"🔍 User authenticated: {user.email} (ID: {user.id})")
    return user


def get_current_admin_user(current_user: User = Depends(get_current_user)) -> User:
    """Get current user, ensuring they are an admin."""
    if current_user.user_type != "admin":
        logger.warning(
            f"❌ Admin function access attempt by user: {current_user.email} "
            f"(type: {current_user.user_type})"
        )
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Access denied. Administrator privileges required"
        )
    
    logger.info(f"👑 Admin access: {current_user.email} (ID: {current_user.id})")
    return current_user 