"""邀请码 / 邀请链俱乐部隔离。"""
import logging

from jituan.models import UserWxOpenid
from jituan.services.club_resolver import resolve_club_id_for_wechat_request
from jituan.services.club_user import resolve_invite_party_club

logger = logging.getLogger(__name__)


def _invitee_has_club_binding(user, club_id):
    uid = getattr(user, 'UserUID', None)
    if not uid or not club_id:
        return False
    return UserWxOpenid.query.filter(yonghuid=uid, club_id=club_id).exists()


def assert_invite_same_club(request, inviter_user, invitee_user=None):
    """
    校验邀请人与被邀请人属于同一俱乐部，且与请求 club 一致。
    未归属俱乐部的被邀请人允许在本小程序完成首次注册。
    返回 (ok, message)
    """
    club_id = resolve_club_id_for_wechat_request(request)
    inviter_club = resolve_invite_party_club(inviter_user, club_id)
    if inviter_club is None:
        # 管事未落库 ClubID/绑定时，以当前小程序为准（星之界扫码邀请常见）
        inviter_club = club_id
    if inviter_club != club_id:
        logger.warning(
            'invite_guard 管事俱乐部不符 inviter=%s inviter_club=%s req_club=%s',
            getattr(inviter_user, 'UserUID', '?'), inviter_club, club_id,
        )
        # 文案带上两侧 club，方便排查「种子 ClubID ≠ 小程序 X-Club-Id」
        return False, (
            f'邀请码不属于当前小程序俱乐部'
            f'（邀请人归属={inviter_club or "空"}，当前小程序={club_id or "空"}）'
        )

    if invitee_user is not None:
        invitee_club = resolve_invite_party_club(invitee_user, club_id)
        if invitee_club is not None and invitee_club != club_id:
            # 仅在「管事码也不属于当前小程序」且「用户已绑定别俱乐部 wx」时拒绝
            if (
                inviter_club != club_id
                and _invitee_has_club_binding(invitee_user, invitee_club)
                and not _invitee_has_club_binding(invitee_user, club_id)
            ):
                logger.warning(
                    'invite_guard 被邀请人俱乐部不符 invitee=%s invitee_club=%s req_club=%s',
                    getattr(invitee_user, 'UserUID', '?'), invitee_club, club_id,
                )
                return False, '您的账号归属与当前小程序不一致，请使用对应俱乐部小程序'
        # 管事码已证明属于当前小程序时，允许老 xq 账号在 xzj 完成注册（注册后写 ClubID）

    return True, ''
