import logging
from datetime import date
from decimal import Decimal
from django.db import transaction
from django.db.models import F
from .models import ShangpinMeiriTongji
from products.models import Shangpin

logger = logging.getLogger(__name__)


def update_shangpin_daily_stat(
    shangpin_id,
    caozuo_leixing,
    dingdan_jiage=Decimal('0.00'),
    pingtai_shouyi=Decimal('0.00'),
    dianpu_zongshouyi=Decimal('0.00')
):
    """
    原子更新商品每日统计数据（高并发安全，无店铺关联）

    参数:
        shangpin_id: 商品ID (int)
        caozuo_leixing: 操作类型
                        1 = 下单（点单）
                        2 = 结算（成交）
                        3 = 退款
        dingdan_jiage: 订单金额（商品价格），默认0.00
        pingtai_shouyi: 平台收益金额，默认0.00
        dianpu_zongshouyi: 店铺总收益金额，默认0.00

    注意:
        - 金额若小于0则自动设为0
        - 日期自动取当天
        - 使用 select_for_update 配合事务，保证并发时数据绝对准确
        - 若商品不存在，仅记录日志不中断主流程
    """
    # 参数归一化与合法性处理
    dingdan_jiage = Decimal(str(dingdan_jiage)) if dingdan_jiage else Decimal('0.00')
    pingtai_shouyi = Decimal(str(pingtai_shouyi)) if pingtai_shouyi else Decimal('0.00')
    dianpu_zongshouyi = Decimal(str(dianpu_zongshouyi)) if dianpu_zongshouyi else Decimal('0.00')

    if dingdan_jiage < 0:
        dingdan_jiage = Decimal('0.00')
    if pingtai_shouyi < 0:
        pingtai_shouyi = Decimal('0.00')
    if dianpu_zongshouyi < 0:
        dianpu_zongshouyi = Decimal('0.00')

    today = date.today()

    # 校验商品是否存在（不加锁，仅校验）
    if not Shangpin.objects.filter(id=shangpin_id).exists():
        logger.error(f"商品ID {shangpin_id} 不存在，统计更新失败")
        return

    # 开启事务，使用行锁确保并发安全
    with transaction.atomic():
        # 获取或创建统计记录，并锁定该行
        tongji, created = ShangpinMeiriTongji.objects.select_for_update().get_or_create(
            shangpin_id=shangpin_id,
            riqi=today,
            defaults={
                'nian': today.year,
                'yue': today.month,
                'ri': today.day,
                'diandan_zongliang': 0,
                'diandan_zonge': Decimal('0.00'),
                'chengjiao_zongliang': 0,
                'chengjiao_zonge': Decimal('0.00'),
                'tuikuan_zongliang': 0,
                'tuikuan_zonge': Decimal('0.00'),
                'pingtai_shouyi': Decimal('0.00'),
                'dianpu_zongshouyi': Decimal('0.00'),
            }
        )

        # 根据操作类型构建更新字段（使用 F 表达式累加）
        update_fields = {}

        if caozuo_leixing == 1:  # 下单
            update_fields['diandan_zongliang'] = F('diandan_zongliang') + 1
            update_fields['diandan_zonge'] = F('diandan_zonge') + dingdan_jiage

        elif caozuo_leixing == 2:  # 结算（成交）
            update_fields['chengjiao_zongliang'] = F('chengjiao_zongliang') + 1
            update_fields['chengjiao_zonge'] = F('chengjiao_zonge') + dingdan_jiage
            # 收益直接累加传入值
            update_fields['pingtai_shouyi'] = F('pingtai_shouyi') + pingtai_shouyi
            update_fields['dianpu_zongshouyi'] = F('dianpu_zongshouyi') + dianpu_zongshouyi

        elif caozuo_leixing == 3:  # 退款
            update_fields['tuikuan_zongliang'] = F('tuikuan_zongliang') + 1
            update_fields['tuikuan_zonge'] = F('tuikuan_zonge') + dingdan_jiage
            # 退款是否应扣减收益？根据业务需求决定，此处暂不处理收益字段

        else:
            logger.warning(f"未知的操作类型: {caozuo_leixing}")
            return

        # 原子更新字段
        if update_fields:
            for field, value in update_fields.items():
                setattr(tongji, field, value)
            tongji.save(update_fields=list(update_fields.keys()))

        logger.info(
            f"商品统计更新: 商品ID={shangpin_id}, 操作类型={caozuo_leixing}, "
            f"订单金额={dingdan_jiage}, 平台收益={pingtai_shouyi}, "
            f"店铺收益={dianpu_zongshouyi}, 日期={today}"
        )