"""czjilu 充值类型常量与查询辅助（避免罚款与商家充值混用 leixing=4）。"""
from django.conf import settings
from django.db.models import Q

# 与 czjilu.leixing 一致
CZJILU_LEIXING_HUIYUAN = 1
CZJILU_LEIXING_YAJIN = 2
CZJILU_LEIXING_JIFEN = 3
CZJILU_LEIXING_SHANGJIA = 4
CZJILU_LEIXING_KAOHE = 5
CZJILU_LEIXING_FAKUAN = 6
CZJILU_LEIXING_ZHUANPAN = 7  # 转盘购票（履约只写抽奖机会，不进抢单池）

ZHUANPAN_ORDER_PREFIX = 'CzZP'

CZJILU_PAID_STATUS = 3
# 用户取消/关闭：保留流水，不物理删除；若官方已付款，回调/查单仍可履约入账（防少加）
CZJILU_CANCELLED_STATUS = 2
CZJILU_PENDING_STATUS = 9
# 可被「官方已付款」触发履约的状态（仅这些会入账，已付 3 不会再加 → 防多加）
CZJILU_FULFILLABLE_STATUSES = (CZJILU_PENDING_STATUS, CZJILU_CANCELLED_STATUS)

FAKUAN_ORDER_PREFIX = 'FK'
PENALTY_SHUOMING_MARKER = '罚款'
PENALTY_FADAN_TAG = '#fadan:'


def penalty_cz_shuoming(fadan_id):
    """罚款微信支付/抵扣流水说明（含罚单 ID 便于对账）。"""
    desc = getattr(settings, 'FAKUAN_PAY_DESCRIPTION', '罚款缴纳')
    return f'{desc}{PENALTY_FADAN_TAG}{fadan_id}'


def is_legacy_penalty_leixing4(cz):
    """历史误写 leixing=4 的罚款流水。"""
    dingdan = (getattr(cz, 'dingdan_id', None) or '').strip()
    shuoming = (getattr(cz, 'shuoming', None) or '')
    if dingdan.startswith(FAKUAN_ORDER_PREFIX):
        return True
    if PENALTY_SHUOMING_MARKER in shuoming:
        return True
    if PENALTY_FADAN_TAG in shuoming:
        return True
    return False


def is_penalty_czjilu(cz):
    leixing = getattr(cz, 'leixing', None)
    if leixing == CZJILU_LEIXING_FAKUAN:
        return True
    if leixing == CZJILU_LEIXING_SHANGJIA:
        return is_legacy_penalty_leixing4(cz)
    return False


def is_merchant_recharge_czjilu(cz):
    return (
        getattr(cz, 'leixing', None) == CZJILU_LEIXING_SHANGJIA
        and not is_legacy_penalty_leixing4(cz)
    )


def exclude_penalty_from_cz_qs(qs):
    """从 czjilu 查询中排除罚款流水（含历史 leixing=4 误标）。"""
    return qs.exclude(
        Q(leixing=CZJILU_LEIXING_FAKUAN)
        | Q(leixing=CZJILU_LEIXING_SHANGJIA, dingdan_id__startswith=FAKUAN_ORDER_PREFIX)
        | Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_SHUOMING_MARKER)
        | Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_FADAN_TAG)
    )


def merchant_recharge_cz_qs(qs):
    """仅真·商家余额充值（微信 CzSJ… 或 leixing=4 且非罚款）。"""
    prefix = getattr(settings, 'SHANGJIA_CZ_PREFIX', 'CzSJ')
    return exclude_penalty_from_cz_qs(qs).filter(
        leixing=CZJILU_LEIXING_SHANGJIA,
        dingdan_id__startswith=prefix,
    )


def penalty_payment_cz_qs(qs):
    """罚款支付流水（微信 FK… 或 leixing=6 / 历史误标）。"""
    return qs.filter(
        Q(leixing=CZJILU_LEIXING_FAKUAN)
        | Q(leixing=CZJILU_LEIXING_SHANGJIA, dingdan_id__startswith=FAKUAN_ORDER_PREFIX)
        | Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_SHUOMING_MARKER)
        | Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_FADAN_TAG)
    )


def is_czjilu_fulfillable_status(zhuangtai):
    """是否允许在确认官方已付款后执行履约（9 待付 / 2 用户取消但仍可能已扣款）。"""
    try:
        return int(zhuangtai) in CZJILU_FULFILLABLE_STATUSES
    except (TypeError, ValueError):
        return False


def close_unpaid_czjilu(order, reason='用户取消支付'):
    """
    关闭未支付充值单：只改状态为取消(2)，绝不 delete。
    若用户其实已付款，后续回调/查单仍可通过 is_czjilu_fulfillable_status 履约。
    返回 True 表示本次从 9 改为 2。
    """
    if int(getattr(order, 'zhuangtai', 0) or 0) != CZJILU_PENDING_STATUS:
        return False
    note = (getattr(order, 'shuoming', None) or '').strip()
    tag = f'|关单:{reason}'
    if tag not in note:
        merged = f'{note}{tag}' if note else f'关单:{reason}'
        order.shuoming = merged[:100]
    order.zhuangtai = CZJILU_CANCELLED_STATUS
    order.save(update_fields=['zhuangtai', 'shuoming'])
    return True


def looks_like_czjilu_out_trade_no(out_trade_no):
    """粗判商户订单号是否为 Czjilu 充值单（避免打进老板订单回调后被 success 吞掉）。"""
    s = (out_trade_no or '').strip()
    if not s:
        return False
    prefixes = (
        'CzHY', 'CzYJ', 'CzJF', 'CzSJ', 'KH', 'FK', 'CzZP',
        getattr(settings, 'SHANGJIA_CZ_PREFIX', 'CzSJ') or 'CzSJ',
        ZHUANPAN_ORDER_PREFIX,
    )
    return any(s.startswith(p) for p in prefixes if p)
