"""Dependencies for API routes."""

from typing import Optional

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

from app.database import get_db
from app.models.admin_user import AdminRole, AdminUser
from app.models.user import User, UserType
from app.utils.security import verify_token

security = HTTPBearer(auto_error=False)


def get_current_admin(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
    db: Session = Depends(get_db),
) -> AdminUser:
    """Get the current authenticated admin user."""
    # Check if credentials were provided
    if credentials is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authorization header missing or invalid",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    token = credentials.credentials
    if not token:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Bearer token is empty",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    payload = verify_token(token)
    
    if not payload:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired token",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    user_id = payload.get("sub")
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token payload - missing user ID",
        )
    
    user = db.query(AdminUser).filter(AdminUser.id == user_id).first()
    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="Account is inactive. Contact support or an administrator.",
        )
    
    return user


def require_role(required_role: AdminRole):
    """Dependency to require a specific admin role."""
    def role_checker(current_admin: AdminUser = Depends(get_current_admin)) -> AdminUser:
        # Super admin has access to everything
        if current_admin.role == AdminRole.SUPER_ADMIN:
            return current_admin
        
        # Check if user has required role
        if current_admin.role != required_role:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail=f"Requires {required_role.value} role",
            )
        
        return current_admin
    
    return role_checker


def get_current_user(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
    db: Session = Depends(get_db),
):
    """Get the current authenticated user (any type - admin or regular user)."""
    # Check if credentials were provided
    if credentials is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authorization header missing or invalid",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    token = credentials.credentials
    if not token:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Bearer token is empty",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    payload = verify_token(token)
    
    if not payload:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired token",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    user_id = payload.get("sub")
    user_type = payload.get("user_type")
    
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token payload - missing user ID",
        )
    
    # Check if it's an admin user
    if user_type == "admin" or "role" in payload:
        user = db.query(AdminUser).filter(AdminUser.id == user_id).first()
        if user and user.is_active:
            return {"type": "admin", "user": user}
    
    # Check regular user
    user = db.query(User).filter(User.id == user_id).first()
    if not user or not user.is_active:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Account is inactive. Contact support or an administrator.",
        )
    
    return {"type": "user", "user": user}


def require_user_type(*allowed_types: UserType):
    """Dependency to require specific user types."""
    def type_checker(current_user_data: dict = Depends(get_current_user)):
        user_data = current_user_data
        
        # Admin users can access everything if needed
        if user_data.get("type") == "admin":
            admin_user = user_data.get("user")
            if admin_user.role == AdminRole.SUPER_ADMIN:
                return user_data
        
        # Check if user type matches
        if user_data.get("type") == "user":
            user = user_data.get("user")
            if user.user_type not in allowed_types:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=f"Access denied. Required user types: {[t.value for t in allowed_types]}"
                )
            return user_data
        
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Access denied for this user type"
        )
    
    return type_checker
