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

from genovation_advanced_auth.core.security import decode_token
from genovation_advanced_auth.core.config import get_config
from genovation_advanced_auth.exceptions import TokenExpiredError, InvalidTokenError
from genovation_advanced_auth.services.user_service import UserService

# HTTP Bearer token security
security = HTTPBearer(auto_error=False)


def get_current_user(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
) -> dict:
    """
    Get current authenticated user from JWT token.
    Uses global config from .env for token verification.
    
    Note: For v0.1.0, this validates token only. Database lookup removed for simplicity.
    """
    if credentials is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not authenticated",
            headers={"WWW-Authenticate": "Bearer"}
        )
    
    token = credentials.credentials
    config = get_config()
    
    try:
        payload = decode_token(
            token,
            secret_key=config.secret_key,
            algorithm=config.algorithm
        )
        
        user_id = payload.get("sub")
        username = payload.get("username")
        
        if user_id is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Could not validate credentials"
            )
        
        return {
            "id": int(user_id),
            "username": username,
            "is_superuser": payload.get("is_superuser", False)
        }
        
    except TokenExpiredError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Token has expired",
            headers={"WWW-Authenticate": "Bearer"}
        )
    except InvalidTokenError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token",
            headers={"WWW-Authenticate": "Bearer"}
        )


# Optional: For users who need database lookup
def get_current_user_with_db(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
    db: Session = None  # User must provide get_db dependency
) -> dict:
    """
    Get current user with database verification.
    Users must provide their own get_db dependency.
    """
    if credentials is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not authenticated"
        )
    
    token = credentials.credentials
    config = get_config()
    
    try:
        payload = decode_token(token, secret_key=config.secret_key, algorithm=config.algorithm)
        user_id = int(payload.get("sub"))
        
        if db:
            user_service = UserService(db)
            user = user_service.get_user_by_id(user_id)
            
            if not user:
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="User not found"
                )
            
            if not user.is_active:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="User account is disabled"
                )
            
            return {
                "id": user.id,
                "username": user.username,
                "is_superuser": user.is_superuser
            }
        
        return {
            "id": user_id,
            "username": payload.get("username")
        }
        
    except (TokenExpiredError, InvalidTokenError):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired token"
        )
