"""商家订单操作流水：真实操作人落库（支持同一订单多次操作）。"""
import logging
from decimal import Decimal, InvalidOperation

from merchant_ops.constants import (
    ACTOR_MERCHANT,
    ACTOR_STAFF,
    ORDER_ACTION_LABELS,
)
from merchant_ops.models import MerchantOrderActionLog

logger = logging.getLogger(__name__)


def _to_decimal(amount):
    if amount is None or amount == '':
        return None
    try:
        return Decimal(str(amount))
    except (InvalidOperation, TypeError, ValueError):
        return None


def _client_ip(request):
    if request is None:
        return ''
    xff = request.META.get('HTTP_X_FORWARDED_FOR')
    if xff:
        return xff.split(',')[0].strip()
    return request.META.get('REMOTE_ADDR', '') or ''


def resolve_operator_from_request(request, merchant_id):
    """
    优先 request._staff_member（子客服代理）；否则记为商家本人。
    返回 dict: operator_user_id/operator_type/staff_member_id/role_code/role_name
    """
    mid = str(merchant_id or '').strip()
    staff_member = getattr(request, '_staff_member', None) if request is not None else None
    if staff_member is not None:
        role = getattr(staff_member, 'role', None)
        return {
            'operator_user_id': str(getattr(staff_member, 'staff_user_id', '') or ''),
            'operator_type': ACTOR_STAFF,
            'staff_member_id': getattr(staff_member, 'id', None),
            'role_code': getattr(role, 'role_code', '') or '',
            'role_name': getattr(role, 'role_name', '') or '',
        }
    # 商家本人：代理场景下 request.user 已是商家
    uid = ''
    if request is not None and getattr(request, 'user', None) is not None:
        uid = str(getattr(request.user, 'UserUID', '') or '')
    if not uid:
        uid = mid
    return {
        'operator_user_id': uid,
        'operator_type': ACTOR_MERCHANT,
        'staff_member_id': None,
        'role_code': 'OWNER',
        'role_name': '商家本人',
    }


def record_order_action(
    *,
    merchant_id,
    order_id,
    action_code,
    operator_user_id,
    operator_type,
    staff_member_id=None,
    role_code='',
    role_name='',
    amount=None,
    leixing_id=None,
    remark='',
    club_id='xq',
    request=None,
):
    """写入一条操作流水。失败只打日志，不影响主业务。"""
    try:
        oid = str(order_id or '').strip()
        mid = str(merchant_id or '').strip()
        if not oid or not mid or not operator_user_id:
            logger.warning(
                '操作流水跳过：参数不完整 merchant=%s order=%s action=%s operator=%s',
                mid, oid, action_code, operator_user_id,
            )
            return None
        code = int(action_code)
        row = MerchantOrderActionLog.objects.create(
            club_id=(club_id or 'xq')[:16],
            merchant_id=mid[:7],
            order_id=oid[:32],
            action_code=code,
            operator_user_id=str(operator_user_id)[:7],
            operator_type=(operator_type or ACTOR_MERCHANT)[:16],
            staff_member_id=staff_member_id,
            role_code=(role_code or '')[:32],
            role_name=(role_name or '')[:64],
            amount=_to_decimal(amount),
            leixing_id=int(leixing_id) if leixing_id not in (None, '') else None,
            remark=(remark or '')[:500],
        )
        logger.info(
            '【商家操作流水】写入成功 id=%s merchant=%s order=%s action=%s(%s) '
            'operator=%s type=%s role=%s amount=%s leixing=%s ip=%s',
            row.id, mid, oid, code, ORDER_ACTION_LABELS.get(code, '?'),
            operator_user_id, operator_type, role_code or role_name,
            amount, leixing_id, _client_ip(request),
        )
        return row
    except Exception:
        logger.error(
            '【商家操作流水】写入失败 merchant=%s order=%s action=%s',
            merchant_id, order_id, action_code, exc_info=True,
        )
        return None


def record_order_action_from_request(
    request,
    action_code,
    order_id,
    *,
    merchant_id=None,
    amount=None,
    leixing_id=None,
    remark='',
    club_id='xq',
):
    """从 request（含 _staff_member）自动识别操作人并落库。"""
    mid = str(merchant_id or '').strip()
    if not mid and request is not None and getattr(request, 'user', None) is not None:
        mid = str(getattr(request.user, 'UserUID', '') or '')
    op = resolve_operator_from_request(request, mid)
    return record_order_action(
        merchant_id=mid,
        order_id=order_id,
        action_code=action_code,
        operator_user_id=op['operator_user_id'],
        operator_type=op['operator_type'],
        staff_member_id=op.get('staff_member_id'),
        role_code=op.get('role_code', ''),
        role_name=op.get('role_name', ''),
        amount=amount,
        leixing_id=leixing_id,
        remark=remark,
        club_id=club_id,
        request=request,
    )


def leixing_id_from_order(order):
    if order is None:
        return None
    return getattr(order, 'ProductTypeID', None) or getattr(order, 'leixing_id', None)
