package org.dromara.main.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.main.domain.MainBackCandidate;
import org.dromara.main.domain.MainBackCategory;
import org.dromara.main.domain.MainBackClause;
import org.dromara.main.domain.MainBackOrder;
import org.dromara.main.domain.MainBackRecord;
import org.dromara.main.domain.MainOrder;
import org.dromara.main.domain.bo.MainBackOrderBo;
import org.dromara.main.domain.bo.PortalCheckOrderCreateBo;
import org.dromara.main.domain.MainStudent;
import org.dromara.main.domain.Payment;
import org.dromara.main.domain.vo.MainBackClauseVo;
import org.dromara.main.domain.vo.MainBackOrderCandidateVo;
import org.dromara.main.domain.vo.MainBackOrderVo;
import org.dromara.main.mapper.MainBackCandidateMapper;
import org.dromara.main.mapper.MainBackCategoryMapper;
import org.dromara.main.mapper.MainBackClauseMapper;
import org.dromara.main.mapper.MainBackOrderMapper;
import org.dromara.main.mapper.MainBackRecordMapper;
import org.dromara.main.mapper.MainOrderMapper;
import org.dromara.main.mapper.MainStudentMapper;
import org.dromara.main.mapper.PaymentMapper;
import org.dromara.main.service.ICompanyAccountService;
import org.dromara.main.service.IMainBackOrderService;
import org.dromara.system.domain.SysTenant;
import org.dromara.system.domain.bo.SysTenantBo;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.mapper.SysTenantMapper;
import org.dromara.system.service.ISysTenantService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class MainBackOrderServiceImpl implements IMainBackOrderService {

    private final MainBackOrderMapper baseMapper;
    private final MainBackRecordMapper recordMapper;
    private final MainOrderMapper mainOrderMapper;
    private final MainBackCategoryMapper mainBackCategoryMapper;
    private final MainBackClauseMapper mainBackClauseMapper;
    private final MainBackCandidateMapper mainBackCandidateMapper;
    private final MainStudentMapper mainStudentMapper;
    private final PaymentMapper paymentMapper;
    private final SysTenantMapper sysTenantMapper;
    private final ISysTenantService tenantService;
    private final ICompanyAccountService companyAccountService;

    @Override
    public TableDataInfo<MainBackOrderVo> queryPageList(MainBackOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<MainBackOrder> lqw = new LambdaQueryWrapper<>();

        // 1. 左侧分类过滤
        lqw.eq(bo.getCategoryId() != null, MainBackOrder::getCategoryId, bo.getCategoryId());

        // 2. 状态过滤
        lqw.eq(StrUtil.isNotBlank(bo.getStatus()), MainBackOrder::getStatus, bo.getStatus());

        // 3. 右侧单位名称搜索逻辑
        if (StrUtil.isNotBlank(bo.getKeyword())) {
            // 通过单位名称模糊查询租户ID列表
            SysTenantBo tenantBo = new SysTenantBo();
            tenantBo.setCompanyName(bo.getKeyword());
            List<String> tenantIds = tenantService.queryList(tenantBo)
                .stream()
                .map(SysTenantVo::getTenantId)
                .toList();

            if (tenantIds.isEmpty()) {
                return TableDataInfo.build(new ArrayList<>());
            }
            lqw.in(MainBackOrder::getTenantId, tenantIds);
        }

        // 4. 分页查询订单主表
        Page<MainBackOrderVo> pageResult = baseMapper.selectVoPage(pageQuery.build(), lqw);
        TableDataInfo<MainBackOrderVo> result = TableDataInfo.build(pageResult);

        // 5. 动态填充页面所需字段
        for (MainBackOrderVo vo : result.getRows()) {
            // A. 统计候选人人数
            Long count = recordMapper.selectCount(
                new LambdaQueryWrapper<MainBackRecord>()
                    .eq(MainBackRecord::getOrderId, vo.getId())
            );
            vo.setCandidateCount(count);

            // B. 填充企业名称
            SysTenantVo tenant = tenantService.queryByTenantId(vo.getTenantId());
            if (tenant != null) {
                vo.setCompanyName(tenant.getCompanyName());
            }
        }

        return result;
    }

    @Override
    public List<MainBackOrderVo> queryPortalListByTenantId(String tenantId) {
        LambdaQueryWrapper<MainOrder> orderLqw = Wrappers.lambdaQuery();
        orderLqw.eq(StrUtil.isNotBlank(tenantId), MainOrder::getTenantId, tenantId)
            .in(MainOrder::getOrderType, List.of(3, 4))
            .isNotNull(MainOrder::getBusinessId)
            .orderByDesc(MainOrder::getCreateTime);

        List<MainOrder> mainOrders = mainOrderMapper.selectList(orderLqw);
        if (mainOrders.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> businessIds = mainOrders.stream()
            .map(MainOrder::getBusinessId)
            .distinct()
            .collect(Collectors.toList());

        Map<Long, MainBackOrder> backOrderMap = new LinkedHashMap<>();
        for (MainBackOrder backOrder : baseMapper.selectBatchIds(businessIds)) {
            backOrderMap.put(backOrder.getId(), backOrder);
        }

        List<MainBackOrderVo> result = new ArrayList<>();
        for (MainOrder mainOrder : mainOrders) {
            MainBackOrder backOrder = backOrderMap.get(mainOrder.getBusinessId());
            if (backOrder == null) {
                continue;
            }
            MainBackOrderVo vo = MapstructUtils.convert(backOrder, MainBackOrderVo.class);
            fillPortalFields(vo, mainOrder);
            result.add(vo);
        }
        return result;
    }

    @Override
    public MainBackOrderVo queryPortalDetail(String orderNo, String tenantId) {
        MainOrder mainOrder = mainOrderMapper.selectOne(
            Wrappers.<MainOrder>lambdaQuery()
                .eq(MainOrder::getOrderNo, orderNo)
                .eq(MainOrder::getTenantId, tenantId)
                .last("limit 1")
        );
        if (mainOrder == null) {
            return null;
        }
        if (mainOrder.getBusinessId() == null) {
            return null;
        }

        MainBackOrder backOrder = baseMapper.selectById(mainOrder.getBusinessId());
        if (backOrder == null) {
            return null;
        }

        MainBackOrderVo vo = MapstructUtils.convert(backOrder, MainBackOrderVo.class);
        fillPortalFields(vo, mainOrder);
        vo.setPayment(paymentMapper.selectVoOne(
            Wrappers.<Payment>lambdaQuery()
                .eq(Payment::getOrderId, mainOrder.getId())
                .orderByDesc(Payment::getCreateTime)
                .last("limit 1"),
            false
        ));
        if (vo.getPayment() != null) {
            vo.getPayment().setPaymentStatusText(toPaymentStatusText(vo.getPayment().getPaymentStatus()));
        }
        vo.setCandidates(buildPortalCandidates(backOrder.getId()));
        vo.setClauses(buildPortalClauses(backOrder));
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MainBackOrderVo createPortalOrder(String tenantId, PortalCheckOrderCreateBo bo) {
        if (StringUtils.isBlank(tenantId)) {
            throw new ServiceException("未登录或token已失效");
        }
        if (bo.getCandidates() == null || bo.getCandidates().isEmpty()) {
            throw new ServiceException("候选人列表不能为空");
        }

        SysTenantVo tenant = tenantService.queryByTenantId(tenantId);
        if (tenant == null) {
            throw new ServiceException("企业信息不存在");
        }

        List<Long> clauseIds;
        String clauseIdsJson;
        String clauseGroupKey = null;
        Long categoryId = null;
        String categoryName;
        BigDecimal unitPrice;

        if (Integer.valueOf(1).equals(bo.getOrderType())) {
            if (bo.getCategoryId() == null) {
                throw new ServiceException("套餐ID不能为空");
            }
            MainBackCategory category = mainBackCategoryMapper.selectById(bo.getCategoryId());
            if (category == null || !"1".equals(category.getStatus())) {
                throw new ServiceException("背调套餐不存在或已停用");
            }

            List<MainBackClause> clauses = mainBackClauseMapper.selectList(
                Wrappers.<MainBackClause>lambdaQuery()
                    .eq(MainBackClause::getCategoryId, category.getId())
                    .eq(MainBackClause::getStatus, "1")
                    .orderByAsc(MainBackClause::getId)
            );
            if (clauses.isEmpty()) {
                throw new ServiceException("该套餐下暂无可用条款");
            }

            categoryId = category.getId();
            categoryName = category.getName();
            unitPrice = defaultAmount(category.getPrice());
            clauseIds = clauses.stream().map(MainBackClause::getId).toList();
            clauseIdsJson = JsonUtils.toJsonString(clauseIds);
        } else if (Integer.valueOf(2).equals(bo.getOrderType())) {
            if (StringUtils.isBlank(bo.getClauseIds())) {
                throw new ServiceException("自定义条款不能为空");
            }
            List<Long> parsedClauseIds = JsonUtils.parseArray(bo.getClauseIds(), Long.class);
            if (parsedClauseIds == null || parsedClauseIds.isEmpty()) {
                throw new ServiceException("自定义条款不能为空");
            }

            clauseIds = parsedClauseIds.stream().distinct().sorted().collect(Collectors.toList());
            List<MainBackClause> clauses = mainBackClauseMapper.selectBatchIds(clauseIds).stream()
                .filter(clause -> clause != null && "1".equals(clause.getStatus()))
                .sorted(Comparator.comparing(MainBackClause::getId))
                .toList();
            if (clauses.size() != clauseIds.size()) {
                throw new ServiceException("部分自定义条款不存在或已停用");
            }

            unitPrice = clauses.stream()
                .map(MainBackClause::getPrice)
                .filter(java.util.Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            categoryName = "自定义背调组合";
            clauseIdsJson = JsonUtils.toJsonString(clauseIds);
            clauseGroupKey = DigestUtil.md5Hex(clauseIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
        } else {
            throw new ServiceException("不支持的订单类型");
        }

        int candidateCount = bo.getCandidates().size();
        BigDecimal totalAmount = unitPrice.multiply(BigDecimal.valueOf(candidateCount));
        if (totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("订单金额必须大于0");
        }

        List<Long> candidateRelationIds = new ArrayList<>(candidateCount);
        for (PortalCheckOrderCreateBo.CandidateInfo candidateInfo : bo.getCandidates()) {
            MainStudent student = matchStudent(candidateInfo);
            MainBackCandidate relation = findOrCreateCandidateRelation(tenantId, student.getId());
            candidateRelationIds.add(relation.getId());
        }

        String orderNo = generateOrderNo();

        MainBackOrder backOrder = new MainBackOrder();
        backOrder.setOrderNo(orderNo);
        backOrder.setTenantId(tenantId);
        backOrder.setCategoryId(categoryId);
        backOrder.setCategoryName(categoryName);
        backOrder.setTotalAmount(totalAmount);
        backOrder.setClauseIds(clauseIdsJson);
        backOrder.setClauseGroupKey(clauseGroupKey);
        backOrder.setStatus("0");
        baseMapper.insert(backOrder);

        MainOrder mainOrder = new MainOrder();
        mainOrder.setOrderNo(orderNo);
        mainOrder.setOrderType(3);
        mainOrder.setBuyerType(1);
        mainOrder.setBuyerId(tenant.getId());
        mainOrder.setBuyerName(tenant.getCompanyName());
        mainOrder.setSellerId(1L);
        mainOrder.setTotalAmount(totalAmount);
        mainOrder.setPaidAmount(BigDecimal.ZERO);
        mainOrder.setRefundAmount(BigDecimal.ZERO);
        mainOrder.setOrderStatus(0);
        mainOrder.setPayStatus(0);
        mainOrder.setBusinessId(backOrder.getId());
        mainOrder.setTenantId(tenantId);
        mainOrderMapper.insert(mainOrder);

        for (Long candidateRelationId : candidateRelationIds) {
            MainBackRecord record = new MainBackRecord();
            record.setOrderId(backOrder.getId());
            record.setCandidateId(candidateRelationId);
            record.setStatus("未完成");
            recordMapper.insert(record);
        }

        MainBackOrderVo vo = MapstructUtils.convert(backOrder, MainBackOrderVo.class);
        vo.setOrderId(mainOrder.getId());
        vo.setOrderNo(mainOrder.getOrderNo());
        vo.setCompanyId(tenant.getId());
        vo.setCompanyName(tenant.getCompanyName());
        vo.setTenantId(tenantId);
        vo.setOrderType(bo.getOrderType());
        vo.setClauseIds(clauseIdsJson);
        vo.setUnitPrice(unitPrice);
        vo.setTotalAmount(totalAmount);
        vo.setOrderStatus(0);
        vo.setMainOrderStatus(0);
        vo.setCandidateCount((long) candidateCount);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payOrderByBalance(Long orderId, String tenantId) {
        MainOrder mainOrder = mainOrderMapper.selectById(orderId);
        if (mainOrder == null) {
            throw new ServiceException("订单不存在");
        }
        if (!StringUtils.equals(mainOrder.getTenantId(), tenantId)) {
            throw new ServiceException("无权操作该订单");
        }
        if (mainOrder.getOrderStatus() == null || mainOrder.getOrderStatus() != 0) {
            throw new ServiceException("订单状态不正确，无法支付");
        }
        if (mainOrder.getPayStatus() != null && mainOrder.getPayStatus() != 0) {
            throw new ServiceException("订单已支付或已关闭");
        }
        if (mainOrder.getBusinessId() == null) {
            throw new ServiceException("背调订单不存在");
        }

        MainBackOrder backOrder = baseMapper.selectById(mainOrder.getBusinessId());
        if (backOrder == null) {
            throw new ServiceException("背调订单不存在");
        }

        SysTenant tenant = sysTenantMapper.selectOne(
            Wrappers.<SysTenant>lambdaQuery()
                .eq(SysTenant::getTenantId, tenantId)
                .last("limit 1")
        );
        if (tenant == null) {
            throw new ServiceException("企业信息不存在");
        }

        BigDecimal totalAmount = mainOrder.getTotalAmount() == null ? BigDecimal.ZERO : mainOrder.getTotalAmount();
        if (defaultAmount(tenant.getAvailableBalance()).compareTo(totalAmount) < 0) {
            throw new ServiceException("可用余额不足，请充值或选择支付宝支付");
        }
        companyAccountService.payByBalance(
            tenant.getId(),
            totalAmount,
            mainOrder.getId(),
            mainOrder.getOrderNo(),
            "背调订单支付：" + mainOrder.getOrderNo()
        );

        Payment payment = new Payment();
        payment.setPaymentNo("PAY" + cn.hutool.core.date.DateUtil.format(new Date(), "yyyyMMddHHmmss")
            + cn.hutool.core.util.RandomUtil.randomNumbers(4));
        payment.setOrderId(orderId);
        payment.setOrderNo(mainOrder.getOrderNo());
        payment.setPaymentType(3);
        payment.setPaymentMethod(3);
        payment.setPaymentAmount(totalAmount);
        payment.setPaymentStatus(2);
        payment.setPayTime(new Date());
        payment.setRemark("余额支付");
        paymentMapper.insert(payment);

        mainOrder.setOrderStatus(1);
        mainOrder.setPayStatus(2);
        mainOrder.setPaidAmount(totalAmount);
        mainOrder.setPayTime(new Date());
        mainOrderMapper.updateById(mainOrder);

        backOrder.setStatus("1");
        baseMapper.updateById(backOrder);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean completeOrder(Long id) {
        MainBackOrder backOrder = baseMapper.selectById(id);
        if (backOrder == null) {
            throw new ServiceException("背调订单不存在");
        }
        if ("2".equals(backOrder.getStatus())) {
            throw new ServiceException("订单已完成，无需重复操作");
        }
        if ("3".equals(backOrder.getStatus())) {
            throw new ServiceException("订单已退款，无法完成");
        }

        MainOrder mainOrder = mainOrderMapper.selectOne(
            Wrappers.<MainOrder>lambdaQuery()
                .eq(MainOrder::getBusinessId, id)
                .eq(MainOrder::getOrderType, 3)
                .last("limit 1")
        );
        if (mainOrder == null) {
            throw new ServiceException("订单不存在");
        }
        if (mainOrder.getPayStatus() == null || mainOrder.getPayStatus() != 2) {
            throw new ServiceException("订单未支付，无法完成");
        }

        List<MainBackRecord> records = recordMapper.selectList(
            Wrappers.<MainBackRecord>lambdaQuery()
                .eq(MainBackRecord::getOrderId, id)
        );
        if (records.isEmpty()) {
            throw new ServiceException("订单下暂无候选人记录，无法完成");
        }
        boolean hasUnfinished = records.stream()
            .anyMatch(record -> !"已完成".equals(record.getStatus()) && !"完成".equals(record.getStatus()));
        if (hasUnfinished) {
            throw new ServiceException("仍有候选人未完成背调，无法完成订单");
        }

        Payment latestPayment = queryLatestPayment(mainOrder.getId());
        if (isBalancePayment(latestPayment)) {
            companyAccountService.deductInUseBalance(
                mainOrder.getBuyerId(),
                defaultAmount(mainOrder.getTotalAmount()),
                mainOrder.getId(),
                mainOrder.getOrderNo(),
                "订单完成扣款：" + mainOrder.getOrderNo()
            );
        }

        backOrder.setStatus("2");
        baseMapper.updateById(backOrder);

        mainOrder.setOrderStatus(2);
        mainOrder.setCompleteTime(new Date());
        mainOrderMapper.updateById(mainOrder);
        return true;
    }

    private void fillPortalFields(MainBackOrderVo vo, MainOrder mainOrder) {
        Long count = recordMapper.selectCount(
            new LambdaQueryWrapper<MainBackRecord>()
                .eq(MainBackRecord::getOrderId, vo.getId())
        );
        vo.setCandidateCount(count);
        vo.setOrderId(mainOrder.getId());
        vo.setOrderNo(mainOrder.getOrderNo());
        vo.setCompanyId(mainOrder.getBuyerId());
        vo.setTenantId(mainOrder.getTenantId());
        vo.setTotalAmount(mainOrder.getTotalAmount());
        vo.setCreateTime(mainOrder.getCreateTime() == null ? null :
            mainOrder.getCreateTime().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime());
        vo.setOrderType(vo.getCategoryId() != null ? 1 : 2);
        vo.setOrderStatus(parseIntOrDefault(vo.getStatus(), 0));
        vo.setMainOrderStatus(mainOrder.getOrderStatus());

        if (count != null && count > 0 && vo.getTotalAmount() != null) {
            vo.setUnitPrice(vo.getTotalAmount().divide(BigDecimal.valueOf(count), 2, java.math.RoundingMode.HALF_UP));
        } else {
            vo.setUnitPrice(BigDecimal.ZERO);
        }
    }

    private MainStudent matchStudent(PortalCheckOrderCreateBo.CandidateInfo candidateInfo) {
        MainStudent student = mainStudentMapper.selectOne(
            Wrappers.<MainStudent>lambdaQuery()
                .eq(MainStudent::getMobile, candidateInfo.getCandidatePhone())
                .eq(MainStudent::getIdCardNumber, candidateInfo.getCandidateIdNumber())
                .eq(MainStudent::getStatus, "0")
                .last("limit 1")
        );
        if (student == null) {
            throw new ServiceException(
                "候选人【" + candidateInfo.getCandidateName() + "】未在学员库中找到，请先完成学员注册"
            );
        }
        return student;
    }

    private MainBackCandidate findOrCreateCandidateRelation(String tenantId, Long studentId) {
        MainBackCandidate relation = mainBackCandidateMapper.selectOne(
            Wrappers.<MainBackCandidate>lambdaQuery()
                .eq(MainBackCandidate::getTenantId, tenantId)
                .eq(MainBackCandidate::getStudentId, studentId)
                .last("limit 1")
        );
        if (relation != null) {
            return relation;
        }

        relation = new MainBackCandidate();
        relation.setTenantId(tenantId);
        relation.setStudentId(studentId);
        relation.setSource("portal");
        mainBackCandidateMapper.insert(relation);
        return relation;
    }

    private BigDecimal defaultAmount(BigDecimal amount) {
        return amount == null ? BigDecimal.ZERO : amount;
    }

    private Payment queryLatestPayment(Long orderId) {
        return paymentMapper.selectOne(
            Wrappers.<Payment>lambdaQuery()
                .eq(Payment::getOrderId, orderId)
                .orderByDesc(Payment::getCreateTime)
                .last("limit 1")
        );
    }

    private boolean isBalancePayment(Payment payment) {
        return payment == null || Integer.valueOf(3).equals(payment.getPaymentMethod());
    }

    private List<MainBackOrderCandidateVo> buildPortalCandidates(Long backOrderId) {
        List<MainBackRecord> records = recordMapper.selectList(
            Wrappers.<MainBackRecord>lambdaQuery()
                .eq(MainBackRecord::getOrderId, backOrderId)
                .orderByAsc(MainBackRecord::getCreateTime)
        );
        if (records.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> candidateIds = records.stream()
            .map(MainBackRecord::getCandidateId)
            .distinct()
            .toList();
        Map<Long, MainBackCandidate> candidateMap = new HashMap<>();
        for (MainBackCandidate candidate : mainBackCandidateMapper.selectBatchIds(candidateIds)) {
            candidateMap.put(candidate.getId(), candidate);
        }

        List<Long> studentIds = candidateMap.values().stream()
            .map(MainBackCandidate::getStudentId)
            .filter(java.util.Objects::nonNull)
            .distinct()
            .toList();
        Map<Long, MainStudent> studentMap = new HashMap<>();
        for (MainStudent student : mainStudentMapper.selectBatchIds(studentIds)) {
            studentMap.put(student.getId(), student);
        }

        List<MainBackOrderCandidateVo> result = new ArrayList<>(records.size());
        for (MainBackRecord record : records) {
            MainBackCandidate candidate = candidateMap.get(record.getCandidateId());
            MainStudent student = candidate == null ? null : studentMap.get(candidate.getStudentId());

            MainBackOrderCandidateVo vo = new MainBackOrderCandidateVo();
            vo.setId(record.getId());
            vo.setOrderId(backOrderId);
            vo.setStudentName(student == null ? null : student.getName());
            vo.setCandidatePhone(student == null ? null : student.getMobile());
            vo.setCandidateIdType("1");
            vo.setCandidateIdNumber(student == null ? null : student.getIdCardNumber());
            vo.setStatus(mapRecordStatus(record.getStatus()));
            vo.setReportUrl(record.getReportUrl());
            result.add(vo);
        }
        return result;
    }

    private List<MainBackClauseVo> buildPortalClauses(MainBackOrder backOrder) {
        if (backOrder.getCategoryId() != null) {
            return mainBackClauseMapper.selectVoList(
                Wrappers.<MainBackClause>lambdaQuery()
                    .eq(MainBackClause::getCategoryId, backOrder.getCategoryId())
                    .eq(MainBackClause::getStatus, "1")
                    .orderByAsc(MainBackClause::getId)
            );
        }
        if (StringUtils.isBlank(backOrder.getClauseIds())) {
            return new ArrayList<>();
        }

        List<Long> clauseIds = JsonUtils.parseArray(backOrder.getClauseIds(), Long.class);
        if (clauseIds == null || clauseIds.isEmpty()) {
            return new ArrayList<>();
        }

        Map<Long, MainBackClauseVo> clauseMap = mainBackClauseMapper.selectVoList(
            Wrappers.<MainBackClause>lambdaQuery().in(MainBackClause::getId, clauseIds)
        ).stream().collect(Collectors.toMap(MainBackClauseVo::getId, item -> item, (a, b) -> a));

        List<MainBackClauseVo> result = new ArrayList<>();
        for (Long clauseId : clauseIds) {
            MainBackClauseVo clause = clauseMap.get(clauseId);
            if (clause != null) {
                result.add(clause);
            }
        }
        return result;
    }

    private String generateOrderNo() {
        return "ORD" + cn.hutool.core.date.DateUtil.format(new Date(), "yyyyMMddHHmmss")
            + cn.hutool.core.util.RandomUtil.randomNumbers(4);
    }

    private Integer mapRecordStatus(String status) {
        if (StringUtils.isBlank(status)) {
            return 0;
        }
        return switch (status) {
            case "进行中" -> 1;
            case "已完成", "完成" -> 2;
            case "已取消", "失败" -> 3;
            default -> 0;
        };
    }

    private String toPaymentStatusText(Integer status) {
        if (status == null) {
            return "未知";
        }
        return switch (status) {
            case 0 -> "待支付";
            case 1 -> "支付中";
            case 2 -> "支付成功";
            case 3 -> "支付失败";
            default -> "未知";
        };
    }

    private Integer parseIntOrDefault(String value, int defaultValue) {
        if (StringUtils.isBlank(value)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException ignored) {
            return defaultValue;
        }
    }
}


