from fastapi import Depends

from app.core.config import settings
from app.core.security import get_current_user
from shared.exceptions import ForbiddenError

_ADMINS = {"platform_admin", "tenant_owner", "tenant_admin"}


def user_has_permission(user, permission: str) -> bool:
    roles = set(user.roles)
    if roles & _ADMINS or "payment.*" in roles:
        return True
    if permission in roles:
        return True
    parts = permission.split(".")
    return len(parts) >= 3 and f"{parts[0]}.{parts[1]}.manage" in roles


def require_permissions(*permissions: str):
    async def dependency(user=Depends(get_current_user)):
        if not settings.auth_required or any(
            user_has_permission(user, permission) for permission in permissions
        ):
            return user
        raise ForbiddenError(
            "Permission denied",
            error_code="permission_denied",
            details={"required": list(permissions)},
        )

    return dependency


async def require_payment_access(user=Depends(get_current_user)):
    if not settings.auth_required:
        return user
    roles = set(user.roles)
    if roles & _ADMINS or any(role.startswith("payment.") for role in roles):
        return user
    raise ForbiddenError("Permission denied", error_code="permission_denied")
