"""users.views.kefu_base - 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,
)
from jituan.services.admin_context import is_kefu_backend_account
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 KefuLoginView(APIView):
    """
    客服/管理员登录接口（支持手机号重复）
    请求：POST /yonghu/kefujinru
    请求体：{"phone": "13800138000", "password": "xxx", "erjimima": "yyy"}
    返回：
        code=0 成功，data包含token,nicheng,yonghuid
        code=1 失败（msg区分：用户不存在/密码错误/二级密码错误）
        code=4 账号被封禁

    管理员（IsSuperuser 或 UserType='admin'）无需 erjimima 和 KefuProfile。
    """
    throttle_classes = [AnonRateThrottle]          # 限制匿名请求频率
    permission_classes = [AllowAny]                # 任何人都可访问

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

        if not phone or not password:
            return Response({
                'code': 1,
                'msg': '请填写手机号和密码',
                'data': None
            }, status=status.HTTP_400_BAD_REQUEST)

        # 2. 获取客户端真实IP
        client_ip = self.get_client_ip(request)

        # 3. 查询该手机号下所有账号（客服 + 管理员）
        #    先查客服（有 KefuProfile），再查管理员（IsSuperuser 或 UserType='admin'）
        user_mains = list(
            User.query.filter(
                Phone=phone,
                KefuProfile__isnull=False,
            ).select_related('KefuProfile')
        )

        # 如果没有客服账号，尝试查找管理员账号
        if not user_mains:
            admin_candidates = User.query.filter(Phone=phone)
            for admin_user in admin_candidates:
                if admin_user.IsSuperuser or admin_user.UserType == 'admin':
                    user_mains = [admin_user]
                    break

        if not user_mains:
            logger.warning(f"登录失败，用户不存在: {phone}, IP: {client_ip}")
            return Response({
                'code': 1,
                'msg': '用户不存在',
                'data': None
            }, status=status.HTTP_400_BAD_REQUEST)

        # 4. 遍历所有匹配的账号，验证密码和二级密码
        target_user = None
        target_kefu = None
        password_matched = False

        for user in user_mains:
            # 验证主密码（bcrypt 哈希验证）
            if not user.CheckPassword(password):
                continue
            password_matched = True

            # 管理员：跳过二级密码；但非白名单若客服已禁用仍拦截
            is_admin = user.IsSuperuser or user.UserType == 'admin'
            from jituan.constants import SUPER_ADMIN_PHONES
            is_whitelist = (user.Phone or '') in SUPER_ADMIN_PHONES
            try:
                kefu_probe = user.KefuProfile
            except Exception:
                kefu_probe = None
            if kefu_probe is not None and int(getattr(kefu_probe, 'zhuangtai', 1) or 0) != 1 and not is_whitelist:
                if target_user is None:
                    target_user = user
                    target_kefu = kefu_probe
                continue

            if is_admin or is_whitelist:
                target_user = user
                target_kefu = kefu_probe
                break

            # 客服：验证二级密码
            kefu = kefu_probe
            if kefu is None:
                continue
            stored_erji = kefu.erjimima or ''
            if stored_erji.startswith(('$2b$', '$2a$')) and len(stored_erji) == 60:
                import bcrypt as _bcrypt
                if not _bcrypt.checkpw(erjimima.encode('utf-8'), stored_erji.encode('utf-8')):
                    continue
            elif stored_erji != erjimima:
                continue

            # 如果账号被禁用，记录但继续查找
            if kefu.zhuangtai != 1:
                if target_user is None:
                    target_user = user
                    target_kefu = kefu
                continue

            # 找到完全匹配且状态正常的账号，立即使用
            target_user = user
            target_kefu = kefu
            break
        else:
            # 循环结束未找到正常账号
            if target_user and target_kefu and int(getattr(target_kefu, 'zhuangtai', 1) or 0) != 1:
                # 只有被禁用的账号匹配，返回封禁提示
                logger.warning(f"登录失败，客服账号已禁用: {phone}, IP: {client_ip}")
                return Response({
                    'code': 4,
                    'msg': '账号已被封禁',
                    'data': None
                }, status=status.HTTP_403_FORBIDDEN)
            elif password_matched:
                # 密码正确但二级密码错误
                logger.warning(f"登录失败，二级密码错误: {phone}, IP: {client_ip}")
                return Response({
                    'code': 1,
                    'msg': '二级密码错误',
                    'data': None
                }, status=status.HTTP_400_BAD_REQUEST)
            else:
                # 密码错误
                logger.warning(f"登录失败，密码错误: {phone}, IP: {client_ip}")
                return Response({
                    'code': 1,
                    'msg': '密码错误',
                    'data': None
                }, status=status.HTTP_400_BAD_REQUEST)

        # 5. 更新IP和最后登录时间
        target_user.IP = client_ip
        target_user.UserLastLoginDate = timezone.now()
        target_user.save(update_fields=['IP', 'UserLastLoginDate'])

        # 6. 生成JWT token
        refresh = RefreshToken.for_user(target_user)
        token = str(refresh.access_token)

        # 7. 返回成功数据（管理员无 KefuProfile，nicheng 用 UserName 或 Phone 兜底）
        nicheng = target_kefu.nicheng if target_kefu else (target_user.UserName or target_user.Phone)
        return Response({
            'code': 0,
            'msg': '登录成功',
            'data': {
                'token': token,
                'nicheng': nicheng,
                'yonghuid': target_user.UserUID,
            }
        })

    def get_client_ip(self, request):
        """
        获取客户端真实IP
        """
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0].strip()
            if ip:
                return ip
        return request.META.get('REMOTE_ADDR', '0.0.0.0')


class KefuStatsView(APIView):
    """
    客服统计数据接口
    请求：POST /yonghu/kfjrhqzl
    请求体：{"phone": "13800138000"}
    认证：必须携带有效的 JWT token（放在 Authorization 头）
    返回：
        code=0 成功，data 包含 jinrichuli, jinyuechuli, zongchuli
        验证失败统一返回 401，不透露具体原因
    """

    permission_classes = [IsAuthenticated]        # 必须登录


    def post(self, request):
        # 1. 获取请求中的 phone
        phone = request.data.get('phone', '').strip()
        if not phone:
            # 缺少参数，但按约定返回 401（可以改为 400，但为了统一，用401）
            logger.warning(f"统计接口缺少 phone 参数，用户: {request.user.UserUID}")
            return Response({'detail': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 2. 获取当前登录用户（从 JWT 中解析）
        current_user = request.user

        # 3. 验证前端传来的 phone 是否与当前用户的 phone 一致
        if current_user.Phone != phone:
            # 不一致，可能 token 被冒用或参数错误
            logger.warning(f"统计接口 phone 不匹配: 请求phone={phone}, 用户phone={current_user.Phone}")
            return Response({'detail': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 4. 验证是否为后台客服账号
        from jituan.services.admin_context import is_kefu_backend_account, is_system_super_admin
        if not is_kefu_backend_account(current_user):
            logger.warning(f"统计接口用户类型非客服: {current_user.UserUID}")
            return Response({'detail': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 5. 尝试获取客服扩展表数据（管理员跳过）
        is_admin = is_system_super_admin(current_user)
        if is_admin:
            return Response({
                'code': 0,
                'data': {
                    'jinrichuli': 0,
                    'jinyuechuli': 0,
                    'zongchuli': 0,
                }
            }, status=status.HTTP_200_OK)

        try:
            kefu_profile = current_user.KefuProfile  # OneToOneField 反向关系
        except UserKefu.DoesNotExist:
            logger.warning(f"统计接口客服扩展表不存在: {current_user.UserUID}")
            return Response({'detail': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)

        # 6. 返回统计数据（字段名与前端约定一致）
        return Response({
            'code': 0,
            'data': {
                'jinrichuli': kefu_profile.jinrichuli,
                'jinyuechuli': kefu_profile.jinyuechuli,
                'zongchuli': kefu_profile.zongchuli,
            }
        }, status=status.HTTP_200_OK)


class KefuGetOrderTypesView(APIView):
    """
    客服获取订单类型列表（平台/商家/跨平台订单页共用）
    请求：POST /yonghu/kfhqptddlx
    认证：JWT + 与 menu-access 相同的 is_kefu_backend_account
    返回：code=0 + 类型列表
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        if not is_kefu_backend_account(request.user):
            return Response({'code': 403, 'msg': '非后台账号'}, status=403)

        try:
            types_qs = ShangpinLeixing.query.all().only('id', 'jieshao', 'tupian_url')
            type_list = [
                {
                    'id': t.id,
                    'biaoti': t.jieshao or '',
                    'tupian_url': t.tupian_url or ''
                }
                for t in types_qs
            ]
            return Response({'code': 0, 'data': type_list})
        except Exception as e:
            logger.error(f"查询商品类型表失败: {str(e)}")
            return Response({'code': 0, 'data': []})
