# 标准库
import time
import random
import logging
from decimal import Decimal
# Django 内置
from django.db.models import F, Max
# 项目模型
## 当前dengji应用
from .models import (
    Chenghao, KaoheCishuFeiyong, ShenheJilu, KaoheJiluFeiyong,
    YonghuChenghao, KaoheguanBankuai, DingdanBiaoqian
)
## users应用
from users.models import UserShenheguan, UserDashou
from users.business_models import User
## orders应用
from .models import YonghuChenghao
# 日志对象
logger = logging.getLogger(__name__)



def check_dashou_biaoqian_required(order_id, dashou_yonghuid):
    """
    检查打手是否满足订单的标签需求。
    - 如果订单没有需求标签，直接放行。
    - 如果有，则要求打手至少拥有其中一个标签。
    返回 (allowed: bool, message: str)
    """
    try:
        # 1. 获取订单的需求标签ID集合
        required_ids = set(
            DingdanBiaoqian.objects.filter(dingdan_id=order_id)
            .values_list('chenghao_id', flat=True)
        )
        if not required_ids:
            return True, ''

        # 2. 找到打手对应的用户记录
        try:
            user = User.objects.get(UserUID=dashou_yonghuid)
        except User.DoesNotExist:
            return False, '用户信息异常'

        # 3. 获取打手已拥有的标签ID集合（只取打手类型）
        owned_ids = set(
            YonghuChenghao.objects.filter(
                yonghu=user,
                chenghao__leixing='dashou'
            ).values_list('chenghao_id', flat=True)
        )

        if not owned_ids:
            return False, '您未拥有任何打手标签，无法抢此订单'

        # 4. 交集判断
        if required_ids.intersection(owned_ids):
            return True, ''
        else:
            return False, '您的标签不符合此订单要求，无法抢单'

    except Exception as e:
        # 标签校验失败不影响主流程，记录日志并保守放行（也可保守拒绝，按需求选择）
        logger.error(f"标签校验异常: {e}", exc_info=True)
        # 安全起见，如果校验出错，选择拒绝，避免越权
        return False, '订单标签校验异常，请稍后重试'





def get_tag_fee(chenghao, cishu):
    """
    获取标签在指定考核次数下的费用。
    - 若有对应次数的配置，直接返回。
    - 若没有该次数，取该标签下已有最大次数的费用（作为后续次数的价格）。
    - 若该标签完全没有费用记录，返回 0.00（免费）。
    """
    fee_obj = KaoheCishuFeiyong.objects.filter(chenghao=chenghao, cishu=cishu).first()
    if fee_obj:
        return fee_obj.feiyong

    max_obj = KaoheCishuFeiyong.objects.filter(chenghao=chenghao).order_by('-cishu').first()
    if max_obj:
        return max_obj.feiyong

    return Decimal('0.00')


def generate_unique_jilu_id():
    """
    生成唯一的审核记录 ID，格式：SH + 时间戳(10位) + 随机数(4位)
    循环检查数据库避免重复，最多尝试 10 次。
    """
    for _ in range(10):
        timestamp = str(int(time.time() * 1000))[-10:]
        random_part = str(random.randint(1000, 9999))
        jilu_id = f'SH{timestamp}{random_part}'
        if not ShenheJilu.objects.filter(jilu_id=jilu_id).exists():
            return jilu_id
    raise Exception('无法生成唯一记录ID，请稍后重试')


def validate_shenheguan(shenheguan_id, bankuai, fee, applicant_user):
    """
    校验指定考核官是否合法
    - 考核官必须存在且未被禁用
    - 必须属于对应板块
    - 必须处于空闲状态
    - 若费用>0，则要求已认证
    返回 (valid, error_msg)
    """
    if not shenheguan_id:
        return True, ''
    try:
        kg = UserShenheguan.objects.select_related('user').get(
            user__UserUID=shenheguan_id,
            zhuangtai=1
        )
    except UserShenheguan.DoesNotExist:
        return False, '考核官不存在或已被禁用'

    # 板块权限
    if not KaoheguanBankuai.objects.filter(kaoheguan_id=shenheguan_id, bankuai=bankuai).exists():
        return False, '该考核官不属于此板块'

    # 空闲状态
    if kg.shenhe_zhuangtai != 0:
        return False, '该考核官当前忙碌，无法指定'

    # 费用>0需要认证
    if float(fee) > 0 and not kg.is_renzheng:
        return False, '费用大于0时只能指定已认证的考核官'

    return True, ''


def create_shenhe_jilu(user, tag_id, game_nick, remark, reapply, jilu_id=None, shenheguan_id=''):
    """
    创建或更新审核记录。
    - 首次申请：创建新记录，生成唯一 jilu_id。
    - 再次申请：基于原记录（必须状态为未通过）更新次数、累加总费用、更新备注和游戏昵称，
      保留审核官信息，状态重置为待审核。不创建新记录。
    - 每次申请均创建一条费用明细记录（KaoheJiluFeiyong），记录本次缴费。
    - 若原记录有考核官，则将其状态改为审核中。
    - 新增 shenheguan_id 参数：指定考核官ID，仅在原记录无考核官时可传入。
    返回 (success, message, record)
    """
    try:
        # 1. 校验标签存在
        try:
            chenghao = Chenghao.objects.get(id=tag_id)
        except Chenghao.DoesNotExist:
            return False, '标签不存在', None

        # 2. 判断用户是否已拥有该标签
        if YonghuChenghao.objects.filter(yonghu=user, chenghao=chenghao).exists():
            return False, '您已拥有该标签，无需重复考核', None

        # 3. 检查是否有进行中的审核记录（待审核、审核中）
        has_pending = ShenheJilu.objects.filter(
            shenqingren_id=user.UserUID,
            chenghao=chenghao,
            zhuangtai__in=[0, 3]
        ).exists()
        if has_pending:
            return False, '您有未完成的考核申请，请等待结果', None

        last_record = None
        current_fee = Decimal('0.00')

        # 4. 处理再次申请
        if reapply and jilu_id:
            # 查询原记录（未通过状态）
            last_record = ShenheJilu.objects.filter(
                jilu_id=jilu_id,
                shenqingren_id=user.UserUID,
                zhuangtai=2
            ).first()
            if not last_record:
                return False, '原记录不存在或状态不是未通过', None

            new_cishu = last_record.cishu + 1
            current_fee = get_tag_fee(chenghao, new_cishu)

            # 确定最终状态：有考核官 = 审核中(0)，否则待审核(3)
            final_kg_id = last_record.shenheguan_id  # 保留原来的
            if shenheguan_id and not last_record.shenheguan_id:
                final_kg_id = shenheguan_id            # 新指定

            final_zhuangtai = 0 if final_kg_id else 3   # 有考核官就是审核中
            if final_zhuangtai == 3:
                final_kg_id = None

            # 原子化更新
            ShenheJilu.objects.filter(pk=last_record.pk).update(
                cishu=new_cishu,
                jiaofei_jine=F('jiaofei_jine') + current_fee,
                dashou_youxi_id=game_nick,
                dashou_beizhu=remark,
                guize_neirong=chenghao.kaohe_guize or '',
                zhuangtai=final_zhuangtai,
                shenheguan_id=final_kg_id,
            )
            last_record.refresh_from_db()
            record = last_record

            # 如果原考核官被替换或清除，释放旧考核官
            if last_record.shenheguan_id != final_kg_id:
                if last_record.shenheguan_id:
                    UserShenheguan.objects.filter(
                        user__UserUID=last_record.shenheguan_id
                    ).update(shenhe_zhuangtai=0)
        else:
            # 首次申请
            max_cishu = ShenheJilu.objects.filter(
                shenqingren_id=user.UserUID,
                chenghao=chenghao,
                zhuangtai__in=[1, 2]
            ).aggregate(max=Max('cishu'))['max'] or 0
            new_cishu = max_cishu + 1
            current_fee = get_tag_fee(chenghao, new_cishu)

            bankuai = chenghao.bankuai
            rule_text = chenghao.kaohe_guize or ''
            new_jilu_id = generate_unique_jilu_id()

            initial_zhuangtai = 0 if shenheguan_id else 3   # 指定→审核中，否则待审核
            record = ShenheJilu.objects.create(
                jilu_id=new_jilu_id,
                shenqingren_id=user.UserUID,
                zhuangtai=initial_zhuangtai,
                bankuai=bankuai,
                chenghao=chenghao,
                cishu=new_cishu,
                jiaofei_jine=current_fee,
                dashou_youxi_id=game_nick,
                dashou_beizhu=remark,
                guize_neirong=rule_text,
                shenheguan_id=shenheguan_id if shenheguan_id else None,
            )

        # 5. 创建费用明细（防重复）
        KaoheJiluFeiyong.objects.get_or_create(
            jilu=record,
            cishu=record.cishu,
            defaults={'jine': current_fee}
        )

        # 6. 更新考核官统计（仅当状态为审核中且有考核官）
        if record.zhuangtai == 0 and record.shenheguan_id:
            UserShenheguan.objects.filter(
                user__UserUID=record.shenheguan_id
            ).update(
                shenhe_zongshu=F('shenhe_zongshu') + 1,
                shenhe_zhuangtai=1
            )

        return True, '申请成功', record

    except Exception as e:
        logger.error(f"创建审核记录异常: {e}", exc_info=True)
        return False, '系统异常', None











def create_shenhe_jilu_from_temp(user, temp_data):
    """
    根据临时表数据创建审核记录（专供支付回调使用）
    参数 temp_data 是 KaohePayTemp 对象
    返回 (success, message, record)
    """

    try:
        logger.info(f"开始从临时表创建审核记录: 用户={user.UserUID}, 订单={temp_data.dingdan_id}")
        
        chenghao = Chenghao.objects.get(id=temp_data.tag_id)
        logger.info(f"获取标签成功: {chenghao.mingcheng}")
        
        # 检查是否已拥有标签
        if YonghuChenghao.objects.filter(yonghu=user, chenghao=chenghao).exists():
            logger.warning(f"用户 {user.UserUID} 已拥有标签 {chenghao.mingcheng}")
            return False, '您已拥有该标签，无需重复考核', None
            
        # 检查是否有进行中的审核
        if ShenheJilu.objects.filter(
            shenqingren_id=user.UserUID,
            chenghao=chenghao,
            zhuangtai__in=[0, 3]
        ).exists():
            logger.warning(f"用户 {user.UserUID} 有未完成的考核申请")
            return False, '您有未完成的考核申请，请等待结果', None

        # 使用临时表中预计算好的次数和费用
        new_cishu = temp_data.cishu
        current_fee = temp_data.fee
        reapply = temp_data.reapply
        jilu_id = temp_data.jilu_id
        shenheguan_id = temp_data.shenheguan_id

        logger.info(f"临时表数据: cishu={new_cishu}, fee={current_fee}, reapply={reapply}, jilu_id={jilu_id}, shenheguan_id={shenheguan_id}")

        # 再次申请校验
        if reapply:
            if not jilu_id:
                logger.error("再次申请但未提供原记录ID")
                return False, '再次申请必须提供原记录ID', None
            last = ShenheJilu.objects.filter(
                jilu_id=jilu_id,
                shenqingren_id=user.UserUID,
                zhuangtai=2
            ).first()
            if not last:
                logger.error(f"原记录不存在或状态不是未通过: jilu_id={jilu_id}")
                return False, '原记录不存在或状态不是未通过', None
            if new_cishu != last.cishu + 1:
                logger.error(f"考核次数不一致: 临时表={new_cishu}, 原记录次数={last.cishu}")
                return False, '考核次数不一致', None
            logger.info(f"再次申请校验通过，原记录ID: {jilu_id}")

        # 创建或更新审核记录
        if reapply and jilu_id:
            # 更新原记录
            final_kg_id = last.shenheguan_id
            if shenheguan_id and not last.shenheguan_id:
                final_kg_id = shenheguan_id
            final_zhuangtai = 0 if final_kg_id else 3
            if final_zhuangtai == 3:
                final_kg_id = None
                
            ShenheJilu.objects.filter(pk=last.pk).update(
                cishu=new_cishu,
                jiaofei_jine=F('jiaofei_jine') + current_fee,
                dashou_youxi_id=temp_data.game_nick,
                dashou_beizhu=temp_data.remark,
                guize_neirong=chenghao.kaohe_guize or '',
                zhuangtai=final_zhuangtai,
                shenheguan_id=final_kg_id,
            )
            last.refresh_from_db()
            record = last
            
            # 释放旧考核官
            if last.shenheguan_id != final_kg_id and last.shenheguan_id:
                UserShenheguan.objects.filter(user__UserUID=last.shenheguan_id).update(shenhe_zhuangtai=0)
                logger.info(f"释放旧考核官: {last.shenheguan_id}")
                
            logger.info(f"更新审核记录成功: jilu_id={record.jilu_id}, 新次数={new_cishu}")
        else:
            # 首次申请
            bankuai = chenghao.bankuai
            rule_text = chenghao.kaohe_guize or ''
            new_jilu_id = generate_unique_jilu_id()
            initial_zhuangtai = 0 if shenheguan_id else 3
            
            record = ShenheJilu.objects.create(
                jilu_id=new_jilu_id,
                shenqingren_id=user.UserUID,
                zhuangtai=initial_zhuangtai,
                bankuai=bankuai,
                chenghao=chenghao,
                cishu=new_cishu,
                jiaofei_jine=current_fee,
                dashou_youxi_id=temp_data.game_nick,
                dashou_beizhu=temp_data.remark,
                guize_neirong=rule_text,
                shenheguan_id=shenheguan_id if shenheguan_id else None,
            )
            logger.info(f"创建审核记录成功: jilu_id={new_jilu_id}, 状态={initial_zhuangtai}")

        # 记录费用明细
        fee_detail, created = KaoheJiluFeiyong.objects.get_or_create(
            jilu=record,
            cishu=record.cishu,
            defaults={'jine': current_fee}
        )
        if created:
            logger.info(f"创建费用明细成功: 记录ID={record.jilu_id}, 金额={current_fee}")
        else:
            logger.warning(f"费用明细已存在: 记录ID={record.jilu_id}, 次数={record.cishu}")

        # 更新考核官状态
        if record.zhuangtai == 0 and record.shenheguan_id:
            UserShenheguan.objects.filter(user__UserUID=record.shenheguan_id).update(
                shenhe_zongshu=F('shenhe_zongshu') + 1,
                shenhe_zhuangtai=1
            )
            logger.info(f"更新考核官状态: {record.shenheguan_id}, 审核总数+1, 状态=忙碌")

        logger.info(f"从临时表创建审核记录完成: jilu_id={record.jilu_id}")
        return True, '申请成功', record

    except Chenghao.DoesNotExist:
        logger.error(f"标签不存在: tag_id={temp_data.tag_id}")
        return False, '标签不存在', None
    except Exception as e:
        logger.error(f"从临时表创建审核记录异常: {str(e)}", exc_info=True)
        return False, '系统异常', None        