package com.erp.aftersale.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.aftersale.client.FinanceClient;
import com.erp.aftersale.client.InventoryClient;
import com.erp.aftersale.client.OrderClient;
import com.erp.aftersale.dto.request.AfterSaleCreateRequest;
import com.erp.aftersale.dto.request.AfterSaleQueryRequest;
import com.erp.aftersale.dto.request.AfterSaleStatusUpdateRequest;
import com.erp.aftersale.dto.response.*;
import com.erp.aftersale.entity.AfterSale;
import com.erp.aftersale.entity.AfterSaleItem;
import com.erp.aftersale.entity.AfterSaleOperationLog;
import com.erp.aftersale.exception.AfterSaleException;
import com.erp.aftersale.repository.AfterSaleItemMapper;
import com.erp.aftersale.repository.AfterSaleLogMapper;
import com.erp.aftersale.repository.AfterSaleMapper;
import com.erp.aftersale.service.AfterSaleService;
import com.erp.aftersale.statemachine.AfterSaleStatusMachine;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import com.erp.common.core.model.PageResponse;

@Slf4j
@Service
@RequiredArgsConstructor
public class AfterSaleServiceImpl implements AfterSaleService {

    private final AfterSaleMapper afterSaleMapper;
    private final AfterSaleItemMapper afterSaleItemMapper;
    private final AfterSaleLogMapper afterSaleLogMapper;
    private final OrderClient orderClient;
    private final InventoryClient inventoryClient;
    private final FinanceClient financeClient;
    private final AfterSaleStatusMachine statusMachine;
    private final ObjectMapper objectMapper;

    private static final DateTimeFormatter SHORT_ID_DATE = DateTimeFormatter.ofPattern("yyyyMMdd");

    // ============ 查询 ============

    @Override
    public PageResponse<AfterSaleResponse> listAfterSales(AfterSaleQueryRequest request) {
        Page<AfterSale> page = new Page<>(request.getPage(), request.getPageSize());
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<AfterSale> wrapper =
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        if (request.getShortId() != null && !request.getShortId().isEmpty()) {
            wrapper.like(AfterSale::getShortId, request.getShortId());
        }
        if (request.getOrderId() != null) {
            wrapper.eq(AfterSale::getOrderId, request.getOrderId());
        }
        if (request.getOrderShortId() != null && !request.getOrderShortId().isEmpty()) {
            wrapper.like(AfterSale::getOrderShortId, request.getOrderShortId());
        }
        if (request.getPlatformOrderSn() != null && !request.getPlatformOrderSn().isEmpty()) {
            wrapper.eq(AfterSale::getPlatformOrderSn, request.getPlatformOrderSn());
        }
        if (request.getType() != null && !request.getType().isEmpty()) {
            wrapper.eq(AfterSale::getType, request.getType());
        }
        if (request.getStatus() != null && !request.getStatus().isEmpty()) {
            wrapper.eq(AfterSale::getStatus, request.getStatus());
        }
        if (request.getAuditStatus() != null && !request.getAuditStatus().isEmpty()) {
            wrapper.eq(AfterSale::getAuditStatus, request.getAuditStatus());
        }
        if (request.getCustomerId() != null) {
            wrapper.eq(AfterSale::getCustomerId, request.getCustomerId());
        }
        if (request.getShopId() != null) {
            wrapper.eq(AfterSale::getShopId, request.getShopId());
        }
        wrapper.orderByDesc(AfterSale::getCreatedAt);
        IPage<AfterSale> result = afterSaleMapper.selectPage(page, wrapper);
        List<AfterSaleResponse> list = result.getRecords().stream()
                .map(this::toResponse)
                .collect(Collectors.toList());
        return PageResponse.of(result.getTotal(), (int) result.getCurrent(), (int) result.getSize(), list);
    }

    @Override
    public AfterSaleResponse getAfterSale(Long id) {
        AfterSale afterSale = afterSaleMapper.selectById(id);
        if (afterSale == null) {
            throw new AfterSaleException("售后单不存在: " + id);
        }
        return toResponse(afterSale);
    }

    @Override
    public AfterSaleResponse getAfterSaleByShortId(String shortId) {
        AfterSale afterSale = afterSaleMapper.selectByShortId(shortId);
        if (afterSale == null) {
            throw new AfterSaleException("售后单不存在: " + shortId);
        }
        return toResponse(afterSale);
    }

    @Override
    public List<OperationLogResponse> getLogs(Long afterSaleId) {
        List<AfterSaleOperationLog> logs = afterSaleLogMapper.selectByAfterSaleId(afterSaleId);
        return logs.stream().map(log -> OperationLogResponse.builder()
                .id(log.getId())
                .afterSaleId(log.getAfterSaleId())
                .operatorId(log.getOperatorId())
                .operatorName(log.getOperatorName())
                .operatorType(log.getOperatorType())
                .action(log.getAction())
                .fromStatus(log.getFromStatus())
                .toStatus(log.getToStatus())
                .content(log.getContent())
                .ip(log.getIp())
                .createdAt(log.getCreatedAt())
                .build())
                .collect(Collectors.toList());
    }

    // ============ 创建 ============

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AfterSaleResponse createAfterSale(AfterSaleCreateRequest request, OperatorInfo operator) {
        // 1. 校验订单存在性
        ApiResponse<?> orderResp = orderClient.getOrder(request.getOrderId());
        if (orderResp == null || orderResp.getCode() != 200) {
            throw new AfterSaleException("关联订单不存在或无法访问: " + request.getOrderId());
        }

        // 2. 校验售后类型
        validateType(request.getType());

        // 3. 生成短ID
        String shortId = generateShortId();

        // 4. 构建售后单
        AfterSale afterSale = AfterSale.builder()
                .shortId(shortId)
                .orderId(request.getOrderId())
                .type(request.getType())
                .reason(request.getReason())
                .reasonDetail(request.getReasonDetail())
                .description(request.getDescription())
                .applyAmount(request.getApplyAmount())
                .freightRefund(request.getFreightRefund() != null ? request.getFreightRefund() : BigDecimal.ZERO)
                .status(AfterSale.STATUS_PENDING)
                .auditStatus(AfterSale.AUDIT_PENDING)
                .images(toImagesJson(request.getImages()))
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
                .build();

        afterSaleMapper.insert(afterSale);

        // 5. 保存明细
        if (request.getItems() != null && !request.getItems().isEmpty()) {
            for (AfterSaleCreateRequest.AfterSaleItemRequest itemReq : request.getItems()) {
                AfterSaleItem item = AfterSaleItem.builder()
                        .afterSaleId(afterSale.getId())
                        .orderItemId(itemReq.getOrderItemId())
                        .productId(itemReq.getProductId())
                        .skuId(itemReq.getSkuId())
                        .applyQuantity(itemReq.getApplyQuantity())
                        .itemAmount(itemReq.getApplyAmount())
                        .createdAt(LocalDateTime.now())
                        .updatedAt(LocalDateTime.now())
                        .build();
                afterSaleItemMapper.insert(item);
            }
        }

        // 6. 记录操作日志
        saveOperationLog(afterSale.getId(), operator, AfterSaleOperationLog.ACTION_CREATE,
                null, AfterSale.STATUS_PENDING,
                "创建售后单，类型：" + getTypeDesc(request.getType()));

        log.info("[售后] 创建售后单成功 id={} shortId={} type={}", afterSale.getId(), shortId, request.getType());
        return toResponse(afterSale);
    }

    // ============ 状态更新 ============

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AfterSaleResponse updateStatus(Long id, AfterSaleStatusUpdateRequest request, OperatorInfo operator) {
        AfterSale afterSale = afterSaleMapper.selectById(id);
        if (afterSale == null) {
            throw new AfterSaleException("售后单不存在: " + id);
        }

        String newStatus = request.getStatus();
        validateStatusTransition(afterSale, newStatus);

        String fromStatus = afterSale.getStatus();
        afterSale.setStatus(newStatus);
        afterSale.setUpdatedAt(LocalDateTime.now());

        // 审核信息
        if (AfterSale.STATUS_APPROVED.equals(newStatus) || AfterSale.STATUS_REJECTED.equals(newStatus)) {
            afterSale.setAuditStatus(AfterSale.STATUS_APPROVED.equals(newStatus) ? AfterSale.AUDIT_APPROVED : AfterSale.AUDIT_REJECTED);
            afterSale.setAuditComment(request.getComment());
            afterSale.setAuditorId(operator.getOperatorId());
            afterSale.setAuditorName(operator.getOperatorName());
            afterSale.setAuditTime(LocalDateTime.now());
            if (request.getApproveAmount() != null) {
                afterSale.setApproveAmount(request.getApproveAmount());
            }
        }

        // 收到退货
        if ("received".equals(newStatus)) {
            afterSale.setReceiveTime(LocalDateTime.now());
            afterSale.setReceiveComment(request.getReceiveComment());
        }

        // 完成
        if (AfterSale.STATUS_COMPLETED.equals(newStatus)) {
            afterSale.setCompleteTime(LocalDateTime.now());
            afterSale.setRefundTime(LocalDateTime.now());
        }

        // 关闭
        if (AfterSale.STATUS_CLOSED.equals(newStatus)) {
            afterSale.setCloseTime(LocalDateTime.now());
            afterSale.setCloseReason(request.getCloseReason());
        }

        // 退货快递
        if (StrUtil.isNotBlank(request.getReturnTrackingNo())) {
            afterSale.setReturnTrackingNo(request.getReturnTrackingNo());
            afterSale.setReturnExpressCompany(request.getReturnExpressCompany());
        }

        afterSaleMapper.updateById(afterSale);

        // 联动：审核通过后
        if (AfterSale.STATUS_APPROVED.equals(newStatus)) {
            handleAfterApproval(afterSale, operator);
        }

        // 联动：完成/关闭时回写订单
        if (AfterSale.STATUS_COMPLETED.equals(newStatus) || AfterSale.STATUS_CLOSED.equals(newStatus)) {
            notifyOrderStatus(afterSale);
        }

        saveOperationLog(afterSale.getId(), operator, AfterSaleOperationLog.ACTION_UPDATE,
                fromStatus, newStatus, request.getComment());

        log.info("[售后] 更新售后单状态 id={} {} -> {}", id, fromStatus, newStatus);
        return toResponse(afterSale);
    }

    @Override
    public AfterSaleResponse approve(Long id, AfterSaleStatusUpdateRequest request, OperatorInfo operator) {
        request.setStatus(AfterSale.STATUS_APPROVED);
        return updateStatus(id, request, operator);
    }

    @Override
    public AfterSaleResponse reject(Long id, AfterSaleStatusUpdateRequest request, OperatorInfo operator) {
        request.setStatus(AfterSale.STATUS_REJECTED);
        return updateStatus(id, request, operator);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AfterSaleResponse executeRefund(Long id, OperatorInfo operator) {
        AfterSale afterSale = afterSaleMapper.selectById(id);
        if (afterSale == null) {
            throw new AfterSaleException("售后单不存在: " + id);
        }

        if (!AfterSale.STATUS_APPROVED.equals(afterSale.getStatus())
                && !AfterSale.STATUS_PROCESSING.equals(afterSale.getStatus())) {
            throw new AfterSaleException("当前状态不允许执行退款: " + afterSale.getStatus());
        }

        BigDecimal refundAmount = afterSale.getApproveAmount() != null
                ? afterSale.getApproveAmount()
                : afterSale.getApplyAmount();

        Map<String, Object> refundRequest = new HashMap<>();
        refundRequest.put("orderId", afterSale.getOrderId());
        refundRequest.put("afterSaleId", afterSale.getId());
        refundRequest.put("amount", refundAmount);
        refundRequest.put("type", afterSale.getType());
        refundRequest.put("operatorId", operator.getOperatorId());

        try {
            ApiResponse<?> financeResp = financeClient.createRefund(refundRequest);
            if (financeResp != null && financeResp.getCode() == 200) {
                afterSale.setStatus(AfterSale.STATUS_COMPLETED);
                afterSale.setActualRefund(refundAmount);
                afterSale.setCompleteTime(LocalDateTime.now());
                afterSale.setRefundTime(LocalDateTime.now());
                afterSale.setUpdatedAt(LocalDateTime.now());
                afterSaleMapper.updateById(afterSale);

                saveOperationLog(afterSale.getId(), operator, AfterSaleOperationLog.ACTION_REFUND,
                        AfterSale.STATUS_APPROVED, AfterSale.STATUS_COMPLETED,
                        "执行退款，退款金额：" + refundAmount);

                // 退货/换货回写库存
                if (AfterSale.TYPE_RETURN.equals(afterSale.getType())
                        || AfterSale.TYPE_EXCHANGE.equals(afterSale.getType())) {
                    releaseInventory(afterSale);
                }

                log.info("[售后] 退款成功 id={} amount={}", id, refundAmount);
            } else {
                throw new AfterSaleException("财务服务退款失败: " + (financeResp != null ? financeResp.getMessage() : "未知错误"));
            }
        } catch (AfterSaleException e) {
            throw e;
        } catch (Exception e) {
            log.error("[售后] 调用财务服务退款异常 id={}", id, e);
            throw new AfterSaleException("退款失败: " + e.getMessage());
        }

        return toResponse(afterSale);
    }

    // ============ 删除 ============

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAfterSale(Long id, OperatorInfo operator) {
        AfterSale afterSale = afterSaleMapper.selectById(id);
        if (afterSale == null) {
            throw new AfterSaleException("售后单不存在: " + id);
        }
        if (!AfterSale.STATUS_PENDING.equals(afterSale.getStatus())) {
            throw new AfterSaleException("仅待审核状态的售后单可删除，当前状态: " + afterSale.getStatus());
        }
        afterSaleMapper.deleteById(id);
        saveOperationLog(afterSale.getId(), operator, "delete",
                afterSale.getStatus(), "deleted", "删除售后单");
        log.info("[售后] 删除售后单 id={}", id);
        return true;
    }

    // ============ 可售后订单 ============

    @Override
    public PageResponse<?> getAvailableOrders(AfterSaleQueryRequest request) {
        int page = request.getPage() == null ? 1 : request.getPage();
        int pageSize = request.getPageSize() == null ? 20 : request.getPageSize();
        ApiResponse<?> resp = orderClient.listAvailableOrders("shipped", page, pageSize);
        if (resp != null && resp.getCode() == 200) {
            return (PageResponse<?>) resp.getData();
        }
        return PageResponse.of(0L, 1, 20, Collections.emptyList());
    }

    @Override
    public PageResponse<?> getAllAvailableOrders(AfterSaleQueryRequest request) {
        int page = request.getPage() == null ? 1 : request.getPage();
        int pageSize = request.getPageSize() == null ? 20 : request.getPageSize();
        ApiResponse<?> resp = orderClient.listAvailableOrders(null, page, pageSize);
        if (resp != null && resp.getCode() == 200) {
            return (PageResponse<?>) resp.getData();
        }
        return PageResponse.of(0L, 1, 20, Collections.emptyList());
    }

    // ============ 统计 ============

    @Override
    public AfterSaleStatsResponse getStats() {
        return AfterSaleStatsResponse.builder()
                .totalCount(countAll())
                .pendingCount(afterSaleMapper.countByStatus(AfterSale.STATUS_PENDING))
                .approvedCount(afterSaleMapper.countByStatus(AfterSale.STATUS_APPROVED))
                .processingCount(afterSaleMapper.countByStatus(AfterSale.STATUS_PROCESSING))
                .completedCount(afterSaleMapper.countByStatus(AfterSale.STATUS_COMPLETED))
                .rejectedCount(afterSaleMapper.countByStatus(AfterSale.STATUS_REJECTED))
                .totalApplyAmount(afterSaleMapper.sumApplyAmount())
                .totalActualRefund(afterSaleMapper.sumActualRefund())
                .byType(countGroupByType())
                .byStatus(countGroupByStatus())
                .build();
    }

    // ============ 内部方法 ============

    @Override
    public String generateShortId() {
        String date = LocalDateTime.now().format(SHORT_ID_DATE);
        String random = UUID.randomUUID().toString().replace("-", "").substring(0, 6).toUpperCase();
        return "AS" + date + random;
    }

    @Override
    public void validateStatusTransition(AfterSale afterSale, String newStatus) {
        if (!statusMachine.canTransition(afterSale.getStatus(), newStatus)) {
            throw new AfterSaleException(
                    String.format("状态流转非法: %s -> %s", afterSale.getStatus(), newStatus));
        }
    }

    // ============ 私有方法 ============

    private Long countAll() {
        // Use BaseMapper's selectCount for total
        return afterSaleMapper.selectCount(null);
    }

    private Map<String, Long> countGroupByType() {
        List<Map<String, Object>> rows = afterSaleMapper.countGroupByType();
        Map<String, Long> result = new HashMap<>();
        for (Map<String, Object> row : rows) {
            result.put(String.valueOf(row.get("type")), ((Number) row.get("count")).longValue());
        }
        return result;
    }

    private Map<String, Long> countGroupByStatus() {
        List<Map<String, Object>> rows = afterSaleMapper.countGroupByStatus();
        Map<String, Long> result = new HashMap<>();
        for (Map<String, Object> row : rows) {
            result.put(String.valueOf(row.get("status")), ((Number) row.get("count")).longValue());
        }
        return result;
    }

    private void handleAfterApproval(AfterSale afterSale, OperatorInfo operator) {
        String type = afterSale.getType();
        if (AfterSale.TYPE_REFUND.equals(type)) {
            executeRefund(afterSale.getId(), operator);
        } else {
            afterSale.setStatus(AfterSale.STATUS_PROCESSING);
            afterSale.setUpdatedAt(LocalDateTime.now());
            afterSaleMapper.updateById(afterSale);
        }
    }

    private void notifyOrderStatus(AfterSale afterSale) {
        try {
            Map<String, Object> req = new HashMap<>();
            req.put("afterSaleId", afterSale.getId());
            req.put("afterSaleType", afterSale.getType());
            req.put("status", afterSale.getStatus());
            orderClient.updateOrderStatus(afterSale.getOrderId(), req);
        } catch (Exception e) {
            log.warn("[售后] 回写订单状态失败 afterSaleId={}", afterSale.getId(), e);
        }
    }

    private void releaseInventory(AfterSale afterSale) {
        try {
            List<AfterSaleItem> items = afterSaleItemMapper.selectByAfterSaleId(afterSale.getId());
            for (AfterSaleItem item : items) {
                Map<String, Object> req = new HashMap<>();
                req.put("skuId", item.getSkuId());
                req.put("quantity", item.getApproveQuantity() != null ? item.getApproveQuantity() : item.getApplyQuantity());
                req.put("orderId", afterSale.getOrderId());
                req.put("afterSaleId", afterSale.getId());
                inventoryClient.returnIn(req);
            }
        } catch (Exception e) {
            log.warn("[售后] 回写库存失败 afterSaleId={}", afterSale.getId(), e);
        }
    }

    private void saveOperationLog(Long afterSaleId, OperatorInfo operator, String action,
                                  String fromStatus, String toStatus, String content) {
        try {
            AfterSaleOperationLog logEntry = AfterSaleOperationLog.builder()
                    .afterSaleId(afterSaleId)
                    .operatorId(operator != null ? operator.getOperatorId() : 0L)
                    .operatorName(operator != null ? operator.getOperatorName() : "SYSTEM")
                    .operatorType("user")
                    .action(action)
                    .fromStatus(fromStatus)
                    .toStatus(toStatus)
                    .content(content)
                    .ip(operator != null ? operator.getIp() : null)
                    .createdAt(LocalDateTime.now())
                    .build();
            afterSaleLogMapper.insert(logEntry);
        } catch (Exception e) {
            log.warn("[售后] 记录操作日志失败 afterSaleId={}", afterSaleId, e);
        }
    }

    private void validateType(String type) {
        if (type == null || (!type.equals(AfterSale.TYPE_REFUND)
                && !type.equals(AfterSale.TYPE_RETURN)
                && !type.equals(AfterSale.TYPE_EXCHANGE)
                && !type.equals(AfterSale.TYPE_REPAIR))) {
            throw new AfterSaleException("无效的售后类型: " + type);
        }
    }

    private String toImagesJson(List<String> images) {
        if (images == null || images.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(images);
        } catch (Exception e) {
            return null;
        }
    }

    private List<String> fromImagesJson(String images) {
        if (StrUtil.isBlank(images)) {
            return Collections.emptyList();
        }
        try {
            return objectMapper.readValue(images, new TypeReference<List<String>>() {});
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    private AfterSaleResponse toResponse(AfterSale afterSale) {
        AfterSaleResponse resp = AfterSaleResponse.builder()
                .id(afterSale.getId())
                .shortId(afterSale.getShortId())
                .orderId(afterSale.getOrderId())
                .orderShortId(afterSale.getOrderShortId())
                .platformOrderSn(afterSale.getPlatformOrderSn())
                .shopId(afterSale.getShopId())
                .shopName(afterSale.getShopName())
                .customerId(afterSale.getCustomerId())
                .customerName(afterSale.getCustomerName())
                .customerPhone(afterSale.getCustomerPhone())
                .type(afterSale.getType())
                .typeDesc(getTypeDesc(afterSale.getType()))
                .reason(afterSale.getReason())
                .reasonDetail(afterSale.getReasonDetail())
                .description(afterSale.getDescription())
                .applyAmount(afterSale.getApplyAmount())
                .approveAmount(afterSale.getApproveAmount())
                .freightRefund(afterSale.getFreightRefund())
                .actualRefund(afterSale.getActualRefund())
                .status(afterSale.getStatus())
                .statusDesc(getStatusDesc(afterSale.getStatus()))
                .auditStatus(afterSale.getAuditStatus())
                .auditStatusDesc(getAuditStatusDesc(afterSale.getAuditStatus()))
                .previousStatus(afterSale.getPreviousStatus())
                .auditComment(afterSale.getAuditComment())
                .auditorId(afterSale.getAuditorId())
                .auditorName(afterSale.getAuditorName())
                .auditTime(afterSale.getAuditTime())
                .refundTime(afterSale.getRefundTime())
                .returnTrackingNo(afterSale.getReturnTrackingNo())
                .returnExpressCompany(afterSale.getReturnExpressCompany())
                .receiveTime(afterSale.getReceiveTime())
                .receiveComment(afterSale.getReceiveComment())
                .completeTime(afterSale.getCompleteTime())
                .closeTime(afterSale.getCloseTime())
                .closeReason(afterSale.getCloseReason())
                .images(fromImagesJson(afterSale.getImages()))
                .exchangeOrderId(afterSale.getExchangeOrderId())
                .repairOrderId(afterSale.getRepairOrderId())
                .financeRefundId(afterSale.getFinanceRefundId())
                .createdAt(afterSale.getCreatedAt())
                .updatedAt(afterSale.getUpdatedAt())
                .build();

        // 加载明细
        try {
            List<AfterSaleItem> items = afterSaleItemMapper.selectByAfterSaleId(afterSale.getId());
            resp.setItems(items.stream().map(item -> AfterSaleItemResponse.builder()
                    .id(item.getId())
                    .afterSaleId(item.getAfterSaleId())
                    .orderItemId(item.getOrderItemId())
                    .productId(item.getProductId())
                    .productName(item.getProductName())
                    .skuId(item.getSkuId())
                    .skuCode(item.getSkuCode())
                    .skuSpecs(item.getSkuSpecs())
                    .imageUrl(item.getImageUrl())
                    .unitPrice(item.getUnitPrice())
                    .quantity(item.getQuantity())
                    .applyQuantity(item.getApplyQuantity())
                    .approveQuantity(item.getApproveQuantity())
                    .returnQuantity(item.getReturnQuantity())
                    .itemAmount(item.getItemAmount())
                    .build())
                    .collect(Collectors.toList()));
        } catch (Exception e) {
            log.warn("加载售后明细失败 id={}", afterSale.getId());
        }

        return resp;
    }

    private String getTypeDesc(String type) {
        return switch (type) {
            case AfterSale.TYPE_REFUND -> "仅退款";
            case AfterSale.TYPE_RETURN -> "退货退款";
            case AfterSale.TYPE_EXCHANGE -> "换货";
            case AfterSale.TYPE_REPAIR -> "维修";
            default -> type;
        };
    }

    private String getStatusDesc(String status) {
        return switch (status) {
            case AfterSale.STATUS_PENDING -> "待审核";
            case AfterSale.STATUS_APPROVED -> "已通过";
            case AfterSale.STATUS_REJECTED -> "已驳回";
            case AfterSale.STATUS_PROCESSING -> "处理中";
            case AfterSale.STATUS_COMPLETED -> "已完成";
            case AfterSale.STATUS_CLOSED -> "已关闭";
            default -> status;
        };
    }

    private String getAuditStatusDesc(String auditStatus) {
        return switch (auditStatus) {
            case AfterSale.AUDIT_PENDING -> "待审核";
            case AfterSale.AUDIT_APPROVED -> "已通过";
            case AfterSale.AUDIT_REJECTED -> "已驳回";
            default -> auditStatus;
        };
    }
}
