"""商家发单退款审核通过（与 KefuMerchantRefundView / 后台同意退款业务一致）。"""
import logging
from decimal import Decimal

from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction

from backend.utils import update_dashou_daily_by_action, update_shangjia_daily
from orders.models import Order, RefundRecord
from users.business_models import User

logger = logging.getLogger(__name__)

# tuikuanjilu.chuliid / RefundRecord.ProcessorID 数据库列最长 11
PROCESSOR_ID_MAX_LEN = 11


def normalize_processor_id(processor_id, *, default='138377'):
    """处理人 ID 须 <=11 位（与客服手机号字段一致），超长则截断。"""
    val = (processor_id or default or '').strip()
    if not val:
        val = default
    if len(val) > PROCESSOR_ID_MAX_LEN:
        logger.warning(
            'processor_id 超长已截断: %s -> %s',
            val, val[:PROCESSOR_ID_MAX_LEN],
        )
        val = val[:PROCESSOR_ID_MAX_LEN]
    return val


class MerchantRefundApproveError(Exception):
    """单笔商家退款同意失败。"""


def approve_merchant_refund_order(
    order,
    *,
    processor_id='138377',
    tuikuan_liyou='',
    require_status_4=True,
):
    """
    同意商家发单退款（Platform=2）。

    与 POST /yonghu/kefusjtk 核心事务一致：
    - 订单 Status → 5（已退款）
    - 打手 tuikuanliang+1、zhuangtai=1
    - 商家 tuikuan+1、余额+订单金额（子客服额度单除外）
    - RefundRecord ApplyStatus → 1
    - update_shangjia_daily(action=3)、update_dashou_daily_by_action(action=3)

    返回 (True, 'ok')；失败抛 MerchantRefundApproveError。
    """
    dingdan_id = order.OrderID
    processor_id = normalize_processor_id(processor_id)

    if order.Platform != 2:
        raise MerchantRefundApproveError(f'订单 {dingdan_id} 不是商家发单(Platform=2)')

    if require_status_4 and order.Status != 4:
        raise MerchantRefundApproveError(
            f'订单 {dingdan_id} 状态={order.Status}，非退款审核中(4)',
        )
    if not require_status_4 and order.Status not in (1, 7, 2, 8, 4):
        raise MerchantRefundApproveError(
            f'订单 {dingdan_id} 状态={order.Status}，不允许退款',
        )

    jine = order.Amount
    if jine is None:
        raise MerchantRefundApproveError(f'订单 {dingdan_id} 缺少订单金额')

    try:
        shangjia_id = order.shangjia_kuozhan.MerchantID
    except ObjectDoesNotExist as exc:
        raise MerchantRefundApproveError(f'订单 {dingdan_id} 缺少商家扩展信息') from exc

    jiedan_dashou_id = order.PlayerID

    with transaction.atomic():
        locked = Order.objects.select_for_update().select_related('shangjia_kuozhan').get(
            pk=order.pk,
        )
        if require_status_4 and locked.Status != 4:
            raise MerchantRefundApproveError(
                f'订单 {dingdan_id} 并发冲突：当前状态={locked.Status}',
            )
        if locked.Platform != 2:
            raise MerchantRefundApproveError(f'订单 {dingdan_id} 不是商家发单')

        locked.Status = 5
        if tuikuan_liyou:
            locked.RefundReason = tuikuan_liyou
        if processor_id:
            locked.AssignedCS = processor_id
        locked.save(update_fields=['Status', 'RefundReason', 'AssignedCS', 'UpdateTime'])

        if jiedan_dashou_id:
            try:
                dashou_user = User.objects.select_for_update().get(UserUID=jiedan_dashou_id)
                dashou_profile = dashou_user.DashouProfile
                dashou_profile.tuikuanliang += 1
                dashou_profile.zhuangtai = 1
                dashou_profile.save(update_fields=['tuikuanliang', 'zhuangtai'])
            except (User.DoesNotExist, ObjectDoesNotExist):
                logger.warning('商家退款：打手 %s 不存在，跳过', jiedan_dashou_id)

        from merchant_ops.services.wallet import is_staff_quota_order

        try:
            shangjia_user = User.objects.select_for_update().get(UserUID=shangjia_id)
            shangjia_profile = shangjia_user.ShopProfile
            shangjia_profile.tuikuan += 1
            if not is_staff_quota_order(dingdan_id):
                shangjia_profile.yue += jine
            shangjia_profile.save(update_fields=['tuikuan', 'yue'])
        except (User.DoesNotExist, ObjectDoesNotExist):
            logger.warning('商家退款：商家 %s 不存在，跳过', shangjia_id)

        try:
            refund_record = RefundRecord.objects.select_for_update().get(OrderID=dingdan_id)
            refund_record.ApplyStatus = 1
            refund_record.ProcessorID = processor_id
            refund_record.save(update_fields=['ApplyStatus', 'ProcessorID', 'UpdateTime'])
        except RefundRecord.DoesNotExist:
            logger.warning('商家退款：订单 %s 无 RefundRecord，跳过更新', dingdan_id)

        update_shangjia_daily(
            yonghuid=shangjia_id,
            amount=Decimal(str(jine)),
            action=3,
            order_id=dingdan_id,
        )

        if jiedan_dashou_id and order.PlayerCommission is not None:
            try:
                update_dashou_daily_by_action(
                    yonghuid=jiedan_dashou_id,
                    amount=order.PlayerCommission,
                    action=3,
                )
            except Exception as exc:
                logger.error('打手每日统计更新失败 order=%s err=%s', dingdan_id, exc)

    logger.info('同意商家退款成功 order=%s processor=%s', dingdan_id, processor_id)
    return True, 'ok'
