"""各俱乐部微信支付 V2（MD5）配置与验签。"""
import hashlib
import logging

from django.conf import settings

from jituan.constants import CLUB_ID_DEFAULT
from jituan.models import Club

logger = logging.getLogger(__name__)


def get_wechat_v2_config(club_id=None):
    """
    小程序 JSAPI 支付 V2 配置。
    多 club 时读 club 表；缺省或 xq 回落 settings（现网不变）。
    """
    cid = (club_id or '').strip() or CLUB_ID_DEFAULT
    fallback = {
        'appid': getattr(settings, 'WEIXIN_APPID', ''),
        'mch_id': getattr(settings, 'WEIXIN_MCHID', ''),
        'key': getattr(settings, 'WEIXIN_SHANGHUMIYAO', ''),
        'club_id': CLUB_ID_DEFAULT,
    }
    if cid == CLUB_ID_DEFAULT:
        return fallback

    try:
        club = Club.query.get(club_id=cid)
    except Club.DoesNotExist:
        logger.warning('club %s 不存在，回落全局支付配置', cid)
        return fallback

    cfg_json = club.config_json or {}
    mch_key = (
        cfg_json.get('mch_key')
        or cfg_json.get('shanghumiyao')
        or cfg_json.get('WEIXIN_SHANGHUMIYAO')
        or fallback['key']
    )
    return {
        'appid': club.pay_app_id or club.wx_appid or fallback['appid'],
        'mch_id': club.mch_id or fallback['mch_id'],
        'key': mch_key,
        'club_id': cid,
    }


def verify_wechat_v2_signature(xml_data, club_id=None):
    """验证微信 V2 支付回调 MD5 签名。"""
    try:
        import defusedxml.ElementTree as ET
        root = ET.fromstring(xml_data)
        sign_node = root.find('sign')
        if sign_node is None or not sign_node.text:
            return False
        sign = sign_node.text
        data = {child.tag: child.text for child in root if child.tag != 'sign'}
        string_a = '&'.join([f'{k}={data[k]}' for k in sorted(data.keys()) if data[k]])
        pay_cfg = get_wechat_v2_config(club_id)
        calc = hashlib.md5(f'{string_a}&key={pay_cfg["key"]}'.encode('utf-8')).hexdigest().upper()
        if calc == sign:
            return True
        # 兼容：子 club 未配密钥时尝试全局密钥
        global_key = getattr(settings, 'WEIXIN_SHANGHUMIYAO', '')
        if global_key and global_key != pay_cfg['key']:
            calc2 = hashlib.md5(f'{string_a}&key={global_key}'.encode('utf-8')).hexdigest().upper()
            return calc2 == sign
        return False
    except Exception as e:
        logger.error('微信验签异常: %s', e)
        return False


def club_id_from_czjilu(dingdan_id):
    from products.models import Czjilu
    try:
        row = Czjilu.query.filter(dingdan_id=dingdan_id).first()
        if row and getattr(row, 'club_id', None):
            return row.club_id
    except Exception:
        pass
    return CLUB_ID_DEFAULT


def club_id_from_order(order_id):
    from orders.models import Order
    try:
        row = Order.query.filter(OrderID=order_id).first()
        if row and getattr(row, 'ClubID', None):
            return row.ClubID
    except Exception:
        pass
    return CLUB_ID_DEFAULT


def get_wechat_v3_config(club_id=None):
    """
    微信 V3（转账/查单）配置。
    多 club 读 club 表；缺省或 xq 回落 settings.WECHAT_PAY_V3_CONFIG。
    """
    cid = (club_id or '').strip() or CLUB_ID_DEFAULT
    wx = dict(getattr(settings, 'WECHAT_PAY_V3_CONFIG', {}) or {})
    fallback = {
        'APPID': wx.get('APPID', ''),
        'MCHID': wx.get('MCHID', ''),
        'PRIVATE_KEY_PATH': wx.get('PRIVATE_KEY_PATH', ''),
        'CERT_SERIAL_NO': wx.get('CERT_SERIAL_NO', ''),
        'API_V3_KEY': wx.get('API_V3_KEY', ''),
        'PLATFORM_CERT_DIR': wx.get('PLATFORM_CERT_DIR', ''),
        'TRANSFER_SCENE_ID': wx.get('TRANSFER_SCENE_ID', '1005'),
        'club_id': CLUB_ID_DEFAULT,
    }
    if cid == CLUB_ID_DEFAULT:
        return fallback

    try:
        club = Club.query.get(club_id=cid)
    except Club.DoesNotExist:
        logger.warning('club %s 不存在，回落全局 V3 支付配置', cid)
        return fallback

    cfg_json = club.config_json or {}
    return {
        'APPID': club.pay_app_id or club.wx_appid or fallback['APPID'],
        'MCHID': club.mch_id or fallback['MCHID'],
        'PRIVATE_KEY_PATH': (
            club.private_key_path
            or cfg_json.get('private_key_path')
            or fallback['PRIVATE_KEY_PATH']
        ),
        'CERT_SERIAL_NO': (
            club.cert_serial_no
            or cfg_json.get('cert_serial_no')
            or fallback['CERT_SERIAL_NO']
        ),
        'API_V3_KEY': (
            club.api_v3_key
            or cfg_json.get('api_v3_key')
            or fallback['API_V3_KEY']
        ),
        'PLATFORM_CERT_DIR': (
            club.platform_cert_dir
            or cfg_json.get('platform_cert_dir')
            or fallback['PLATFORM_CERT_DIR']
        ),
        'TRANSFER_SCENE_ID': (
            cfg_json.get('transfer_scene_id')
            or cfg_json.get('TRANSFER_SCENE_ID')
            or fallback['TRANSFER_SCENE_ID']
        ),
        'club_id': cid,
    }


def club_id_for_tixian_yonghuid(yonghuid):
    from jituan.services.club_user import get_user_club_id
    from users.business_models import User
    user = User.query.filter(UserUID=yonghuid).first()
    return get_user_club_id(user)
