"""集团后台管理员俱乐部上下文。"""
from jituan.constants import (
    ADMIN_ROLE_LABELS,
    DATA_SCOPE_ALL,
    DATA_SCOPE_SINGLE,
    CLUB_ID_DEFAULT,
    SUPER_ADMIN_PHONES,
)
from jituan.models import AdminAssignment, Club

GROUP_MANAGE_ROLES = frozenset({
    'GROUP_OWNER',
    'GROUP_SUPER_ADMIN',
})


def get_allowed_club_ids(user):
    """用户可切换/访问的子公司 club_id 集合（不含集团汇总）。"""
    if is_system_super_admin(user):
        return {c.club_id for c in Club.query.filter(status=1)}
    assignments = AdminAssignment.query.filter(yonghuid=user.UserUID, status=1)
    has_group = assignments.filter(
        club_id__isnull=True
    ).exists() or assignments.filter(data_scope=DATA_SCOPE_ALL).exists()
    if has_group:
        return {c.club_id for c in Club.query.filter(status=1)}
    allowed = {
        a.club_id for a in assignments if a.club_id
    }
    if not allowed:
        cid = (getattr(user, 'ClubID', None) or '').strip()
        if cid:
            allowed = {cid}
    return allowed


def resolve_admin_effective_club(user, request):
    """
    校验后台用户请求的俱乐部/范围，返回 (club_id, scope, error_msg)。
    无权限访问请求的俱乐部时，回退到主任职俱乐部（避免 localStorage 脏数据串俱乐部）。
    """
    from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope

    requested_club = resolve_club_id_from_request(request)
    requested_scope = resolve_club_scope(request)

    if is_system_super_admin(user):
        return requested_club, requested_scope, None

    ctx = build_admin_club_context(user)
    allowed = get_allowed_club_ids(user)

    if requested_scope == DATA_SCOPE_ALL:
        if not ctx.get('is_group_admin'):
            primary = ctx.get('club_id') or CLUB_ID_DEFAULT
            return primary, DATA_SCOPE_SINGLE, None
        return ctx.get('club_id') or CLUB_ID_DEFAULT, DATA_SCOPE_ALL, None

    if requested_club not in allowed:
        primary = ctx.get('club_id') or CLUB_ID_DEFAULT
        return primary, DATA_SCOPE_SINGLE, None

    return requested_club, DATA_SCOPE_SINGLE, None


def build_admin_club_context(user):
    """
    根据 admin_assignment + 超管推断后台登录后的俱乐部上下文。
    返回 dict 供前端存储与请求头使用。
    """
    yonghuid = user.UserUID
    is_super = is_system_super_admin(user)

    assignments = list(
        AdminAssignment.query.filter(yonghuid=yonghuid, status=1).order_by('-is_primary', 'club_id')
    )

    clubs_qs = Club.query.filter(status=1).order_by('sort_order', 'club_id')
    all_clubs = [
        {'club_id': c.club_id, 'name': c.name}
        for c in clubs_qs
    ]

    # 系统超管：始终集团视角 + 全部俱乐部（不受任职记录限制）
    if is_super:
        role_code = 'GROUP_SUPER_ADMIN'
        if assignments:
            primary = next((a for a in assignments if a.is_primary), assignments[0])
            role_code = primary.role_code or role_code
        return _pack(
            scope=DATA_SCOPE_ALL,
            club_id=CLUB_ID_DEFAULT,
            is_group_admin=True,
            assignments=assignments,
            clubs=all_clubs,
            can_switch_club=True,
            role_code=role_code,
            role_name=ADMIN_ROLE_LABELS.get(role_code, role_code),
        )

    if not assignments:
        allowed_ids = get_allowed_club_ids(user)
        visible_clubs = [c for c in all_clubs if c['club_id'] in allowed_ids]
        club_id = next(iter(allowed_ids), CLUB_ID_DEFAULT) if allowed_ids else CLUB_ID_DEFAULT
        return _pack(
            scope=DATA_SCOPE_SINGLE,
            club_id=club_id,
            is_group_admin=False,
            assignments=[],
            clubs=visible_clubs,
            can_switch_club=len(visible_clubs) > 1,
            role_code='CLUB_ADMIN',
            role_name='子公司客服（默认）',
        )

    primary = next((a for a in assignments if a.is_primary), assignments[0])
    has_group = any(
        a.club_id is None or a.data_scope == DATA_SCOPE_ALL
        for a in assignments
    )
    allowed_ids = get_allowed_club_ids(user)

    if has_group:
        scope = DATA_SCOPE_ALL
        club_id = CLUB_ID_DEFAULT
        visible_clubs = all_clubs
    else:
        scope = DATA_SCOPE_SINGLE
        primary_cid = primary.club_id or CLUB_ID_DEFAULT
        if primary_cid in allowed_ids:
            club_id = primary_cid
        elif allowed_ids:
            club_id = sorted(allowed_ids)[0]
        else:
            club_id = primary_cid
        visible_clubs = [c for c in all_clubs if c['club_id'] in allowed_ids]

    role_code = primary.role_code or 'CLUB_ADMIN'
    return _pack(
        scope=scope,
        club_id=club_id,
        is_group_admin=has_group,
        assignments=assignments,
        clubs=visible_clubs,
        can_switch_club=has_group or len(visible_clubs) > 1,
        role_code=role_code,
        role_name=ADMIN_ROLE_LABELS.get(role_code, role_code),
    )


def is_system_super_admin(user):
    """
    系统级超管。
    白名单手机号：始终超管。
    其它账号：仅看 IsSuperuser / UserType=admin；停用集团任职时会清掉 IsSuperuser，
    避免「任职停了仍是集团上帝」。
    """
    if getattr(user, 'Phone', '') in SUPER_ADMIN_PHONES:
        return True
    return bool(user.IsSuperuser) or user.UserType == 'admin'


def is_hardcoded_super_phone(user):
    """仅代码白名单手机号（不可被后台「禁用」锁死本人）。"""
    return getattr(user, 'Phone', '') in SUPER_ADMIN_PHONES


def is_kefu_account_disabled(user):
    """
    客服扩展表已禁用。
    非白名单账号：即使挂了 IsSuperuser 也必须认 zhuangtai（否则后台点禁用等于摆设）。
    """
    if is_hardcoded_super_phone(user):
        return False
    try:
        kefu = user.KefuProfile
    except Exception:
        return False
    return int(getattr(kefu, 'zhuangtai', 1) or 0) != 1


def is_kefu_backend_account(user):
    """可登录客服后台：超管 / UserType=kefu / 有正常 KefuProfile。"""
    if is_kefu_account_disabled(user):
        return False
    if is_system_super_admin(user):
        return True
    if getattr(user, 'UserType', '') == 'kefu':
        return True
    try:
        return user.KefuProfile.zhuangtai == 1
    except Exception:
        return False


def can_manage_admin_assignments(user, permissions=None):
    """是否可维护数据范围任职、俱乐部密钥等集团级配置（不含俱乐部 000001）。"""
    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
    return any(
        a.role_code in GROUP_MANAGE_ROLES
        and (a.club_id is None or a.data_scope == DATA_SCOPE_ALL)
        for a in AdminAssignment.query.filter(yonghuid=user.UserUID, status=1)
    )


def get_switchable_club_ids(user):
    """顶栏可切换俱乐部：有任职/数据范围即可切换；菜单按当前俱乐部功能角色展示。"""
    return get_allowed_club_ids(user)


def can_manage_roles_for_club(user, permissions, club_id):
    """
    是否可为指定俱乐部分配/移除功能角色、添加本店后台用户。
    集团高层：全部俱乐部；否则须在该俱乐部拥有 000001 超级管理（不必有集团权限）。
    """
    if can_manage_admin_assignments(user, permissions):
        return True
    cid = (club_id or '').strip()
    if not cid:
        return False
    from jituan.constants import DATA_SCOPE_SINGLE
    from jituan.services.club_rbac import resolve_effective_permission_codes
    # 与菜单/verify_kefu 同一套：含 legacy，避免「页面能进但添加按钮出不来」
    codes = resolve_effective_permission_codes(user, cid, DATA_SCOPE_SINGLE)
    return '000001' in (codes or [])


def get_manageable_club_ids(user, permissions=None, current_club_id=None):
    """
    当前操作者可管理角色/后台用户的俱乐部集合。
    current_club_id：若请求上下文已带 000001，务必把当前顶栏俱乐部算进去。
    """
    if can_manage_admin_assignments(user, permissions):
        return {c.club_id for c in Club.query.filter(status=1)}
    ids = {
        c.club_id for c in Club.query.filter(status=1)
        if can_manage_roles_for_club(user, permissions, c.club_id)
    }
    cid = (current_club_id or '').strip()
    if cid and permissions and '000001' in permissions:
        ids.add(cid)
    return ids


def can_access_admin_user_management(user, permissions=None):
    """
    是否可访问「后台用户」页（列表、按俱乐部分配功能角色）。
    系统超管 / 000001 / 集团高管 / 任一俱乐部超管均可。
    """
    if is_system_super_admin(user):
        return True
    if permissions and '000001' in permissions:
        return True
    if can_manage_admin_assignments(user, permissions):
        return True
    return bool(get_manageable_club_ids(user, permissions))


def _pack(scope, club_id, is_group_admin, assignments, clubs, can_switch_club,
          role_code, role_name):
    allowed_club_ids = sorted({
        c['club_id'] for c in clubs if c.get('club_id')
    })
    return {
        'scope': scope,
        'club_id': club_id,
        'is_group_admin': is_group_admin,
        'role_code': role_code,
        'role_name': role_name,
        'allowed_club_ids': allowed_club_ids,
        'perm_source': 'gvsdsdk',
        'perm_note': (
            '【功能权限】在「角色管理」为各俱乐部创建角色，在「管理员用户」绑定；'
            '切换俱乐部后菜单按该俱乐部角色生效。'
            '【数据范围】在本页添加任职，可分配多个俱乐部，无需集团权限即可切换。'
        ),
        'assignments': [
            {
                'club_id': a.club_id,
                'role_code': a.role_code,
                'role_name': ADMIN_ROLE_LABELS.get(a.role_code, a.role_code),
                'data_scope': a.data_scope,
                'is_primary': a.is_primary,
            }
            for a in assignments
        ],
        'clubs': clubs,
        'can_switch_club': can_switch_club,
    }
