# yonghu/fadan_fenhong_utils.py
# 罚款缴纳分红处理公共方法（支持更新罚单中的申请人分红金额）

import decimal
import logging
from decimal import Decimal
from django.db import transaction
from django.core.exceptions import ObjectDoesNotExist

from dingdan.models import Fadan, FadanFenhong, FadanFenhongLilv
from yonghu.models import UserShangjia

logger = logging.getLogger(__name__)


# 身份映射字典
IDENTITY_MAP = {
    1: {'fenhong': 2, 'lilv': 1},   # 客服
    2: {'fenhong': 5, 'lilv': 2},   # 售后
    3: {'fenhong': 3, 'lilv': 3},   # 管理员
    4: {'fenhong': 4, 'lilv': 4},   # 店铺
    5: {'fenhong': 1, 'lilv': 5},   # 商家
}


def process_fadan_fenhong(fadan_id):
    """
    罚款缴纳后的分红处理（在回调中调用）
    参数：
        fadan_id: 罚单 ID
    返回：
        (success, message)
    """
    try:
        # 1. 获取罚单对象（必须是已缴纳状态）
        try:
            fadan = Fadan.objects.get(id=fadan_id, zhuangtai=2)
        except Fadan.DoesNotExist:
            logger.error(f"罚单 {fadan_id} 不存在或状态不是已缴纳")
            return False, "罚单不存在或状态异常"

        # 2. 获取申请处罚者ID和身份（源身份数字）
        shenqing_chufa = fadan.shenqing_chufa
        src_shenfen = fadan.shenqingren_shenfen

        if not shenqing_chufa:
            logger.info(f"罚单 {fadan_id} 无申请处罚者，不进行分红")
            # 即使无申请者，也可将分红金额字段设为0（默认已是0）
            return True, "无申请处罚者，无需分红"

        # 3. 映射身份数字
        if src_shenfen not in IDENTITY_MAP:
            logger.error(f"未知的申请处罚者身份: {src_shenfen}，罚单 {fadan_id}")
            return False, f"未知身份 {src_shenfen}"

        mapped = IDENTITY_MAP[src_shenfen]
        fenhong_shenfen = mapped['fenhong']   # 用于 FadanFenhong.shenfen
        lilv_shenfen = mapped['lilv']         # 用于 FadanFenhongLilv.shenfen

        # 4. 获取罚款金额
        fakuan_jine = fadan.fakuanjine
        if fakuan_jine <= 0:
            logger.info(f"罚单 {fadan_id} 罚款金额为0，不产生分红")
            fadan.shenqingren_fenhong_jine = Decimal('0.00')
            fadan.save(update_fields=['shenqingren_fenhong_jine'])
            return True, "罚款金额为0，无分红"

        # 5. 确定分红利率
        rate = _get_fenhong_rate(shenqing_chufa, fenhong_shenfen, lilv_shenfen)
        if rate is None:
            logger.warning(f"未找到身份 {src_shenfen} (映射后 fenhong_shenfen={fenhong_shenfen}, lilv_shenfen={lilv_shenfen}) 的分红利率，罚单 {fadan_id} 不进行分红")
            fadan.shenqingren_fenhong_jine = Decimal('0.00')
            fadan.save(update_fields=['shenqingren_fenhong_jine'])
            return True, "未配置分红利率，无分红"

        # 6. 计算分红金额
        fenhong_jine = (Decimal(str(fakuan_jine)) * Decimal(str(rate))).quantize(Decimal('0.01'))
        if fenhong_jine <= 0:
            logger.info(f"罚单 {fadan_id} 计算分红金额为0，无需处理")
            fadan.shenqingren_fenhong_jine = Decimal('0.00')
            fadan.save(update_fields=['shenqingren_fenhong_jine'])
            return True, "分红金额为0"

        # 7. 根据申请处罚者身份执行不同的分红逻辑
        #    src_shenfen == 5 代表商家（源身份）
        if src_shenfen == 5:
            # 商家特殊处理：只记录总额，可提现分红永远为0，直接加到商家余额
            with transaction.atomic():
                fenhong_record, created = FadanFenhong.objects.get_or_create(
                    fenhongzhe_id=shenqing_chufa,
                    shenfen=fenhong_shenfen,
                    defaults={
                        'zonge': Decimal('0.00'),
                        'ketixian_fenhong': Decimal('0.00'),
                        'fenhong_cishu': 0,
                        'yingde_lilv': rate,
                        'is_individual_rate': False
                    }
                )
                fenhong_record.zonge += fenhong_jine
                # 可提现分红不累加，保持0
                fenhong_record.fenhong_cishu += 1
                fenhong_record.save()

                # 直接增加商家余额（UserShangjia.yue）
                try:
                    shangjia = UserShangjia.objects.get(user__yonghuid=shenqing_chufa)
                    shangjia.yue += fenhong_jine
                    shangjia.save(update_fields=['yue'])
                    logger.info(f"商家 {shenqing_chufa} 余额增加 {fenhong_jine} 元")
                except UserShangjia.DoesNotExist:
                    logger.error(f"商家 {shenqing_chufa} 扩展表不存在，无法增加余额")
                    raise Exception(f"商家 {shenqing_chufa} 扩展表不存在，无法增加余额")

                # 更新罚单中的申请人分红金额
                fadan.shenqingren_fenhong_jine = fenhong_jine
                fadan.save(update_fields=['shenqingren_fenhong_jine'])

        else:
            # 其他身份（客服、售后、管理员、店铺）：同时增加总额和可提现分红
            with transaction.atomic():
                fenhong_record, created = FadanFenhong.objects.get_or_create(
                    fenhongzhe_id=shenqing_chufa,
                    shenfen=fenhong_shenfen,
                    defaults={
                        'zonge': Decimal('0.00'),
                        'ketixian_fenhong': Decimal('0.00'),
                        'fenhong_cishu': 0,
                        'yingde_lilv': rate,
                        'is_individual_rate': False
                    }
                )
                fenhong_record.zonge += fenhong_jine
                fenhong_record.ketixian_fenhong += fenhong_jine
                fenhong_record.fenhong_cishu += 1
                fenhong_record.save()

                # 更新罚单中的申请人分红金额
                fadan.shenqingren_fenhong_jine = fenhong_jine
                fadan.save(update_fields=['shenqingren_fenhong_jine'])

        logger.info(f"罚单 {fadan_id} 分红处理成功: 申请者 {shenqing_chufa}, 分红金额 {fenhong_jine} 元, 源身份 {src_shenfen}, 映射后分红身份 {fenhong_shenfen}")
        return True, "分红处理成功"

    except Exception as e:
        logger.error(f"罚单 {fadan_id} 分红处理异常: {str(e)}", exc_info=True)
        return False, f"分红处理异常: {str(e)}"


def _get_fenhong_rate(fenhongzhe_id, fenhong_shenfen, lilv_shenfen):
    """
    获取分红利率（优先使用个人单独配置，否则使用全局身份配置）
    """
    try:
        individual = FadanFenhong.objects.get(
            fenhongzhe_id=fenhongzhe_id,
            shenfen=fenhong_shenfen,
            is_individual_rate=True
        )
        return individual.yingde_lilv
    except FadanFenhong.DoesNotExist:
        pass

    try:
        global_rate = FadanFenhongLilv.objects.get(shenfen=lilv_shenfen)
        return global_rate.lilv
    except FadanFenhongLilv.DoesNotExist:
        return None