"""users.views.kefu_punishment - auto-generated by split script."""
"""users.views.kefu - 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,
    check_shijidaozhang_within_limit,
    check_dashou_trial_blocks_commission_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 KefuPunishmentListView(APIView):
    """
    客服获取处罚记录列表接口
    请求：POST /yonghu/kefu_cfgl
    参数：{
        "phone": "客服手机号",
        "status": [0,3] 或 [1,2],  # 状态数组
        "dingdan_id": "订单ID（可选）",
        "dashouid": "打手ID（可选）",
        "page": 1,
        "page_size": 20
    }
    认证：JWT
    返回：{
        "code": 0,
        "data": {
            "list": [处罚记录],
            "total": 总数,
            "stats": {
                "zongshu": 总记录数,
                "daichuli": 待处理数,
                "yichuli": 已处理数
            }
        }
    }
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    @staticmethod
    def _parse_status_list(raw):
        """兼容 status=[0,3]、\"0,3\"、单数字；空/all 表示不过滤。"""
        if raw is None:
            return None
        if isinstance(raw, str):
            s = raw.strip().lower()
            if not s or s in ('all', 'null', 'none'):
                return None
            if s.startswith('['):
                import json
                try:
                    raw = json.loads(s)
                except (TypeError, ValueError):
                    return None
            else:
                raw = [x.strip() for x in s.split(',') if x.strip()]
        if isinstance(raw, (int, float)):
            return [int(raw)]
        if isinstance(raw, list):
            out = []
            for x in raw:
                try:
                    out.append(int(x))
                except (TypeError, ValueError):
                    continue
            return out or None
        return None

    def post(self, request):
        # 1. 获取参数
        phone = request.data.get('phone', '').strip()
        status_list = self._parse_status_list(request.data.get('status'))
        dingdan_id = request.data.get('dingdan_id', '').strip()
        dashouid = request.data.get('dashouid', '').strip()
        try:
            page = int(request.data.get('page', 1))
            page_size = int(request.data.get('page_size', 20))
        except ValueError:
            return Response({'code': 400, 'msg': '分页参数错误'}, status=status.HTTP_400_BAD_REQUEST)

        if not phone:
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 2. 客服身份验证
        current_user = request.user
        # 1. 获取前端参数
        username = request.data.get('phone', '').strip()
        if not username:
            return Response({'code': 400, 'msg': '缺少username'})

        # 2. 公共权限校验
        kefu, permissions = verify_kefu_permission(request, username)
        if kefu is None:
            return permissions

        # 3. 检查平台订单管理权限（002ab）
        if '005aa' not in permissions:
            return Response({'code': 403, 'msg': '您无权查看平台订单列表'})

        # 3. 获取统计信息（不分页）
        from jituan.services.club_penalty import filter_penalty_record_qs
        from jituan.services.club_user_access import list_response_meta

        base_qs = filter_penalty_record_qs(PenaltyRecord.query.all(), request)
        agg = base_qs.aggregate(
            zongshu=Count('id'),
            daichuli=Count('id', filter=Q(ApplyStatus__in=[0, 3])),
            yichuli=Count('id', filter=Q(ApplyStatus__in=[1, 2])),
        )
        stats = {
            'zongshu': agg['zongshu'],
            'daichuli': agg['daichuli'],
            'yichuli': agg['yichuli'],
        }

        queryset = base_qs

        if status_list and isinstance(status_list, list):
            queryset = queryset.filter(ApplyStatus__in=status_list)

        if dingdan_id:
            queryset = queryset.filter(OrderID=dingdan_id)

        if dashouid:
            queryset = queryset.filter(PlayerID=dashouid)

        # 5. 分页
        page_obj = queryset.order_by('-CreateTime').paginate(page=page, per_page=page_size)
        total = page_obj.total
        records = page_obj.items

        # 6. 构建返回列表
        list_data = []
        for item in records:
            ct = item.CreateTime
            ut = item.UpdateTime
            list_data.append({
                'dingdan_id': item.OrderID,
                'dashouid': item.PlayerID,
                'qingqiuid': item.ApplicantID,
                'cfliyou': item.PenaltyReason,
                'sqzhuangtai': item.ApplyStatus,
                'jifen': item.DeductedPoints,
                'CreateTime': ct,
                'UpdateTime': ut,
                'create_time': ct.isoformat() if ct else '',
                'update_time': ut.isoformat() if ut else '',
            })

        return Response({
            'code': 0,
            'data': {
                'list': list_data,
                'total': total,
                'stats': stats,
                **list_response_meta(request),
            }
        })


class KefuPunishmentDetailView(APIView):
    """
    客服获取处罚详情接口
    请求：POST /yonghu/kefu_cf_detail
    参数：{
        "phone": "客服手机号",
        "dingdan_id": "订单ID"
    }
    认证：JWT
    返回：code=0 + 处罚记录详情（含图片）
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        phone = request.data.get('phone', '').strip()
        dingdan_id = request.data.get('dingdan_id', '').strip()

        if not phone or not dingdan_id:
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 客服身份验证
        current_user = request.user
        if getattr(current_user, 'Phone', '') != phone:
            logger.warning(f"手机号不匹配: {phone}")
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        if current_user.UserType not in ('kefu', 'admin'):
            logger.warning(f"用户类型非客服: {current_user.UserUID}")
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        is_admin = current_user.UserType == 'admin' or current_user.IsSuperuser
        kefu = None
        if not is_admin:
            try:
                kefu = current_user.KefuProfile
            except ObjectDoesNotExist:
                logger.warning(f"客服扩展表不存在: {current_user.UserUID}")
                return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

            if kefu.zhuangtai != 1:
                logger.warning(f"客服账号已禁用: {current_user.UserUID}")
                return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 查询处罚记录（按创建时间倒序取最新一条）
        try:
            record = PenaltyRecord.query.filter(OrderID=dingdan_id).order_by('-CreateTime').first()
            if not record:
                return Response({'code': 404, 'msg': '处罚记录不存在'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"查询处罚记录失败: {e}")
            return Response({'code': 500, 'msg': '服务器内部错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 查询商家证据图片
        zhengju_images = []
        shensu_images = []
        try:
            # 商家证据图片：上传者为请求人 (ApplicantID)
            zhengju_qs = PenaltyEvidenceImage.query.filter(OrderID=dingdan_id, UserID=record.ApplicantID)
            zhengju_images = [item.ImageURL for item in zhengju_qs if item.ImageURL]

            # 打手申诉图片：上传者为打手 (PlayerID)
            shensu_qs = PenaltyEvidenceImage.query.filter(OrderID=dingdan_id, UserID=record.PlayerID)
            shensu_images = [item.ImageURL for item in shensu_qs if item.ImageURL]
        except Exception as e:
            logger.error(f"查询图片失败: {e}")

        # 构建返回数据
        data = {
            'dingdan_id': record.OrderID,
            'dashouid': record.PlayerID,
            'qingqiuid': record.ApplicantID,
            'chuliid': record.ProcessorID,
            'cfliyou': record.PenaltyReason,
            'sqzhuangtai': record.ApplyStatus,
            'bhliyou': record.RejectReason,
            'jifen': record.DeductedPoints,
            'ssliyou': record.AppealReason or '',
            'zhengju_tupian': zhengju_images,
            'shensu_tupian': shensu_images,
            'CreateTime': record.CreateTime,
            'UpdateTime': record.UpdateTime,
        }

        return Response({'code': 0, 'data': data})


class KefuPunishmentActionView(APIView):
    """
    客服同意/驳回处罚接口
    请求：POST /yonghu/kefu_cf_action
    参数：{
        "phone": "客服手机号",
        "dingdan_id": "订单ID",
        "action": 1(同意) / 2(驳回),
        "reject_reason": "驳回理由（驳回时必填）"
    }
    认证：JWT
    返回：code=0 成功
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        phone = request.data.get('phone', '').strip()
        dingdan_id = request.data.get('dingdan_id', '').strip()
        action = request.data.get('action')
        reject_reason = request.data.get('reject_reason', '').strip()

        if not phone or not dingdan_id or action not in [1, 2]:
            return Response({'code': 401, 'msg': '参数错误'}, status=status.HTTP_400_BAD_REQUEST)

        if action == 2 and not reject_reason:
            return Response({'code': 400, 'msg': '驳回理由不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        # 客服身份验证（完整验证，此处略）
        current_user = request.user
        if getattr(current_user, 'Phone', '') != phone:
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)
        if current_user.UserType not in ('kefu', 'admin'):
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)
        is_admin = current_user.UserType == 'admin' or current_user.IsSuperuser
        kefu = None
        if not is_admin:
            try:
                kefu = current_user.KefuProfile
                if kefu.zhuangtai != 1:
                    return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)
            except ObjectDoesNotExist:
                return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 查询待处理的处罚记录（状态0或3）
        try:
            record = PenaltyRecord.query.filter(
                OrderID=dingdan_id,
                ApplyStatus__in=[0, 3]
            ).order_by('-CreateTime').first()
            if not record:
                exists = PenaltyRecord.query.filter(OrderID=dingdan_id).exists()
                if exists:
                    return Response({'code': 400, 'msg': '该处罚记录已处理'}, status=status.HTTP_400_BAD_REQUEST)
                else:
                    return Response({'code': 404, 'msg': '处罚记录不存在'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"查询处罚记录失败: {e}")
            return Response({'code': 500, 'msg': '服务器内部错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        with transaction.atomic():
            # 处理重复记录：同一订单的其他待处理/申诉中记录标记为驳回
            duplicate_records = PenaltyRecord.query.filter(
                OrderID=dingdan_id,
                ApplyStatus__in=[0, 3]
            ).exclude(id=record.id)
            for dup in duplicate_records:
                dup.ApplyStatus = 2
                dup.ProcessorID = phone
                dup.RejectReason = "系统自动驳回：存在重复处罚记录"
                dup.save()
                logger.info(f"自动驳回重复处罚记录 ID={dup.id}")

            if action == 1:  # 同意
                # 可选验证打手存在
                if record.PlayerID:
                    try:
                        dashou = UserDashou.query.get(user__UserUID=record.PlayerID)
                    except UserDashou.DoesNotExist:
                        return Response({'code': 400, 'msg': '被处罚打手不存在'}, status=status.HTTP_400_BAD_REQUEST)

                record.ApplyStatus = 1
                record.ProcessorID = phone
                record.save()

                # 更新商家订单扩展表
                try:
                    dingdan = Order.query.select_related('shangjia_kuozhan').get(OrderID=dingdan_id)
                    if hasattr(dingdan, 'shangjia_kuozhan'):
                        dingdan.shangjia_kuozhan.PenaltyApplyStatus = 1
                        dingdan.shangjia_kuozhan.save()
                except Exception as e:
                    logger.warning(f"更新商家扩展表失败: {e}")

            elif action == 2:  # 驳回
                # 返还积分
                if record.DeductedPoints > 0 and record.PlayerID:
                    try:
                        dashou = UserDashou.query.get(user__UserUID=record.PlayerID)
                        if dashou.jifen <= 1000:  # 安全限制
                            dashou.jifen += record.DeductedPoints
                            dashou.save()
                            logger.info(f"驳回处罚，打手{record.PlayerID}返还积分{record.DeductedPoints}")
                        else:
                            logger.warning(f"打手积分异常({dashou.jifen})，不再返还")
                    except UserDashou.DoesNotExist:
                        logger.warning(f"打手{record.PlayerID}不存在，无法返还积分")

                record.ApplyStatus = 2
                record.ProcessorID = phone
                record.RejectReason = reject_reason
                record.save()

                try:
                    dingdan = Order.query.select_related('shangjia_kuozhan').get(OrderID=dingdan_id)
                    if hasattr(dingdan, 'shangjia_kuozhan'):
                        dingdan.shangjia_kuozhan.PenaltyApplyStatus = 2
                        dingdan.shangjia_kuozhan.RejectReason = reject_reason
                        dingdan.shangjia_kuozhan.save()
                except Exception as e:
                    logger.warning(f"更新商家扩展表失败: {e}")

        return Response({'code': 0, 'msg': '处理成功'})


class KefuPunishView(APIView):
    """
    客服处罚打手接口
    请求：POST /yonghu/kefuchufa
    参数：{
        "phone": "客服手机号",
        "dingdan_id": "订单ID",
        "reason": "处罚原因（可选）"
    }
    认证：JWT
    返回：code=0 成功
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        # 1. 获取参数
        phone = request.data.get('phone', '').strip()
        dingdan_id = request.data.get('dingdan_id', '').strip()
        reason = request.data.get('reason', '').strip()

        if not phone or not dingdan_id:
            return Response({'code': 401, 'msg': '参数不完整'}, status=status.HTTP_400_BAD_REQUEST)

        # 2. 客服身份验证
        current_user = request.user
        if getattr(current_user, 'Phone', '') != phone:
            logger.warning(f"手机号不匹配: {phone}")
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        if current_user.UserType not in ('kefu', 'admin'):
            logger.warning(f"用户类型非客服: {current_user.UserUID}")
            return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        is_admin = current_user.UserType == 'admin' or current_user.IsSuperuser
        kefu = None
        if not is_admin:
            try:
                kefu = current_user.KefuProfile
            except ObjectDoesNotExist:
                logger.warning(f"客服扩展表不存在: {current_user.UserUID}")
                return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

            if kefu.zhuangtai != 1:
                logger.warning(f"客服账号已禁用: {current_user.UserUID}")
                return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 3. 查询订单
        try:
            order = Order.query.get(OrderID=dingdan_id)
        except Order.DoesNotExist:
            return Response({'code': 404, 'msg': '订单不存在'}, status=status.HTTP_404_NOT_FOUND)

        # 4. 获取打手ID
        dashou_id = order.PlayerID
        if not dashou_id:
            return Response({'code': 400, 'msg': '订单未接单，无法处罚打手'}, status=status.HTTP_400_BAD_REQUEST)

        # 5. 查询打手
        try:
            dashou_user = User.query.select_related('DashouProfile').get(UserUID=dashou_id)
            dashou = dashou_user.DashouProfile
        except User.DoesNotExist:
            return Response({'code': 404, 'msg': '打手用户不存在'}, status=status.HTTP_404_NOT_FOUND)
        except ObjectDoesNotExist:
            return Response({'code': 400, 'msg': '该用户不是打手'}, status=status.HTTP_400_BAD_REQUEST)

        # 6. 使用事务
        from jituan.services.club_penalty import resolve_penalty_record_club_id
        with transaction.atomic():
            # 创建处罚记录（积分扣除5分）
            jifen = 5
            chufa = PenaltyRecord.query.create(
                PlayerID=dashou_id,
                ApplicantID=phone,           # 客服手机号作为请求人
                PenaltyReason=reason or '',
                ApplyStatus=0,              # 待处理
                DeductedPoints=jifen,
                OrderID=dingdan_id,
                ClubID=resolve_penalty_record_club_id(
                    order_id=dingdan_id,
                    player_id=dashou_id,
                    request=request,
                    user=request.user,
                ),
            )

            # 扣除打手积分
            if dashou.jifen >= jifen:
                dashou.jifen -= jifen
            else:
                dashou.jifen = 0
            dashou.save()

            # 可选：更新订单的 clkf 字段记录处理客服
            order.AssignedCS = phone
            order.save()

        return Response({'code': 0, 'msg': '处罚成功'})
