"""users.views.tixian - auto-generated by split script."""
import os
import sys
import json
import re
import time
import uuid
import random
import string
import requests
import hashlib
import traceback
import decimal
import jwt
import ipaddress
import xmltodict
from datetime import datetime, timedelta
from decimal import Decimal
import defusedxml.ElementTree as ET

from django.conf import settings
from django.db import models, transaction, IntegrityError, DatabaseError, connection
from django.db.models import Q, F, Sum, Count, Case, When, IntegerField, Prefetch
from django.core.cache import cache
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.http import HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.hashers import make_password

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions, status
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.throttling import AnonRateThrottle
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.authentication import JWTAuthentication

from gvsdsdk.fluent import db, func, FQ

from utils.oss_utils import validate_image, upload_to_oss, delete_from_oss
from utils.money import yuan_to_fen
from utils.fadan_utils import check_fadan_qiangdan_eligible
from utils.invitationcode_utils import CreateInvitationCode, VerifyInvitationCode
from users.fadan_fenhong_utils import process_fadan_fenhong

from orders.utils import (
    update_daily_payout,
    settle_shangjia_order_guanshi_fenhong
)
from backend.utils import (
    update_dashou_daily_by_action, update_guanshi_daily_by_action,
    update_shangjia_daily, update_zuzhang_daily_by_action,
    verify_kefu_permission
)
from rank.utils import get_tag_fee, create_shenhe_jilu, validate_shenheguan

from ..models import (
    UserBoss, UserDashou, UserShangjia, UserGuanshi,
    UserZuzhang, UserKefu, AdminProfile, OfficialAccountUser,
    TixianAutoRecord, TixianShenheJilu, Tixianjilu, Xiugaijilu,
    RankingRecord
)
from users.business_models import User
from ..tixian_shenhe_services import (
    load_audit_meta_map, refund_balance, sync_audit_and_jilu_status,
    mark_transfer_success, release_collect_quota_for_record,
    close_audit_wechat_failed, query_wechat_transfer_bill,
    _mark_transfer_attempt_failed, club_id_for_tixian_yonghuid,
    check_shijidaozhang_within_limit,
    check_dashou_has_formal_huiyuan_for_withdraw,
    check_dashou_trial_blocks_commission_withdraw,
    validate_withdraw_eligibility,
    validate_payment_info_for_withdraw,
    WX_STATE_FAIL, WX_STATE_SUCCESS, WX_STATE_WAIT, WX_STATE_CANCELING,
)
from ..tixian_shenhe_views import process_audit_collect

from orders.models import (
    Order, PlatformOrderExt, MerchantOrderExt, CommissionRate,
    PenaltyRecord, PenaltyEvidenceImage, RefundRecord, PlayerDeliveryImage,
    Penalty, PenaltyAppealImage
)
from products.models import (
    ShangpinLeixing, Huiyuan, Huiyuangoumai, Gsfenhong, Czjilu
)
from config.models import Qunpeizhi
from backend.models import MerchantDailyStats
from rank.models import (
    KaohePayTemp, Chenghao, ShenheJilu,
    KaoheCishuFeiyong, YonghuChenghao
)
from users.models import UserShenheguan
from products.utils import update_shangpin_daily_stat
from shop.utils import update_dianpu_daily_stat
from rank.utils import create_shenhe_jilu_from_temp

import logging

logger = logging.getLogger(__name__)

class TixianXinxiHuoquView(APIView):
    """
    获取用户提现收款信息接口
    返回用户已设置的手机号、收款码、收款账号
    """
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        """
        处理获取收款信息的POST请求
        直接返回用户当前的收款设置
        """
        try:
            # 从request.user获取当前用户
            user_main = request.user

            from jituan.services.club_user import get_user_club_id
            from jituan.services.withdraw_config import get_tixian_feilv

            club_id = get_user_club_id(user_main)
            dashou_rate = get_tixian_feilv(club_id, 1)
            guanshi_rate = get_tixian_feilv(club_id, 2)

            # 构建返回数据
            response_data = {
                'txdianhua': user_main.Phone if user_main.Phone else '',
                'txtupian': user_main.PaymentQRCode if user_main.PaymentQRCode else '',
                'txzh': user_main.PaymentAccount if user_main.PaymentAccount else '',
                'dashou_rate': dashou_rate,
                'guanshi_rate': guanshi_rate,
            }

            # 返回成功响应
            return Response({
                'code': 0,
                'msg': '获取成功',
                'data': response_data
            })

        except Exception as e:
            return Response({
                'code': 99,
                'msg': f'系统错误: {str(e)}',
                'data': None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class ShoukuanXinxiShangchuanView(APIView):
    """
    上传用户收款信息接口
    支持同时上传手机号、收款账号、收款码图片
    使用multipart/form-data格式
    """
    permission_classes = [permissions.IsAuthenticated]
    parser_classes = (MultiPartParser,FormParser,JSONParser)

    def post(self, request):
        """
        处理上传收款信息的POST请求
        验证并保存用户的收款设置
        """
        try:
            # 获取当前用户
            user_main = request.user
            yonghuid = user_main.UserUID

            # 准备响应数据
            response_data = {}

            # 1. 验证必填字段：手机号必须要有
            txdianhua = request.data.get('txdianhua', '').strip()
            if not txdianhua:
                return Response({
                    'code': 1,
                    'msg': '收款人电话不能为空',
                    'data': None
                }, status=status.HTTP_400_BAD_REQUEST)

            # 验证手机号格式（11位数字）
            if not txdianhua.isdigit() or len(txdianhua) != 11:
                return Response({
                    'code': 2,
                    'msg': '请输入11位有效的手机号码',
                    'data': None
                }, status=status.HTTP_400_BAD_REQUEST)

            # 2. 获取收款账号（可能为空）
            txzh = request.data.get('txzh', '').strip()

            # 3. 处理收款码图片上传（如果有）
            txtupian_file = request.FILES.get('file')  # 注意：前端upload.js使用'file'作为字段名
            txtupian_url = ''

            if txtupian_file:
                # 验证图片
                is_valid, error_msg = validate_image(txtupian_file)
                if not is_valid:
                    return Response({
                        'code': 3,
                        'msg': f'图片验证失败: {error_msg}',
                        'data': None
                    }, status=status.HTTP_400_BAD_REQUEST)

                # 上传收款码图片
                txtupian_url = self.handle_shoukuanma_upload(user_main, txtupian_file)
                if txtupian_url:
                    response_data['txtupian'] = txtupian_url
                else:
                    return Response({
                        'code': 4,
                        'msg': '收款码上传失败',
                        'data': None
                    }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            else:
                response_data['txtupian'] = ''

            # 4. 验证收款账号和收款码至少有一个
            if not txzh and not txtupian_url:
                return Response({
                    'code': 5,
                    'msg': '请填写收款账号或上传收款码',
                    'data': None
                }, status=status.HTTP_400_BAD_REQUEST)

            # 5. 保存所有信息到数据库
            with transaction.atomic():
                user_main.Phone = txdianhua
                user_main.PaymentAccount = txzh if txzh else ''

                # 只有上传了图片才更新zhifu字段
                if txtupian_url:
                    user_main.PaymentQRCode = txtupian_url

                user_main.save()

            # 6. 构建完整的返回数据
            response_data['txdianhua'] = txdianhua
            response_data['txzh'] = txzh if txzh else ''

            # 7. 返回成功响应
            return Response({
                'code': 0,
                'msg': '收款信息设置成功',
                'data': response_data
            })

        except Exception as e:
            traceback.print_exc()  # 打印详细错误信息到控制台
            return Response({
                'code': 99,
                'msg': f'系统错误: {str(e)}',
                'data': None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def handle_shoukuanma_upload(self, user_main, image_file):
        """
        处理收款码图片上传到腾讯云COS
        存储路径: tixian/{yonghuid}/{yonghuid}.扩展名
        """
        try:
            yonghuid = user_main.UserUID
            if not yonghuid:
                return None

            # 获取旧收款码URL
            old_shoukuanma_url = user_main.PaymentQRCode

            # 生成文件扩展名
            file_name = image_file.name
            file_extension = os.path.splitext(file_name)[1].lower()
            if not file_extension:
                file_extension = '.jpg'

            # 构建OSS文件路径: tixian/{yonghuid}/{yonghuid}{扩展名}
            # 使用用户ID作为文件名，确保同一用户多次上传会覆盖
            oss_file_name = f"{yonghuid}{file_extension}"
            oss_file_path = f"tixian/{yonghuid}/{oss_file_name}"

            # 删除旧收款码（如果存在）
            if old_shoukuanma_url and old_shoukuanma_url.strip():
                delete_from_oss(old_shoukuanma_url)

            # 上传新收款码到OSS
            new_shoukuanma_url = upload_to_oss(image_file, oss_file_path)

            if new_shoukuanma_url:
                # 返回相对路径（从tixian文件夹开始）
                return oss_file_path
            else:
                return None

        except Exception as e:
            print(f"处理收款码上传失败: {e}")
            return None


# ========== 订单状态常量（请根据您的实际业务修改）==========
# 假设状态值：已完成=9，已退款=10（示例，实际以您的项目为准）
ORDER_STATUS_COMPLETED = 3   # 订单已完成
ORDER_STATUS_REFUNDED = 5   # 订单已退款
ORDER_STATUS_FAIL = 6
# 进行中状态（不可提现）例如：待接单、已接单、进行中等，您需要定义排除列表
FORBIDDEN_STATUS_FOR_WITHDRAW = [1, 2, 3, 4, 5, 6, 7, 8]  # 除已完成和已退款外的所有状态


class TixianShenqingView(APIView):
    """
    用户提现申请接口（完整版）
    支持类型：
        1-打手佣金提现
        2-管事分红提现
        3-组长分红提现
        4-审核官分佣提现
        5-打手押金提现（退出平台）
        6-商家余额提现（退出平台）
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            user_main = request.user
            yonghuid = user_main.UserUID

            # 1. 获取并验证参数
            leixing = request.data.get('leixing')
            jine = request.data.get('jine')
            fangshi = request.data.get('fangshi')
            txskfs = request.data.get('txskfs', 0)

            # 罚单检查（共用）
            fadan_ok, fadan_msg = check_fadan_qiangdan_eligible(yonghuid, 2)
            if not fadan_ok:
                return Response({'code': 400, 'msg': fadan_msg})

            # 参数完整性
            missing = []
            if leixing is None: missing.append('leixing')
            if jine is None: missing.append('jine')
            if fangshi is None: missing.append('fangshi')
            if missing:
                return Response({'code': 1, 'msg': f'缺少参数: {", ".join(missing)}'},
                                status=status.HTTP_400_BAD_REQUEST)

            try:
                leixing = int(leixing)
                jine = decimal.Decimal(str(jine))
                fangshi = int(fangshi)
                txskfs = int(txskfs)
            except (ValueError, TypeError, decimal.InvalidOperation) as e:
                return Response({'code': 2, 'msg': f'参数格式错误: {str(e)}'},
                                status=status.HTTP_400_BAD_REQUEST)

            if jine <= decimal.Decimal('0'):
                return Response({'code': 3, 'msg': '提现金额必须大于0'},
                                status=status.HTTP_400_BAD_REQUEST)

            # 支持的提现类型（1-6）
            if leixing not in [1, 2, 3, 4, 5, 6]:
                return Response({'code': 4, 'msg': '无效的提现类型'},
                                status=status.HTTP_400_BAD_REQUEST)

            if fangshi not in [1, 2]:
                return Response({'code': 5, 'msg': '无效的收款方式，只能是1(微信)或2(支付宝)'},
                                status=status.HTTP_400_BAD_REQUEST)

            from jituan.services.club_user import get_user_club_id
            from jituan.services.withdraw_config import get_tixian_feilv

            club_id = get_user_club_id(user_main)
            current_rate = decimal.Decimal('0.00')
            rate_key = {
                1: '5',   # 打手佣金
                2: '6',   # 管事分红
                3: '8',   # 组长分红
                4: '9',   # 审核官分佣
                5: '11',  # 打手押金提现
                6: '10',  # 商家余额提现
            }.get(leixing)

            if rate_key:
                try:
                    current_rate = get_tixian_feilv(club_id, leixing)
                except ValueError:
                    return Response({'code': 41, 'msg': f'提现费率未配置（类型{leixing}）'},
                                    status=status.HTTP_400_BAD_REQUEST)

            shouxufei = jine * current_rate
            shijidaozhang = jine - shouxufei
            if shijidaozhang <= decimal.Decimal('0'):
                return Response({'code': 6, 'msg': '提现金额过低，扣除手续费后无实际到账'},
                                status=status.HTTP_400_BAD_REQUEST)

            pay_ok, pay_msg = validate_payment_info_for_withdraw(user_main)
            if not pay_ok:
                return Response({'code': 7, 'msg': pay_msg},
                                status=status.HTTP_400_BAD_REQUEST)

            ok, elig_msg, extra = validate_withdraw_eligibility(user_main, leixing, jine)
            if not ok:
                body = {'code': 8, 'msg': elig_msg}
                if (extra or {}).get('code') == 'COMPLAINT_BLOCK_WITHDRAW':
                    body['data'] = {
                        'tab': extra.get('tab') or 'received',
                        'reason': extra.get('reason') or '',
                        'count': extra.get('count') or 0,
                        'code': 'COMPLAINT_BLOCK_WITHDRAW',
                    }
                return Response(body, status=status.HTTP_400_BAD_REQUEST)

            # 3. 根据提现类型扣款（资格已在 validate_withdraw_eligibility 校验）
            nicheng = extra.get('nicheng', '')
            if leixing == 1:
                with transaction.atomic():
                    profile = UserDashou.objects.select_for_update().get(user=user_main)
                    if profile.yue < jine:
                        return Response({'code': 13, 'msg': '余额不足'})
                    profile.yue = F('yue') - jine
                    profile.save()
            elif leixing == 2:
                with transaction.atomic():
                    profile = UserGuanshi.objects.select_for_update().get(user=user_main)
                    if profile.yue < jine:
                        return Response({'code': 22, 'msg': '余额不足'})
                    profile.yue = F('yue') - jine
                    profile.save()
                nicheng = extra.get('nicheng') or '管事用户'
            elif leixing == 3:
                with transaction.atomic():
                    profile = UserZuzhang.objects.select_for_update().get(user=user_main)
                    if profile.ketixian_jine < jine:
                        return Response({'code': 32, 'msg': '可提现金额不足'})
                    profile.ketixian_jine = F('ketixian_jine') - jine
                    profile.save()
                nicheng = extra.get('nicheng') or ''
            elif leixing == 4:
                with transaction.atomic():
                    profile = UserShenheguan.objects.select_for_update().get(user=user_main)
                    if profile.yue < jine:
                        return Response({'code': 42, 'msg': '可提现金额不足'})
                    profile.yue = F('yue') - jine
                    profile.save()
                nicheng = extra.get('nicheng') or '审核官'
            elif leixing == 5:
                # 打手押金提现：仅扣押金，走审核流程，不再封禁账号
                with transaction.atomic():
                    profile = UserDashou.objects.select_for_update().get(user=user_main)
                    if profile.yajin < jine:
                        return Response({'code': 53, 'msg': '押金余额不足'})
                    profile.yajin = F('yajin') - jine
                    profile.save(update_fields=['yajin'])
                nicheng = extra.get('nicheng') or profile.nicheng or ''
            elif leixing == 6:
                with transaction.atomic():
                    profile = UserShangjia.objects.select_for_update().get(user=user_main)
                    if profile.yue < jine:
                        return Response({'code': 63, 'msg': '商家余额不足'})
                    profile.yue = F('yue') - jine
                    profile.save()
                nicheng = extra.get('nicheng') or profile.nicheng or ''

            # 4. 创建提现记录（先扣款后创建，确保资金安全）
            try:
                avatar = user_main.Avatar or ''
                phone = user_main.Phone or ''
                zhifu = user_main.PaymentQRCode or ''
                skzhanghao = user_main.PaymentAccount or ''
                from jituan.services.club_user import get_user_club_id
                tixian_record = Tixianjilu.query.create(
                    club_id=get_user_club_id(user_main),
                    yonghuid=yonghuid,
                    avatar=avatar,
                    phone=phone,
                    nicheng=nicheng,
                    leixing=leixing,
                    zhifu=zhifu,
                    skzhanghao=skzhanghao,
                    jine=shijidaozhang,      # 记录实际到账金额
                    zhuangtai=1,              # 审核中
                    fangshi=fangshi,
                    shenheid=None,
                    bhliyou='',
                )
            except Exception as e:
                return Response({'code': 99, 'msg': f'创建提现记录失败: {str(e)}'},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 5. 返回成功响应
            return Response({
                'code': 0,
                'msg': '提现申请提交成功',
                'data': {
                    'tixian_id': tixian_record.id,
                    'leixing': leixing,
                    'jine': str(jine.quantize(decimal.Decimal('0.01'))),
                    'fangshi': fangshi,
                    'zhuangtai': 1,
                    'CreateTime': tixian_record.CreateTime.strftime('%Y-%m-%d %H:%M:%S'),
                    'current_rate': str(current_rate.quantize(decimal.Decimal('0.0000'))),
                    'shouxufei': str(shouxufei.quantize(decimal.Decimal('0.01'))),
                    'shijidaozhang': str(shijidaozhang.quantize(decimal.Decimal('0.01'))),
                    'tip': f'本次提现手续费率{current_rate * 100}%，手续费{shouxufei}元，实际到账{shijidaozhang}元'
                }
            })

        except Exception as e:
            traceback.print_exc()
            return Response({'code': 99, 'msg': f'系统错误: {str(e)}'},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    # ==================== 校验函数 ====================

    def _check_dashou_commission_withdraw(self, user_main, jine):
        """打手佣金提现校验"""
        try:
            dashou = UserDashou.query.get(user=user_main)
        except ObjectDoesNotExist:
            return {'code': 10, 'msg': '您不是打手身份，无法提现佣金'}

        if dashou.zhanghaozhuangtai != 1:
            return {'code': 11, 'msg': '打手账号已被封禁，无法提现'}
        if dashou.zhuangtai != 1:
            return {'code': 12, 'msg': '您有订单进行中，请完成后提现'}
        if dashou.jifen < 10:
            return {'code': 15, 'msg': '积分不足10分，请补充积分后提现'}
        if dashou.yue < jine:
            return {'code': 13, 'msg': f'余额不足，当前余额: {dashou.yue}'}

        formal_ok, formal_msg = check_dashou_has_formal_huiyuan_for_withdraw(user_main.UserUID)
        if not formal_ok:
            return {'code': 14, 'msg': formal_msg}

        trial_ok, trial_msg = check_dashou_trial_blocks_commission_withdraw(user_main.UserUID)
        if not trial_ok:
            return {'code': 16, 'msg': trial_msg}

        return {'code': 0, 'msg': 'ok', 'data': {'nicheng': dashou.nicheng or ''}}

    def _check_guanshi_dividend_withdraw(self, user_main, jine):
        """管事分红提现校验"""
        try:
            guanshi = UserGuanshi.query.get(user=user_main)
        except ObjectDoesNotExist:
            return {'code': 20, 'msg': '您不是管事身份，无法提现分红'}
        if guanshi.zhuangtai != 1:
            return {'code': 21, 'msg': '管事账号已被封禁，无法提现'}
        if guanshi.yue < jine:
            return {'code': 22, 'msg': f'余额不足，当前余额: {guanshi.yue}'}
        return {'code': 0, 'msg': 'ok', 'data': {}}

    def _check_zuzhang_withdraw(self, user_main, jine):
        """组长分红提现校验"""
        try:
            zuzhang = UserZuzhang.query.get(user=user_main)
        except ObjectDoesNotExist:
            return {'code': 30, 'msg': '您不是组长身份，无法提现组长分红'}
        if zuzhang.zhuangtai != 1:
            return {'code': 31, 'msg': '组长账号已被封禁，无法提现'}
        if zuzhang.ketixian_jine < jine:
            return {'code': 32, 'msg': f'可提现金额不足，当前可提: {zuzhang.ketixian_jine}'}
        return {'code': 0, 'msg': 'ok', 'data': {}}

    def _check_shenheguan_withdraw(self, user_main, jine):
        """审核官分佣提现校验"""
        try:
            shenheguan = UserShenheguan.query.get(user=user_main)
        except ObjectDoesNotExist:
            return {'code': 40, 'msg': '您不是审核官身份，无法提现分佣'}
        if shenheguan.zhuangtai != 1:
            return {'code': 41, 'msg': '审核官账号已被封禁，无法提现'}
        if shenheguan.yue < jine:
            return {'code': 42, 'msg': f'可提现金额不足，当前可提: {shenheguan.yue}'}
        return {'code': 0, 'msg': 'ok', 'data': {}}


    def _check_shangjia_withdraw(self, user_main, jine):
        """
        商家余额提现校验（退出平台）
        包含：订单、自身罚单、申请的罚单检查
        """
        try:
            shangjia = UserShangjia.query.get(user=user_main)
        except ObjectDoesNotExist:
            return {'code': 60, 'msg': '您不是商家身份，无法提现商家余额'}

        if shangjia.zhuangtai != 1:
            return {'code': 61, 'msg': '商家账号已被禁用，无法提现'}
        if shangjia.yue < jine:
            return {'code': 62, 'msg': f'商家余额不足，当前余额: {shangjia.yue}'}

        # 订单检查（使用 Q 取反）
        unfinished_orders = MerchantOrderExt.query.filter(
            MerchantID=user_main.UserUID,
        ).exclude(
            Order__Status__in=[ORDER_STATUS_COMPLETED, ORDER_STATUS_REFUNDED,ORDER_STATUS_FAIL]
        ).exists()
        if unfinished_orders:
            return {'code': 63, 'msg': '您还有未完成或未退款的订单，请先处理完毕再提现余额'}

        # 自身被处罚的罚单检查（状态不是已缴纳(2)和已驳回(4)）
        self_fadan = Penalty.query.filter(
            PenalizedUserID=user_main.UserUID,
        ).exclude(
            Status__in=[2, 4]
        ).exists()
        if self_fadan:
            return {'code': 64, 'msg': '您有未处理完毕的自身罚单（待缴纳/申诉中），请先处理'}

        # 申请的对他人处罚罚单检查（状态不是已缴纳(2)和已驳回(4)）
        applied_fadan = Penalty.query.filter(
            ApplicantID=user_main.UserUID,
        ).exclude(
            Status__in=[2, 4]
        ).exists()
        if applied_fadan:
            return {'code': 65, 'msg': '您发起的对其他用户的处罚尚未处理完毕（待缴纳/申诉中），请等待完结'}

        return {'code': 0, 'msg': 'ok', 'data': {'nicheng': shangjia.nicheng or ''}}

    def _check_dashou_yajin_withdraw(self, user_main, jine):
        """
        打手押金提现校验（退出平台）
        要求：无进行中的订单，无未结算订单，自身罚单需已处理
        """
        try:
            dashou = UserDashou.query.get(user=user_main)
        except ObjectDoesNotExist:
            return {'code': 50, 'msg': '您不是打手身份，无法提取押金'}

        if dashou.zhanghaozhuangtai != 1:
            return {'code': 51, 'msg': '打手账号已禁用，无法提取押金'}
        if dashou.zhuangtai != 1:
            return {'code': 52, 'msg': '您有订单进行中，请完成后提取押金'}
        if dashou.yajin < jine:
            return {'code': 53, 'msg': f'押金余额不足，当前押金: {dashou.yajin}'}

        # 订单检查（使用 exclude + __in）
        unfinished_orders = Order.query.filter(
            PlayerID=user_main.UserUID,
        ).exclude(
            Status__in=[ORDER_STATUS_COMPLETED, ORDER_STATUS_REFUNDED]
        ).exists()
        if unfinished_orders:
            return {'code': 54, 'msg': '您还有未完成或未退款的订单，请先处理完毕再提取押金'}

        # 自身罚单检查
        self_fadan = Penalty.query.filter(
            PenalizedUserID=user_main.UserUID,
        ).exclude(
            Status__in=[2, 4]
        ).exists()
        if self_fadan:
            return {'code': 55, 'msg': '您有未处理完毕的自身罚单（待缴纳/申诉中），请先处理'}

        return {'code': 0, 'msg': 'ok', 'data': {'nicheng': dashou.nicheng or ''}}


class TixianJiluHuoquViewV2(APIView):
    """
    提现记录获取接口
    mode=1：手动提现记录（默认，兼容旧版）
    mode=2：自动提现审核记录（含 shenhe_jilu_id / shenhe_danhao，支持 zhuangtai 筛选）
    """
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        try:
            user_main = request.user
            yonghuid = user_main.UserUID
            page = request.data.get('page', 1)
            limit = request.data.get('limit', 50)
            mode = int(request.data.get('mode', 1) or 1)
            zhuangtai_filter = int(request.data.get('zhuangtai', 0) or 0)

            try:
                page = int(page)
                limit = int(limit)
                if page < 1 or limit < 1:
                    return Response({'code': 1, 'msg': '参数错误', 'data': None},
                                    status=status.HTTP_400_BAD_REQUEST)
            except (TypeError, ValueError):
                return Response({'code': 1, 'msg': '参数格式错误', 'data': None},
                                status=status.HTTP_400_BAD_REQUEST)

            if limit > 100:
                limit = 100
            offset = (page - 1) * limit

            qs = Tixianjilu.query.filter(yonghuid=yonghuid)
            if mode == 2:
                # 自动提现：含新审核关联记录；zhuangtai>0 时按状态筛选
                if zhuangtai_filter > 0:
                    qs = qs.filter(zhuangtai=zhuangtai_filter)
            qs = qs.order_by('-CreateTime')

            records_queryset = qs.values(
                'id', 'leixing', 'jine', 'zhuangtai', 'CreateTime', 'fangshi',
                'phone', 'skzhanghao', 'zhifu', 'bhliyou',
                'shenhe_jilu_id', 'shenhe_danhao',
            )[offset:offset + limit + 1]

            records_list = list(records_queryset)
            has_more = len(records_list) > limit
            records_to_return = records_list[:limit] if has_more else records_list

            # 批量取审核表 fail_reason
            audit_ids = [r['shenhe_jilu_id'] for r in records_to_return if r.get('shenhe_jilu_id')]
            audit_map = {}
            if audit_ids:
                for a in TixianShenheJilu.query.filter(id__in=audit_ids).values(
                    'id', 'fail_reason', 'shenqing_jine', 'shenhe_danhao'
                ):
                    audit_map[a['id']] = a

            # 批量取自动打款失败原因
            danhao_list = [r['shenhe_danhao'] for r in records_to_return if r.get('shenhe_danhao')]
            auto_fail_map = {}
            if danhao_list:
                for ar in TixianAutoRecord.query.filter(
                    shenhe_danhao__in=danhao_list, zhuangtai=2
                ).order_by('-CreateTime').values('shenhe_danhao', 'fail_reason'):
                    if ar['shenhe_danhao'] not in auto_fail_map:
                        auto_fail_map[ar['shenhe_danhao']] = ar['fail_reason']

            formatted_records = []
            for record in records_to_return:
                audit = audit_map.get(record.get('shenhe_jilu_id')) if record.get('shenhe_jilu_id') else None
                fail_reason = ''
                if audit and audit.get('fail_reason'):
                    fail_reason = audit['fail_reason']
                elif record.get('shenhe_danhao'):
                    fail_reason = auto_fail_map.get(record['shenhe_danhao'], '') or ''

                jine_val = float(record['jine']) if record['jine'] else 0.00
                if mode == 2 and audit and audit.get('shenqing_jine') is not None:
                    jine_val = float(audit['shenqing_jine'])

                shenhe_danhao_val = record.get('shenhe_danhao') or (audit.get('shenhe_danhao') if audit else '')
                formatted_records.append({
                    'id': record['id'],
                    'tixianjilu_id': record['id'],
                    'tixian_id': record['id'],
                    'leixing': record['leixing'],
                    'jine': jine_val,
                    'zhuangtai': record['zhuangtai'],
                    'create': record['CreateTime'].strftime('%Y-%m-%d %H:%M:%S'),
                    'fangshi': record['fangshi'],
                    'txdianhua': record['phone'] or '',
                    'txzh': record['skzhanghao'] or '',
                    'txtupian': record['zhifu'] or '',
                    'shibaiyuanyin': record['bhliyou'] or '',
                    'bhliyou': record['bhliyou'] or '',
                    'fail_reason': fail_reason,
                    'shenhe_jilu_id': record.get('shenhe_jilu_id'),
                    'shenhe_danhao': shenhe_danhao_val,
                })

            return Response({
                'code': 0,
                'msg': '获取成功',
                'data': {
                    'list': formatted_records,
                    'has_more': has_more,
                    'page': page,
                    'limit': limit,
                    'current_count': len(formatted_records),
                },
            })

        except Exception as e:
            return Response({
                'code': 99,
                'msg': f'系统错误: {str(e)}',
                'data': None,
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class YonghuTixianShenheXiugaiView(APIView):
    """
    用户修改审核中提现申请接口
    访问路径: /api/yonghu/yonghutxshxg
    请求方法: POST
    权限要求: JWT Token认证通过的用户
    请求体: multipart/form-data 格式
    支持字段: tixian_id, fangshi, txdianhua, txzh, file (图片文件)

    功能: 允许用户修改审核中提现申请的收款方式、电话、账号、收款码等
    """

    permission_classes = [IsAuthenticated]
    parser_classes = (MultiPartParser, FormParser, JSONParser)

    def post(self, request):
        """
        处理用户修改审核中提现申请的POST请求
        """
        try:
            # 1. 获取当前用户
            user_main = request.user
            current_yonghuid = user_main.UserUID

            # 2. 验证必填字段：提现记录ID
            tixian_id = request.data.get('tixian_id')
            if not tixian_id:
                return Response({
                    'code': 1,
                    'msg': '提现记录ID不能为空',
                    'data': None
                }, status=status.HTTP_400_BAD_REQUEST)

            # 3. 查询提现记录（使用select_for_update确保事务安全）
            with transaction.atomic():
                try:
                    tixian_record = Tixianjilu.objects.select_for_update().get(
                        id=tixian_id,
                        yonghuid=current_yonghuid  # 确保只能修改自己的记录
                    )
                except Tixianjilu.DoesNotExist:
                    return Response({
                        'code': 2,
                        'msg': '提现记录不存在或无权修改',
                        'data': None
                    }, status=status.HTTP_404_NOT_FOUND)

                # 4. 验证提现记录状态（必须是审核中）
                if tixian_record.zhuangtai != 1:
                    return Response({
                        'code': 3,
                        'msg': '只有审核中的提现申请可以修改',
                        'data': None
                    }, status=status.HTTP_400_BAD_REQUEST)

                # 5. 获取并验证提现方式
                fangshi = request.data.get('fangshi')
                if fangshi:
                    fangshi = int(fangshi)
                    if fangshi not in [1, 2]:
                        return Response({
                            'code': 4,
                            'msg': '提现方式无效，请选择1(微信)或2(支付宝)',
                            'data': None
                        }, status=status.HTTP_400_BAD_REQUEST)

                    # 检查提现类型与方式的匹配（如果前端提供了leixing）
                    leixing = request.data.get('leixing')
                    if leixing:
                        leixing = int(leixing)
                        # 这里可以根据业务逻辑添加类型与方式的验证
                        # 例如：某些类型只能使用某些方式

                # 6. 验证手机号（必填）
                txdianhua = request.data.get('txdianhua', '').strip()
                if not txdianhua:
                    return Response({
                        'code': 5,
                        'msg': '收款人电话不能为空',
                        'data': None
                    }, status=status.HTTP_400_BAD_REQUEST)

                # 验证手机号格式
                if not txdianhua.isdigit() or len(txdianhua) != 11:
                    return Response({
                        'code': 6,
                        'msg': '请输入11位有效的手机号码',
                        'data': None
                    }, status=status.HTTP_400_BAD_REQUEST)

                # 7. 获取收款账号（可选）
                txzh = request.data.get('txzh', '').strip()

                # 8. 处理收款码图片上传（如果有）
                txtupian_file = request.FILES.get('file')
                new_zhifu_url = None
                old_zhifu_url = tixian_record.zhifu

                if txtupian_file:
                    # 验证图片
                    is_valid, error_msg = validate_image(txtupian_file)
                    if not is_valid:
                        return Response({
                            'code': 7,
                            'msg': f'图片验证失败: {error_msg}',
                            'data': None
                        }, status=status.HTTP_400_BAD_REQUEST)

                    # 上传收款码图片
                    new_zhifu_url = self.handle_shoukuanma_upload(
                        user_main,
                        txtupian_file,
                        old_zhifu_url,
                        tixian_record.leixing
                    )

                    if not new_zhifu_url:
                        return Response({
                            'code': 8,
                            'msg': '收款码上传失败',
                            'data': None
                        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

                # 9. 验证收款信息（账号和图片至少有一个）
                if not txzh and not (new_zhifu_url or old_zhifu_url):
                    return Response({
                        'code': 9,
                        'msg': '请填写收款账号或上传收款码',
                        'data': None
                    }, status=status.HTTP_400_BAD_REQUEST)

                # 10. 更新提现记录
                update_fields = []

                # 更新提现方式（如果有）
                if fangshi:
                    tixian_record.fangshi = fangshi
                    update_fields.append('fangshi')

                # 更新手机号（必填）
                tixian_record.phone = txdianhua
                update_fields.append('phone')

                # 更新收款账号（如果有）
                if txzh is not None:  # 注意：空字符串也要更新
                    tixian_record.skzhanghao = txzh
                    update_fields.append('skzhanghao')

                # 更新收款码图片（如果有新图片）
                if new_zhifu_url:
                    tixian_record.zhifu = new_zhifu_url
                    update_fields.append('zhifu')

                # 保存更新
                if update_fields:
                    tixian_record.save(update_fields=update_fields)

                # 11. 构建返回数据
                response_data = {
                    'tixian_id': tixian_record.id,
                    'fangshi': tixian_record.fangshi,
                    'txdianhua': tixian_record.phone,
                    'txzh': tixian_record.skzhanghao or '',
                    'txtupian': tixian_record.zhifu or ''  # 返回相对URL
                }

                # 12. 返回成功响应
                return Response({
                    'code': 0,
                    'msg': '提现申请修改成功',
                    'data': response_data
                })

        except Exception as e:
            # 记录详细错误日志
            logger.error(
                f"修改提现申请异常 - 用户ID: {getattr(user_main, 'yonghuid', 'N/A')}, "
                f"提现ID: {tixian_id}, "
                f"错误类型: {type(e).__name__}, "
                f"错误详情: {str(e)}",
                exc_info=True
            )

            # 返回友好错误信息
            return Response({
                'code': 99,
                'msg': '系统繁忙，请稍后重试',
                'data': None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def handle_shoukuanma_upload(self, user_main, image_file, old_zhifu_url, leixing=None):
        """
        处理收款码图片上传到腾讯云COS
        存储路径: tixian/{yonghuid}/{timestamp_uuid}.扩展名

        参数:
        - user_main: 当前用户对象
        - image_file: 图片文件对象
        - old_zhifu_url: 旧收款码URL（用于删除）
        - leixing: 提现类型（可选，用于文件夹分类）

        返回: 新的图片相对路径
        """
        try:
            yonghuid = user_main.UserUID
            if not yonghuid:
                return None

            # 删除旧收款码（如果存在且不是空字符串）
            if old_zhifu_url and old_zhifu_url.strip():
                delete_from_oss(old_zhifu_url)

            # 获取文件扩展名
            file_name = image_file.name
            file_extension = os.path.splitext(file_name)[1].lower()
            if not file_extension:
                file_extension = '.jpg'

            # 生成唯一文件名（使用时间戳+UUID确保不重复）
            timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
            unique_id = str(uuid.uuid4())[:8]  # 取UUID前8位
            unique_file_name = f"{timestamp}_{unique_id}{file_extension}"

            # 根据提现类型构建文件夹路径（如果提供了leixing）
            if leixing:
                # leixing=1:打手佣金, leixing=2:管事分红
                type_folder = 'dashou' if leixing == 1 else 'guanshi'
                oss_file_path = f"tixian/{type_folder}/{yonghuid}/{unique_file_name}"
            else:
                # 默认路径
                oss_file_path = f"tixian/{yonghuid}/{unique_file_name}"

            # 上传新收款码到OSS
            new_shoukuanma_url = upload_to_oss(image_file, oss_file_path)

            if new_shoukuanma_url:
                # 返回相对路径（从tixian文件夹开始）
                return oss_file_path
            else:
                return None

        except Exception as e:
            print(f"处理收款码上传失败: {e}")
            return None


class TixianAssetView(APIView):
    """
    获取用户所有可提现资产及费率
    请求方式：POST
    认证：JWT Token
    返回：
    {
        "code": 200,
        "msg": "success",
        "data": {
            "dashou_yue": "123.45",
            "dashou_yajin": "500.00",
            "shangjia_yue": "0.00",
            "guanshi_fenyong": "67.89",
            "zuzhang_fenyong": "0.00",
            "kaoheguan_fenyong": "0.00",
            "dashou_rate": 0.08,
            "dashou_yajin_rate": 0.05,
            "shangjia_rate": 0.06,
            "guanshi_rate": 0.08,
            "zuzhang_rate": 0.05,
            "kaoheguan_rate": 0.07
        }
    }
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        user = User.query.select_related(
            'DashouProfile', 'ShopProfile', 'GuanshiProfile', 'ZuzhangProfile', 'ShenheguanProfile'
        ).get(UserUID=request.user.UserUID)
        # 初始化返回数据，默认全部为0
        # 冻结字段为增量兼容字段：旧前端忽略；提现仍只读 *_yue / *_fenyong
        data = {
            'dashou_yue': '0.00',
            'dashou_yajin': '0.00',
            'shangjia_yue': '0.00',
            'guanshi_fenyong': '0.00',
            'zuzhang_fenyong': '0.00',
            'kaoheguan_fenyong': '0.00',
            'dashou_dongjie_yue': '0.00',
            'guanshi_dongjie_yue': '0.00',
            'zuzhang_dongjie_yue': '0.00',
            'kaoheguan_dongjie_yue': '0.00',
            'dashou_rate': 0.00,
            'dashou_yajin_rate': 0.00,
            'shangjia_rate': 0.00,
            'guanshi_rate': 0.00,
            'zuzhang_rate': 0.00,
            'kaoheguan_rate': 0.00,
        }

        # ------------------- 打手资产 -------------------
        try:
            dashou = user.DashouProfile
            data['dashou_yue'] = str(dashou.yue)
            data['dashou_yajin'] = str(dashou.yajin)
            data['dashou_dongjie_yue'] = str(getattr(dashou, 'dongjie_yue', 0) or 0)
        except ObjectDoesNotExist:
            pass

        # ------------------- 商家资产 -------------------
        try:
            shangjia = user.ShopProfile
            data['shangjia_yue'] = str(shangjia.yue)
        except ObjectDoesNotExist:
            pass

        # ------------------- 管事资产 -------------------
        try:
            guanshi = user.GuanshiProfile
            data['guanshi_fenyong'] = str(guanshi.yue)
            data['guanshi_dongjie_yue'] = str(getattr(guanshi, 'dongjie_yue', 0) or 0)
        except ObjectDoesNotExist:
            pass

        # ------------------- 组长资产 -------------------
        try:
            zuzhang = user.ZuzhangProfile
            data['zuzhang_fenyong'] = str(zuzhang.ketixian_jine)
            data['zuzhang_dongjie_yue'] = str(getattr(zuzhang, 'dongjie_yue', 0) or 0)
        except ObjectDoesNotExist:
            pass

        # ------------------- 审核官（考核官）资产 -------------------
        try:
            kaoheguan = user.ShenheguanProfile
            data['kaoheguan_fenyong'] = str(kaoheguan.yue)
            data['kaoheguan_dongjie_yue'] = str(getattr(kaoheguan, 'dongjie_yue', 0) or 0)
        except ObjectDoesNotExist:
            pass

        from jituan.services.club_user import get_user_club_id
        from jituan.services.withdraw_config import build_tixian_asset_rates
        from users.views.fund_freeze_mp import _freeze_display_reasons, _default_freeze_reason

        club_id = get_user_club_id(user)
        data.update(build_tixian_asset_rates(club_id))

        reasons = _freeze_display_reasons(club_id or '')
        data['freeze_display_reasons'] = reasons
        data['freeze_display_reason'] = reasons.get('dashou') or _default_freeze_reason()

        return Response({
            'code': 200,
            'msg': '获取成功',
            'data': data
        }, status=status.HTTP_200_OK)


class GuanshiContactView(APIView):
    """
    管事获取自己的邀请人（组长）信息
    路径: /api/yonghu/guanshi_contact
    方法: POST
    权限: JWT认证
    请求体: 无（仅需携带合法token）
    成功返回:
        code: 200,
        data: {
            uid: "1234567",       // 组长用户ID
            nicheng: "张三",      // 组长昵称
            touxiang: "avatar/xxx.jpg"  // 组长头像相对路径（前端拼接完整URL）
        }
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        # 1. 获取当前登录用户（必须已通过JWT认证）
        current_user = request.user  # 类型: User

        # 2. 校验是否为管事身份（存在管事扩展表记录）
        try:
            guanshi_profile = current_user.GuanshiProfile
        except ObjectDoesNotExist:
            return Response({
                'code': 403,
                'msg': '您还不是管事，无法获取组长信息',
                'data': None
            })

        # 3. 获取邀请人ID（管事扩展表中的 yaoqingren 字段存储的是邀请人的 yonghuid）
        inviter_yonghuid = guanshi_profile.yaoqingren
        if not inviter_yonghuid:
            return Response({
                'code': 404,
                'msg': '未找到邀请人信息',
                'data': None
            })

        # 4. 根据邀请人用户ID查询用户主表
        try:
            inviter_user = User.query.get(UserUID=inviter_yonghuid)
        except User.DoesNotExist:
            logger.error(f"邀请人用户不存在: yonghuid={inviter_yonghuid}")
            return Response({
                'code': 404,
                'msg': '邀请人账号异常',
                'data': None
            })

        # 5. 获取邀请人昵称（从老板扩展表取，若不存在则给默认值）
        try:
            inviter_nicheng = inviter_user.BossProfile.nickname
        except ObjectDoesNotExist:
            inviter_nicheng = '组长'  # 兜底昵称

        # 6. 构造返回数据
        response_data = {
            'uid': inviter_user.UserUID,
            'nicheng': inviter_nicheng,
            'touxiang': inviter_user.Avatar or ''  # 头像相对路径
        }

        return Response({
            'code': 200,
            'msg': '获取成功',
            'data': response_data
        })


def generate_tixian_id():
    """生成唯一提现订单号：TX + 时间戳(13位) + 4位随机数"""
    timestamp = str(int(time.time() * 1000))
    rand = ''.join(random.choices(string.digits, k=4))
    return f'TX{timestamp}{rand}'


class TixianShenqingV3View(APIView):
    """
    自动提现收款接口（新流程第二步）
    POST /yonghu/tixiansq
    必须传 shenhe_danhao；审核状态须为 6=待收款；申请时已扣款，本接口不再扣款
    """
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        shenhe_danhao = (request.data.get('shenhe_danhao') or '').strip()
        if shenhe_danhao:
            return process_audit_collect(request)
        return Response({
            'code': 7,
            'msg': '缺少审核单号，请先提交提现申请(/yonghu/zddksh)并等待审核通过后再收款',
        })


class TixianCallbackV3View(APIView):
    """
    微信转账结果回调接口（最终状态通知）
    处理微信异步发送的转账成功/失败结果
    """
    permission_classes = []  # 无需认证，签名验证保证安全

    def post(self, request):
        headers = request.headers
        body = request.body.decode('utf-8')

        # 1. 验证签名（多商户依次验签）
        from utils.wechat_v3 import resolve_callback_club_id, decrypt_callback_ciphertext
        callback_club_id = resolve_callback_club_id(headers, body)
        if not callback_club_id:
            return Response({'code': 'FAIL', 'message': '签名验证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 2. 解密数据
        try:
            data = json.loads(body)
            resource = data.get('resource')
            if not resource:
                return Response({'code': 'FAIL', 'message': 'resource不存在'}, status=status.HTTP_400_BAD_REQUEST)

            associated_data = resource.get('associated_data', '')
            nonce = resource.get('nonce')
            ciphertext = resource.get('ciphertext')
            if not nonce or not ciphertext:
                return Response({'code': 'FAIL', 'message': '解密字段缺失'}, status=status.HTTP_400_BAD_REQUEST)

            plaintext = decrypt_callback_ciphertext(associated_data, nonce, ciphertext, club_id=callback_club_id)
            callback_data = json.loads(plaintext)
        except Exception as e:
            logger.error(f"回调解密失败: {str(e)}", exc_info=True)
            return Response({'code': 'FAIL', 'message': f'解密失败: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

        # 3. 获取关键信息
        out_bill_no = callback_data.get('out_bill_no')          # 商户提现单号（即 tixian_id）
        transfer_status = callback_data.get('transfer_status')  # SUCCESS / FAIL
        wechat_transfer_no = callback_data.get('transfer_no')   # 微信转账单号
        fail_reason = callback_data.get('fail_reason', '')

        if not out_bill_no:
            return Response({'code': 'FAIL', 'message': 'out_bill_no缺失'}, status=status.HTTP_400_BAD_REQUEST)

        # 4. 幂等处理：只更新状态为0（处理中）的记录，已最终状态不再处理
        with transaction.atomic():
            try:
                auto_record = TixianAutoRecord.objects.select_for_update().get(tixian_id=out_bill_no)
            except TixianAutoRecord.DoesNotExist:
                # 记录不存在，视为已处理，返回成功
                return Response({'code': 'SUCCESS', 'message': 'ok'})

            # 如果已经是最新状态，直接返回成功（幂等）
            if auto_record.zhuangtai != 0:
                return Response({'code': 'SUCCESS', 'message': 'already processed'})

            if transfer_status == 'SUCCESS':
                mark_transfer_success(
                    auto_record,
                    wechat_transfer_no=wechat_transfer_no,
                    with_accounting=True,
                )

            else:  # transfer_status == 'FAIL'
                _mark_transfer_attempt_failed(
                    auto_record,
                    fail_reason or '微信转账失败',
                    close_audit=False,
                )

        return Response({'code': 'SUCCESS', 'message': 'ok'})


class TixianQueRenAutoView(APIView):
    """
    用户确认提现结果
    POST /yonghu/tixianqr
    以微信官方查单状态为准：SUCCESS 落库成功；FAIL/CANCELLED 关闭审核单+退款；进行中则提示等待
    """
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        try:
            tixian_id = request.data.get('tixian_id')
            result = request.data.get('result')  # 1成功 0失败/取消

            if not tixian_id or result is None:
                return Response({'code': 1, 'msg': '缺少参数'}, status=status.HTTP_400_BAD_REQUEST)

            try:
                result = int(result)
            except ValueError:
                return Response({'code': 2, 'msg': '参数格式错误'}, status=status.HTTP_400_BAD_REQUEST)

            if result not in [0, 1]:
                return Response({'code': 3, 'msg': 'result值无效'}, status=status.HTTP_400_BAD_REQUEST)

            user_main = request.user

            with transaction.atomic():
                try:
                    auto_record = TixianAutoRecord.objects.select_for_update().get(
                        tixian_id=tixian_id,
                        yonghuid=user_main.UserUID,
                    )
                except TixianAutoRecord.DoesNotExist:
                    return Response({'code': 4, 'msg': '提现记录不存在'}, status=status.HTTP_404_NOT_FOUND)

                if result == 1:
                    if auto_record.zhuangtai == 1:
                        return Response({'code': 0, 'msg': '提现成功', 'data': None})

                    payout_club = club_id_for_tixian_yonghuid(auto_record.yonghuid)
                    wx_data = query_wechat_transfer_bill(tixian_id, payout_club)
                    if wx_data is None:
                        return Response({'code': 0, 'msg': '收款确认已提交，请稍后刷新查看结果'})

                    if wx_data.get('_not_found'):
                        age = timezone.now() - auto_record.CreateTime
                        if auto_record.zhuangtai == 0 and age >= timedelta(seconds=20):
                            _mark_transfer_attempt_failed(
                                auto_record, '微信未找到该打款单', close_audit=False,
                            )
                            return Response({'code': 0, 'msg': '请再次点击收款重试'})
                        return Response({'code': 12, 'msg': '收款处理中，请稍后再试'})

                    state = (wx_data.get('state') or '').upper()
                    if state in WX_STATE_SUCCESS:
                        mark_transfer_success(
                            auto_record,
                            wechat_transfer_no=wx_data.get('transfer_bill_no') or wx_data.get('transfer_no'),
                            with_accounting=True,
                        )
                        return Response({'code': 0, 'msg': '提现成功', 'data': None})

                    if state in WX_STATE_FAIL:
                        fail_reason = wx_data.get('fail_reason') or wx_data.get('close_reason') or state
                        _mark_transfer_attempt_failed(
                            auto_record, str(fail_reason)[:500], close_audit=False,
                        )
                        return Response({'code': 0, 'msg': '本次收款未成功，可再次点击收款重试'})

                    if state in WX_STATE_WAIT or state in WX_STATE_CANCELING:
                        return Response({'code': 12, 'msg': '请在微信中完成收款确认'})

                    return Response({'code': 0, 'msg': '收款确认已提交，请稍后刷新查看结果'})

                # 用户报告取消/失败：以微信查单为准，不本地盲目标记
                if auto_record.zhuangtai == 2:
                    return Response({'code': 0, 'msg': '提现已取消', 'data': None})
                if auto_record.zhuangtai == 1:
                    return Response({'code': 0, 'msg': '提现成功', 'data': None})

                wx_data = query_wechat_transfer_bill(
                    tixian_id, club_id_for_tixian_yonghuid(auto_record.yonghuid),
                )
                if wx_data is None:
                    return Response({'code': 0, 'msg': '提现已取消，可再次点击收款重试'})

                if wx_data.get('_not_found'):
                    _mark_transfer_attempt_failed(auto_record, '用户取消收款', close_audit=False)
                    return Response({'code': 0, 'msg': '提现已取消，可再次点击收款重试'})

                state = (wx_data.get('state') or '').upper()
                if state in WX_STATE_SUCCESS:
                    mark_transfer_success(
                        auto_record,
                        wechat_transfer_no=wx_data.get('transfer_bill_no') or wx_data.get('transfer_no'),
                        with_accounting=True,
                    )
                    return Response({'code': 0, 'msg': '提现成功', 'data': None})

                if state in WX_STATE_FAIL:
                    fail_reason = wx_data.get('fail_reason') or wx_data.get('close_reason') or '用户取消收款'
                    _mark_transfer_attempt_failed(
                        auto_record, str(fail_reason)[:500], close_audit=False,
                    )
                    return Response({'code': 0, 'msg': '提现已取消，可再次点击收款重试'})

                if state in WX_STATE_WAIT or state in WX_STATE_CANCELING:
                    return Response({'code': 12, 'msg': '收款仍在进行中，请在微信中操作或稍后再试'})

                return Response({'code': 0, 'msg': '提现已取消，可再次点击收款重试'})

        except Exception as e:
            logger.error(f'提现确认异常: {str(e)}', exc_info=True)
            return Response({'code': 99, 'msg': '系统错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
