"""集团/俱乐部资金处置权限。

加余额（及同类增加资金）：
- 系统超管 / 集团高管（GROUP_OWNER、GROUP_SUPER_ADMIN）：可按数据范围操作
- 当前俱乐部超级管理 000001：仅限 SINGLE_CLUB 本店，且目标用户必须属于当前俱乐部
不再强制「仅集团高管才能加余额」。

提现审核：权限码 005bb 或本店超级管理 000001 + 按俱乐部隔离——
- 子公司视图：持有 005bb/000001 且任职含当前俱乐部 → 可审本俱乐部
- 集团汇总视图 / 跨俱乐部：须集团资金处置权
不再强制「必须集团权限才能审本店提现」。
"""
from django.db.models import Q

from jituan.constants import DATA_SCOPE_ALL
from jituan.models import AdminAssignment
from jituan.services.admin_context import (
    GROUP_MANAGE_ROLES,
    build_admin_club_context,
    get_allowed_club_ids,
    is_system_super_admin,
)

MSG_GROUP_FINANCE_REQUIRED = '该操作仅集团高管可执行（需在数据范围配置中为集团级任职）'
MSG_BALANCE_ADD_DENIED = (
    '无权加余额：需当前俱乐部超级管理权限（000001），或集团高管任职；'
    '且仅能操作当前俱乐部用户'
)
MSG_BALANCE_ADD_CROSS_CLUB = '跨俱乐部加余额仅集团高管可执行，请切换到具体俱乐部后再操作'
MSG_BALANCE_ADD_CLUB_DENIED = '无权在该俱乐部加余额'
MSG_WITHDRAW_CROSS_CLUB = '跨俱乐部提现审核仅集团高管可执行，请切换到具体俱乐部后再操作'
MSG_WITHDRAW_CLUB_DENIED = '无权审核该俱乐部提现'


def has_group_finance_exec(user, request=None):
    """系统超管 / 集团任职（GROUP_OWNER、GROUP_SUPER_ADMIN）。"""
    if is_system_super_admin(user):
        return True
    ctx = build_admin_club_context(user)
    if ctx.get('is_group_admin') and ctx.get('role_code') in GROUP_MANAGE_ROLES:
        return True
    uid = getattr(user, 'UserUID', None)
    if not uid:
        return False
    return AdminAssignment.query.filter(
        yonghuid=uid,
        status=1,
        role_code__in=GROUP_MANAGE_ROLES,
    ).filter(
        Q(club_id__isnull=True) | Q(data_scope=DATA_SCOPE_ALL),
    ).exists()


def deny_group_finance_exec(user, request=None):
    """仅集团高管（旧闸门，保留给非加余额场景如需）。"""
    from rest_framework.response import Response
    if has_group_finance_exec(user, request):
        return None
    return Response({'code': 403, 'msg': MSG_GROUP_FINANCE_REQUIRED})


def deny_balance_add_exec(request, *, permissions=None, target_user=None):
    """
    加余额 / 加押金 / 增加可提现等「资金增加」闸门。

    放行条件（满足其一）：
    1) 系统超管或集团高管
    2) 当前请求权限含俱乐部超级管理 000001，且为 SINGLE_CLUB，
       当前俱乐部在任职范围内

    无论哪种身份：若传入 target_user，必须属于当前请求俱乐部数据范围
    （集团 ALL_CLUBS 视图下目标校验放行，见 forbid_if_user_out_of_scope）。
    """
    from rest_framework.response import Response
    from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope
    from jituan.services.club_user_access import forbid_if_user_out_of_scope

    user = getattr(request, 'user', None)
    perms = permissions or []

    if has_group_finance_exec(user, request):
        if target_user is not None:
            denied = forbid_if_user_out_of_scope(request, target_user)
            if denied:
                return denied
        return None

    if '000001' not in perms:
        return Response({'code': 403, 'msg': MSG_BALANCE_ADD_DENIED})

    scope = resolve_club_scope(request)
    if scope == DATA_SCOPE_ALL:
        return Response({'code': 403, 'msg': MSG_BALANCE_ADD_CROSS_CLUB})

    club_id = resolve_club_id_from_request(request)
    allowed = get_allowed_club_ids(user)
    if not club_id or club_id not in allowed:
        return Response({'code': 403, 'msg': MSG_BALANCE_ADD_CLUB_DENIED})

    if target_user is not None:
        denied = forbid_if_user_out_of_scope(request, target_user)
        if denied:
            return denied

    return None


def require_withdraw_audit_access(request, phone):
    """
    提现审核访问：
    1) 权限码 005bb，或本店超级管理 000001
    2) 集团高管：可在 ALL_CLUBS 或任意子公司视图操作
    3) 俱乐部侧：仅 SINGLE_CLUB 且当前 club 在其任职范围内（只能审本店）
    """
    from backend.utils import has_club_super_perm, verify_kefu_permission
    from rest_framework.response import Response
    from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope

    kefu, permissions = verify_kefu_permission(request, phone)
    if kefu is None:
        return None, permissions
    if '005bb' not in permissions and not has_club_super_perm(permissions):
        return None, Response({'code': 403, 'msg': '您无权操作提现审核（需要 005bb 或本店超级管理 000001）'})

    if has_group_finance_exec(request.user, request):
        return kefu, None

    scope = resolve_club_scope(request)
    if scope == DATA_SCOPE_ALL:
        return None, Response({'code': 403, 'msg': MSG_WITHDRAW_CROSS_CLUB})

    club_id = resolve_club_id_from_request(request)
    allowed = get_allowed_club_ids(request.user)
    if not club_id or club_id not in allowed:
        return None, Response({'code': 403, 'msg': MSG_WITHDRAW_CLUB_DENIED})

    return kefu, None
