"""操作审计。"""
from decimal import Decimal

from merchant_ops.constants import ACTOR_MERCHANT, ACTOR_STAFF, AUDIT_ACTION_LABELS
from merchant_ops.models import MerchantStaffAuditLog, MerchantStaffMember


def write_audit(
    merchant_id,
    operator_user_id,
    operator_type,
    action,
    *,
    staff_member_id=None,
    resource_type='',
    resource_id='',
    value_before=None,
    value_after=None,
    amount=None,
    request_ip='',
    remark='',
):
    MerchantStaffAuditLog.objects.create(
        merchant_id=merchant_id,
        operator_user_id=operator_user_id,
        operator_type=operator_type,
        staff_member_id=staff_member_id,
        action=action,
        resource_type=resource_type,
        resource_id=str(resource_id) if resource_id else '',
        value_before=value_before,
        value_after=value_after,
        amount=Decimal(str(amount)) if amount is not None else None,
        request_ip=request_ip or '',
        remark=remark or '',
    )


def audit_staff(member, action, request, **kwargs):
    write_audit(
        member.merchant_id,
        member.staff_user_id,
        ACTOR_STAFF,
        action,
        staff_member_id=member.id,
        request_ip=_client_ip(request),
        **kwargs,
    )


def audit_owner(merchant_id, operator_id, action, request, **kwargs):
    write_audit(
        merchant_id,
        operator_id,
        ACTOR_MERCHANT,
        action,
        request_ip=_client_ip(request),
        **kwargs,
    )


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


def audit_action_label(action):
    return AUDIT_ACTION_LABELS.get(action, action)


def serialize_audit_row(row, member_map=None):
    """格式化审计记录供前端展示。"""
    member_map = member_map or {}
    label = audit_action_label(row.action)
    operator_name = '商家老板'
    role_name = ''
    if row.operator_type == ACTOR_STAFF and row.staff_member_id:
        m = member_map.get(row.staff_member_id)
        if m:
            operator_name = m.display_name or m.staff_user_id
            role_name = m.role.role_name if m.role else ''
        else:
            operator_name = row.operator_user_id
    elif row.operator_type == ACTOR_MERCHANT:
        operator_name = '商家老板'
    return {
        'id': row.id,
        'operator_user_id': row.operator_user_id,
        'operator_type': row.operator_type,
        'operator_name': operator_name,
        'role_name': role_name,
        'action': row.action,
        'action_label': label,
        'resource_type': row.resource_type,
        'resource_id': row.resource_id,
        'amount': str(row.amount) if row.amount is not None else '',
        'remark': row.remark,
        'time': row.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if row.CreateTime else '',
    }
