package com.erp.reconciliation.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.reconciliation.dto.*;
import com.erp.reconciliation.entity.*;
import com.erp.reconciliation.repository.*;
import com.erp.reconciliation.service.ReconciliationService;
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.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import com.erp.common.core.model.PageResponse;

/**
 * 对账服务实现类
 * 
 * 对应PHP：
 * - DataConsistencyService::checkFinanceConsistency - 财务对账一致性检查
 * - DataConsistencyService::checkOrderStockConsistency - 订单-库存一致性检查
 * - DataConsistencyService::checkWaybillConsistency - 运单-物流轨迹一致性检查
 * - DataConsistencyService::fullCheck - 执行全面一致性检查
 * 
 * @author ERP Migration
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReconciliationServiceImpl implements ReconciliationService {

    private final ReconciliationBillRepository billRepository;
    private final ReconciliationDifferenceRepository differenceRepository;
    private final ReconciliationTaskRepository taskRepository;
    private final OrderReconciliationRecordRepository recordRepository;

    private static final DateTimeFormatter BILL_NO_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private static final DateTimeFormatter TASK_NO_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    // ==================== 对账账单管理（CRUD） ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReconciliationBill createBill(ReconciliationBill bill) {
        if (bill.getBillNo() == null || bill.getBillNo().isEmpty()) {
            bill.setBillNo(generateBillNo());
        }
        if (bill.getReconciliationStatus() == null) {
            bill.setReconciliationStatus(ReconciliationBill.STATUS_PENDING);
        }
        bill.setCreatedAt(LocalDateTime.now());
        bill.setUpdatedAt(LocalDateTime.now());
        billRepository.insert(bill);
        log.info("创建对账单: {}", bill.getBillNo());
        return bill;
    }

    @Override
    public ReconciliationBill getBillById(Long id) {
        return billRepository.selectById(id);
    }

    @Override
    public ReconciliationBill getBillByBillNo(String billNo) {
        return billRepository.findByBillNo(billNo);
    }

    @Override
    public PageResponse<ReconciliationBillDTO> queryBills(ReconciliationQueryRequest request) {
        Page<ReconciliationBill> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        LocalDateTime startDateTime = request.getStartDate() != null ? request.getStartDate().atStartOfDay() : null;
        LocalDateTime endDateTime = request.getEndDate() != null ? request.getEndDate().atTime(23, 59, 59) : null;
        
        IPage<ReconciliationBill> billPage = billRepository.selectPageByConditions(
                page,
                request.getPlatform(),
                request.getShopId(),
                request.getReconciliationStatus(),
                request.getResultStatus(),
                startDateTime,
                endDateTime
        );

        List<ReconciliationBillDTO> dtoList = billPage.getRecords().stream()
                .map(this::toBillDTO)
                .collect(Collectors.toList());

        return PageResponse.of(dtoList, billPage.getTotal(), request.getPageNum(), request.getPageSize());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReconciliationBill updateBill(ReconciliationBill bill) {
        bill.setUpdatedAt(LocalDateTime.now());
        billRepository.updateById(bill);
        log.info("更新对账单: {}", bill.getBillNo());
        return bill;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBill(Long id) {
        ReconciliationBill bill = getBillById(id);
        if (bill == null) {
            throw new IllegalArgumentException("对账单不存在: " + id);
        }
        
        // 删除关联的差异记录
        differenceRepository.deleteByBillId(id);
        
        // 删除关联的订单对账记录
        recordRepository.deleteByBillId(id);
        
        // 删除对账单
        billRepository.deleteById(id);
        log.info("删除对账单: {}", bill.getBillNo());
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmBill(Long id, Long userId, String userName) {
        ReconciliationBill bill = getBillById(id);
        if (bill == null) {
            throw new IllegalArgumentException("对账单不存在: " + id);
        }
        if (!ReconciliationBill.STATUS_COMPLETED.equals(bill.getReconciliationStatus())) {
            throw new IllegalStateException("只有已完成的对账单可以确认");
        }

        bill.setConfirmUserId(userId);
        bill.setConfirmUserName(userName);
        bill.setConfirmTime(LocalDateTime.now());
        updateBill(bill);
        log.info("确认对账单: {}, 确认人: {}", bill.getBillNo(), userName);
        return true;
    }

    // ==================== 账单核对 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReconciliationBill performReconciliation(Long billId) {
        ReconciliationBill bill = getBillById(billId);
        if (bill == null) {
            throw new IllegalArgumentException("对账单不存在: " + billId);
        }

        log.info("开始执行对账: {}", bill.getBillNo());
        bill.setReconciliationStatus(ReconciliationBill.STATUS_PROCESSING);
        bill.setReconciliationStartTime(LocalDateTime.now());
        updateBill(bill);

        try {
            // 1. 获取平台账单数据（这里应该调用平台API或读取平台账单表）
            List<Map<String, Object>> platformOrders = fetchPlatformOrders(
                    bill.getPlatform(), bill.getShopId(), 
                    bill.getPeriodStart(), bill.getPeriodEnd());
            
            // 2. 获取内部订单数据
            List<Map<String, Object>> internalOrders = fetchInternalOrders(
                    bill.getPlatform(), bill.getShopId(),
                    bill.getPeriodStart(), bill.getPeriodEnd());

            // 3. 执行订单匹配
            Map<String, OrderMatchResult> matchResults = matchOrders(platformOrders, internalOrders);

            // 4. 统计匹配结果
            int matchedCount = 0;
            int differenceCount = 0;
            BigDecimal matchedAmount = BigDecimal.ZERO;
            BigDecimal platformTotal = BigDecimal.ZERO;
            BigDecimal internalTotal = BigDecimal.ZERO;
            List<ReconciliationDifference> differences = new ArrayList<>();

            for (Map.Entry<String, OrderMatchResult> entry : matchResults.entrySet()) {
                OrderMatchResult result = entry.getValue();
                platformTotal = platformTotal.add(result.platformAmount);
                internalTotal = internalTotal.add(result.internalAmount);

                if (result.isMatched) {
                    matchedCount++;
                    matchedAmount = matchedAmount.add(result.platformAmount);
                    
                    // 记录匹配订单
                    saveOrderRecord(bill, result, ReconciliationOrder.STATUS_MATCHED);
                } else {
                    differenceCount++;
                    
                    // 创建差异记录
                    ReconciliationDifference diff = createDifference(bill, result);
                    differences.add(diff);
                    
                    // 记录差异订单
                    saveOrderRecord(bill, result, ReconciliationOrder.STATUS_DIFFERENCE);
                }
            }

            // 处理平台有但内部没有的订单
            for (Map<String, Object> platformOrder : platformOrders) {
                String platformOrderSn = (String) platformOrder.get("platformOrderSn");
                if (!matchResults.containsKey(platformOrderSn)) {
                    differenceCount++;
                    ReconciliationDifference diff = ReconciliationDifference.builder()
                            .billId(bill.getId())
                            .billNo(bill.getBillNo())
                            .differenceType(ReconciliationDifference.TYPE_MISSING_INTERNAL)
                            .platformOrderSn(platformOrderSn)
                            .platformOrderAmount(new BigDecimal(platformOrder.get("amount").toString()))
                            .differenceAmount(new BigDecimal(platformOrder.get("amount").toString()))
                            .differenceReason("平台有订单但内部系统未找到对应订单")
                            .handleStatus(ReconciliationDifference.HANDLE_PENDING)
                            .build();
                    differences.add(diff);
                }
            }

            // 5. 保存差异记录
            for (ReconciliationDifference diff : differences) {
                differenceRepository.insert(diff);
            }

            // 6. 更新对账单统计
            BigDecimal differenceAmount = platformTotal.subtract(internalTotal).abs();
            bill.setPlatformOrderCount(platformOrders.size());
            bill.setPlatformTotalAmount(platformTotal);
            bill.setInternalOrderCount(internalOrders.size());
            bill.setInternalTotalAmount(internalTotal);
            bill.setDifferenceAmount(differenceAmount);
            bill.setMatchedCount(matchedCount);
            bill.setMatchedAmount(matchedAmount);
            bill.setDifferenceCount(differenceCount);
            
            // 7. 判断对账结果
            if (differenceCount == 0) {
                bill.setResultStatus(ReconciliationBill.RESULT_CONSISTENT);
            } else if (matchedCount == 0) {
                bill.setResultStatus(ReconciliationBill.RESULT_INCONSISTENT);
            } else {
                bill.setResultStatus(ReconciliationBill.RESULT_PARTIAL);
            }

            bill.setReconciliationStatus(ReconciliationBill.STATUS_COMPLETED);
            bill.setReconciliationEndTime(LocalDateTime.now());
            updateBill(bill);

            log.info("对账完成: {}, 匹配: {}, 差异: {}, 差异金额: {}",
                    bill.getBillNo(), matchedCount, differenceCount, differenceAmount);

            return bill;

        } catch (Exception e) {
            log.error("对账执行失败: {}", bill.getBillNo(), e);
            bill.setReconciliationStatus(ReconciliationBill.STATUS_FAILED);
            bill.setReconciliationEndTime(LocalDateTime.now());
            updateBill(bill);
            throw new RuntimeException("对账执行失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ReconciliationBill> batchReconciliation(List<Long> billIds) {
        List<ReconciliationBill> results = new ArrayList<>();
        for (Long billId : billIds) {
            try {
                ReconciliationBill bill = performReconciliation(billId);
                results.add(bill);
            } catch (Exception e) {
                log.error("批量对账失败: billId={}", billId, e);
            }
        }
        log.info("批量对账完成: 共{}条, 成功{}条", billIds.size(), results.size());
        return results;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReconciliationBill createAndReconcile(String platform, Long shopId, String periodType, 
                                                  LocalDate periodStart, LocalDate periodEnd) {
        // 1. 创建对账单
        ReconciliationBill bill = ReconciliationBill.builder()
                .platform(platform)
                .shopId(shopId)
                .periodType(periodType)
                .periodStart(periodStart.atStartOfDay())
                .periodEnd(periodEnd.atTime(23, 59, 59))
                .reconciliationStatus(ReconciliationBill.STATUS_PENDING)
                .build();
        
        ReconciliationBill created = createBill(bill);
        
        // 2. 执行对账
        return performReconciliation(created.getId());
    }

    @Override
    public List<Map<String, Object>> checkOrderAmountConsistency(LocalDate startDate, LocalDate endDate) {
        log.info("执行订单金额一致性检查: {} ~ {}", startDate, endDate);
        List<Map<String, Object>> issues = new ArrayList<>();
        
        // TODO: 调用订单服务获取订单数据
        // 这里模拟检查逻辑
        // 对应PHP DataConsistencyService::checkFinanceConsistency
        
        // 检查订单金额计算: total_amount = goods_amount + freight - discount_amount
        // List<Order> orders = orderService.getOrdersInRange(startDate, endDate);
        // for (Order order : orders) {
        //     BigDecimal calculated = order.getGoodsAmount().add(order.getFreight()).subtract(order.getDiscountAmount());
        //     BigDecimal amountDiff = order.getTotalAmount().subtract(calculated).abs();
        //     if (amountDiff.compareTo(new BigDecimal("0.01")) > 0) {
        //         issues.add(createIssue(...));
        //     }
        // }
        
        return issues;
    }

    @Override
    public List<Map<String, Object>> checkOrderStockConsistency() {
        log.info("执行订单-库存一致性检查");
        List<Map<String, Object>> issues = new ArrayList<>();
        
        // TODO: 调用库存服务检查已发货订单是否有出库记录
        // 对应PHP DataConsistencyService::checkOrderStockConsistency
        
        // 检查已发货订单是否有出库记录
        // List<Order> shippedOrders = orderService.getShippedOrders();
        // for (Order order : shippedOrders) {
        //     boolean hasOutbound = stockService.hasOutboundLog(order.getId());
        //     if (!hasOutbound) {
        //         issues.add(createIssue(...));
        //     }
        // }
        
        return issues;
    }

    @Override
    public List<Map<String, Object>> checkWaybillConsistency() {
        log.info("执行运单-物流轨迹一致性检查");
        List<Map<String, Object>> issues = new ArrayList<>();
        
        // TODO: 调用物流服务检查运单轨迹
        // 对应PHP DataConsistencyService::checkWaybillConsistency
        
        // 检查已使用运单是否有物流轨迹
        // List<Waybill> usedWaybills = waybillService.getUsedWaybills();
        // for (Waybill waybill : usedWaybills) {
        //     boolean hasTraces = logisticsService.hasTraces(waybill.getWaybillNo());
        //     if (!hasTraces) {
        //         issues.add(createIssue(...));
        //     }
        // }
        
        return issues;
    }

    @Override
    public Map<String, Object> fullConsistencyCheck() {
        log.info("执行全面一致性检查");
        
        Map<String, Object> results = new HashMap<>();
        
        // 1. 财务对账一致性检查
        results.put("finance", checkOrderAmountConsistency(
                LocalDate.now().minusMonths(1), LocalDate.now()));
        
        // 2. 订单-库存一致性检查
        results.put("order_stock", checkOrderStockConsistency());
        
        // 3. 运单-物流轨迹一致性检查
        results.put("waybill", checkWaybillConsistency());
        
        results.put("checked_at", LocalDateTime.now().toString());
        
        return results;
    }

    // ==================== 差异处理 ====================

    @Override
    public PageResponse<ReconciliationDifferenceDTO> queryDifferences(ReconciliationQueryRequest request) {
        Page<ReconciliationDifference> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        LocalDateTime startDateTime = request.getStartDate() != null ? request.getStartDate().atStartOfDay() : null;
        LocalDateTime endDateTime = request.getEndDate() != null ? request.getEndDate().atTime(23, 59, 59) : null;
        
        IPage<ReconciliationDifference> diffPage = differenceRepository.selectPageByConditions(
                page,
                request.getBillId(),
                request.getBillNo(),
                request.getDifferenceType(),
                request.getHandleStatus(),
                request.getPlatform(),
                request.getShopId(),
                startDateTime,
                endDateTime
        );

        List<ReconciliationDifferenceDTO> dtoList = diffPage.getRecords().stream()
                .map(this::toDifferenceDTO)
                .collect(Collectors.toList());

        return PageResponse.of(dtoList, diffPage.getTotal(), request.getPageNum(), request.getPageSize());
    }

    @Override
    public ReconciliationDifference getDifferenceById(Long id) {
        return differenceRepository.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handleDifference(Long id, String handleMethod, String handleRemark, Long userId, String userName) {
        ReconciliationDifference diff = getDifferenceById(id);
        if (diff == null) {
            throw new IllegalArgumentException("差异记录不存在: " + id);
        }

        diff.setHandleMethod(handleMethod);
        diff.setHandleRemark(handleRemark);
        diff.setHandleUserId(userId);
        diff.setHandleUserName(userName);
        diff.setHandleTime(LocalDateTime.now());
        diff.setHandleStatus(ReconciliationDifference.HANDLE_RESOLVED);
        diff.setUpdatedAt(LocalDateTime.now());
        
        differenceRepository.updateById(diff);
        log.info("处理差异: id={}, method={}, user={}", id, handleMethod, userName);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchHandleDifferences(List<Long> ids, String handleMethod, String handleRemark, Long userId, String userName) {
        int count = 0;
        for (Long id : ids) {
            try {
                if (handleDifference(id, handleMethod, handleRemark, userId, userName)) {
                    count++;
                }
            } catch (Exception e) {
                log.error("批量处理差异失败: id={}", id, e);
            }
        }
        return count;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDifferenceStatus(Long id, String handleStatus) {
        ReconciliationDifference diff = getDifferenceById(id);
        if (diff == null) {
            throw new IllegalArgumentException("差异记录不存在: " + id);
        }

        diff.setHandleStatus(handleStatus);
        diff.setUpdatedAt(LocalDateTime.now());
        differenceRepository.updateById(diff);
        log.info("更新差异状态: id={}, status={}", id, handleStatus);
        return true;
    }

    @Override
    public Map<String, Long> getPendingDifferenceStats() {
        Map<String, Long> stats = new HashMap<>();
        
        List<ReconciliationDifference> pending = differenceRepository.findPendingDifferences(1000);
        stats.put("pending", (long) pending.size());
        
        // 按类型统计
        Map<String, Long> typeCount = pending.stream()
                .collect(Collectors.groupingBy(ReconciliationDifference::getDifferenceType, Collectors.counting()));
        stats.putAll(typeCount);
        
        return stats;
    }

    // ==================== 对账任务 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReconciliationTask createTask(ReconciliationTask task) {
        if (task.getTaskNo() == null || task.getTaskNo().isEmpty()) {
            task.setTaskNo(generateTaskNo());
        }
        if (task.getTaskStatus() == null) {
            task.setTaskStatus(ReconciliationTask.STATUS_PENDING);
        }
        task.setCreatedAt(LocalDateTime.now());
        task.setUpdatedAt(LocalDateTime.now());
        taskRepository.insert(task);
        log.info("创建对账任务: {}", task.getTaskNo());
        return task;
    }

    @Override
    public ReconciliationTask getTaskById(Long id) {
        return taskRepository.selectById(id);
    }

    @Override
    public PageResponse<ReconciliationTaskDTO> queryTasks(ReconciliationQueryRequest request) {
        Page<ReconciliationTask> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        LocalDateTime startDateTime = request.getStartDate() != null ? request.getStartDate().atStartOfDay() : null;
        LocalDateTime endDateTime = request.getEndDate() != null ? request.getEndDate().atTime(23, 59, 59) : null;
        
        IPage<ReconciliationTask> taskPage = taskRepository.selectPageByConditions(
                page,
                request.getTaskType(),
                request.getTaskStatus(),
                request.getPlatform(),
                request.getShopId(),
                startDateTime,
                endDateTime
        );

        List<ReconciliationTaskDTO> dtoList = taskPage.getRecords().stream()
                .map(this::toTaskDTO)
                .collect(Collectors.toList());

        return PageResponse.of(dtoList, taskPage.getTotal(), request.getPageNum(), request.getPageSize());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTaskProgress(Long taskId, Integer progress, String currentStep) {
        taskRepository.updateProgress(taskId, progress, currentStep);
        log.info("更新任务进度: taskId={}, progress={}, step={}", taskId, progress, currentStep);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelTask(Long taskId) {
        ReconciliationTask task = getTaskById(taskId);
        if (task == null) {
            throw new IllegalArgumentException("任务不存在: " + taskId);
        }
        if (ReconciliationTask.STATUS_RUNNING.equals(task.getTaskStatus())) {
            throw new IllegalStateException("正在执行的任务无法取消");
        }

        task.setTaskStatus(ReconciliationTask.STATUS_CANCELLED);
        task.setUpdatedAt(LocalDateTime.now());
        taskRepository.updateById(task);
        log.info("取消任务: {}", task.getTaskNo());
        return true;
    }

    // ==================== 统计报表 ====================

    @Override
    public ReconciliationStatisticsDTO getStatistics(ReconciliationQueryRequest request) {
        // TODO: 实现完整的统计逻辑
        // 目前返回空统计，后续需要关联查询订单、差异等表
        return ReconciliationStatisticsDTO.builder()
                .startTime(request.getStartDate() != null ? request.getStartDate().atStartOfDay() : null)
                .endTime(request.getEndDate() != null ? request.getEndDate().atTime(23, 59, 59) : null)
                .totalBillCount(0L)
                .pendingBillCount(0L)
                .completedBillCount(0L)
                .failedBillCount(0L)
                .platformTotalAmount(BigDecimal.ZERO)
                .internalTotalAmount(BigDecimal.ZERO)
                .totalDifferenceAmount(BigDecimal.ZERO)
                .matchedAmount(BigDecimal.ZERO)
                .totalDifferenceCount(0L)
                .pendingDifferenceCount(0L)
                .resolvedDifferenceCount(0L)
                .overallMatchRate(BigDecimal.ZERO)
                .build();
    }

    @Override
    public ReconciliationStatisticsDTO.PlatformStatistics getPlatformStatistics(String platform, LocalDate startDate, LocalDate endDate) {
        return ReconciliationStatisticsDTO.PlatformStatistics.builder()
                .platform(platform)
                .billCount(0L)
                .orderCount(0L)
                .platformAmount(BigDecimal.ZERO)
                .internalAmount(BigDecimal.ZERO)
                .differenceAmount(BigDecimal.ZERO)
                .matchRate(BigDecimal.ZERO)
                .build();
    }

    @Override
    public ReconciliationStatisticsDTO.ShopStatistics getShopStatistics(Long shopId, LocalDate startDate, LocalDate endDate) {
        return ReconciliationStatisticsDTO.ShopStatistics.builder()
                .shopId(shopId)
                .billCount(0L)
                .orderCount(0L)
                .platformAmount(BigDecimal.ZERO)
                .internalAmount(BigDecimal.ZERO)
                .differenceAmount(BigDecimal.ZERO)
                .matchRate(BigDecimal.ZERO)
                .build();
    }

    @Override
    public List<Map<String, Object>> getDifferenceTrend(LocalDate startDate, LocalDate endDate) {
        // TODO: 实现差异趋势统计
        return new ArrayList<>();
    }

    // ==================== 定时对账 ====================

    @Override
    public void executeDailyReconciliation() {
        log.info("执行每日定时对账");
        LocalDate yesterday = LocalDate.now().minusDays(1);
        
        // TODO: 获取所有需要日对账的平台和店铺
        // List<Platform> platforms = platformService.getAll();
        // for (Platform platform : platforms) {
        //     for (Shop shop : platform.getShops()) {
        //         try {
        //             createAndReconcile(platform.getCode(), shop.getId(), 
        //                     ReconciliationBill.PERIOD_DAILY, yesterday, yesterday);
        //         } catch (Exception e) {
        //             log.error("日对账失败: platform={}, shop={}", platform.getCode(), shop.getId(), e);
        //         }
        //     }
        // }
    }

    @Override
    public void executeWeeklyReconciliation() {
        log.info("执行每周定时对账");
        // TODO: 实现周对账
    }

    @Override
    public void executeMonthlyReconciliation() {
        log.info("执行每月定时对账");
        // TODO: 实现月对账
    }

    // ==================== 私有辅助方法 ====================

    private String generateBillNo() {
        return "RCB" + LocalDateTime.now().format(BILL_NO_FORMATTER) + String.format("%04d", new Random().nextInt(10000));
    }

    private String generateTaskNo() {
        return "RCT" + LocalDateTime.now().format(TASK_NO_FORMATTER) + String.format("%04d", new Random().nextInt(10000));
    }

    /**
     * 获取平台订单数据（模拟，后续需要调用平台API）
     */
    private List<Map<String, Object>> fetchPlatformOrders(String platform, Long shopId, 
                                                           LocalDateTime periodStart, LocalDateTime periodEnd) {
        // TODO: 实现真实的平台订单获取逻辑
        // 可能需要调用平台API或读取平台账单表
        return new ArrayList<>();
    }

    /**
     * 获取内部订单数据（模拟，后续需要调用订单服务）
     */
    private List<Map<String, Object>> fetchInternalOrders(String platform, Long shopId,
                                                            LocalDateTime periodStart, LocalDateTime periodEnd) {
        // TODO: 实现真实的内部订单获取逻辑
        // 可能需要调用订单服务
        return new ArrayList<>();
    }

    /**
     * 订单匹配结果
     */
    private static class OrderMatchResult {
        String platformOrderSn;
        String internalOrderSn;
        BigDecimal platformAmount;
        BigDecimal internalAmount;
        boolean isMatched;
        String platformStatus;
        String internalStatus;

        OrderMatchResult(String platformOrderSn, BigDecimal platformAmount) {
            this.platformOrderSn = platformOrderSn;
            this.platformAmount = platformAmount;
            this.internalAmount = BigDecimal.ZERO;
            this.isMatched = false;
        }
    }

    /**
     * 执行订单匹配
     */
    private Map<String, OrderMatchResult> matchOrders(List<Map<String, Object>> platformOrders,
                                                        List<Map<String, Object>> internalOrders) {
        Map<String, OrderMatchResult> results = new HashMap<>();
        
        // 构建内部订单索引
        Map<String, Map<String, Object>> internalIndex = new HashMap<>();
        for (Map<String, Object> order : internalOrders) {
            String platformOrderSn = (String) order.get("platformOrderSn");
            if (platformOrderSn != null) {
                internalIndex.put(platformOrderSn, order);
            }
        }

        // 匹配平台订单
        for (Map<String, Object> platformOrder : platformOrders) {
            String platformOrderSn = (String) platformOrder.get("platformOrderSn");
            BigDecimal platformAmount = new BigDecimal(platformOrder.get("amount").toString());
            
            OrderMatchResult result = new OrderMatchResult(platformOrderSn, platformAmount);
            
            Map<String, Object> internalOrder = internalIndex.get(platformOrderSn);
            if (internalOrder != null) {
                result.internalOrderSn = (String) internalOrder.get("orderSn");
                result.internalAmount = new BigDecimal(internalOrder.get("totalAmount").toString());
                result.internalStatus = (String) internalOrder.get("status");
                
                // 检查金额是否一致
                if (platformAmount.compareTo(result.internalAmount) == 0) {
                    result.isMatched = true;
                } else {
                    result.isMatched = false;
                }
            }
            
            results.put(platformOrderSn, result);
        }
        
        return results;
    }

    /**
     * 创建差异记录
     */
    private ReconciliationDifference createDifference(ReconciliationBill bill, OrderMatchResult result) {
        ReconciliationDifference diff = ReconciliationDifference.builder()
                .billId(bill.getId())
                .billNo(bill.getBillNo())
                .differenceType(ReconciliationDifference.TYPE_AMOUNT_DIFFERENCE)
                .platformOrderSn(result.platformOrderSn)
                .internalOrderSn(result.internalOrderSn)
                .platformOrderAmount(result.platformAmount)
                .internalOrderAmount(result.internalAmount)
                .differenceAmount(result.platformAmount.subtract(result.internalAmount).abs())
                .platformOrderStatus(result.platformStatus)
                .internalOrderStatus(result.internalStatus)
                .differenceReason("订单金额不匹配")
                .handleStatus(ReconciliationDifference.HANDLE_PENDING)
                .build();
        
        return diff;
    }

    /**
     * 保存订单对账记录
     */
    private void saveOrderRecord(ReconciliationBill bill, OrderMatchResult result, String status) {
        OrderReconciliationRecord record = OrderReconciliationRecord.builder()
                .billId(bill.getId())
                .billNo(bill.getBillNo())
                .platformOrderSn(result.platformOrderSn)
                .platform(bill.getPlatform())
                .shopId(bill.getShopId())
                .platformOrderAmount(result.platformAmount)
                .internalOrderAmount(result.internalAmount)
                .differenceAmount(result.platformAmount.subtract(result.internalAmount).abs())
                .checkStatus(status)
                .checkTime(LocalDateTime.now())
                .build();
        
        recordRepository.insert(record);
    }

    /**
     * DTO转换方法
     */
    private ReconciliationBillDTO toBillDTO(ReconciliationBill bill) {
        BigDecimal matchRate = BigDecimal.ZERO;
        if (bill.getPlatformOrderCount() != null && bill.getPlatformOrderCount() > 0 && bill.getMatchedCount() != null) {
            matchRate = BigDecimal.valueOf(bill.getMatchedCount())
                    .divide(BigDecimal.valueOf(bill.getPlatformOrderCount()), 4, RoundingMode.HALF_UP)
                    .multiply(BigDecimal.valueOf(100));
        }
        
        return ReconciliationBillDTO.builder()
                .id(bill.getId())
                .billNo(bill.getBillNo())
                .batchNo(bill.getBatchNo())
                .platform(bill.getPlatform())
                .shopId(bill.getShopId())
                .shopName(bill.getShopName())
                .periodType(bill.getPeriodType())
                .periodStart(bill.getPeriodStart())
                .periodEnd(bill.getPeriodEnd())
                .platformOrderCount(bill.getPlatformOrderCount())
                .platformTotalAmount(bill.getPlatformTotalAmount())
                .internalOrderCount(bill.getInternalOrderCount())
                .internalTotalAmount(bill.getInternalTotalAmount())
                .differenceAmount(bill.getDifferenceAmount())
                .matchedCount(bill.getMatchedCount())
                .matchedAmount(bill.getMatchedAmount())
                .differenceCount(bill.getDifferenceCount())
                .reconciliationStatus(bill.getReconciliationStatus())
                .resultStatus(bill.getResultStatus())
                .reconciliationStartTime(bill.getReconciliationStartTime())
                .reconciliationEndTime(bill.getReconciliationEndTime())
                .confirmTime(bill.getConfirmTime())
                .confirmUserId(bill.getConfirmUserId())
                .confirmUserName(bill.getConfirmUserName())
                .matchRate(matchRate)
                .remark(bill.getRemark())
                .createdAt(bill.getCreatedAt())
                .updatedAt(bill.getUpdatedAt())
                .build();
    }

    private ReconciliationDifferenceDTO toDifferenceDTO(ReconciliationDifference diff) {
        return ReconciliationDifferenceDTO.builder()
                .id(diff.getId())
                .billId(diff.getBillId())
                .billNo(diff.getBillNo())
                .differenceType(diff.getDifferenceType())
                .differenceTypeLabel(getDifferenceTypeLabel(diff.getDifferenceType()))
                .platformOrderSn(diff.getPlatformOrderSn())
                .internalOrderId(diff.getInternalOrderId())
                .internalOrderSn(diff.getInternalOrderSn())
                .platformOrderAmount(diff.getPlatformOrderAmount())
                .internalOrderAmount(diff.getInternalOrderAmount())
                .differenceAmount(diff.getDifferenceAmount())
                .platformOrderStatus(diff.getPlatformOrderStatus())
                .internalOrderStatus(diff.getInternalOrderStatus())
                .differenceReason(diff.getDifferenceReason())
                .handleStatus(diff.getHandleStatus())
                .handleStatusLabel(getHandleStatusLabel(diff.getHandleStatus()))
                .handleMethod(diff.getHandleMethod())
                .handleUserId(diff.getHandleUserId())
                .handleUserName(diff.getHandleUserName())
                .handleTime(diff.getHandleTime())
                .handleRemark(diff.getHandleRemark())
                .relatedBillId(diff.getRelatedBillId())
                .remark(diff.getRemark())
                .createdAt(diff.getCreatedAt())
                .updatedAt(diff.getUpdatedAt())
                .build();
    }

    private ReconciliationTaskDTO toTaskDTO(ReconciliationTask task) {
        return ReconciliationTaskDTO.builder()
                .id(task.getId())
                .taskNo(task.getTaskNo())
                .taskType(task.getTaskType())
                .taskTypeLabel(getTaskTypeLabel(task.getTaskType()))
                .billId(task.getBillId())
                .billNo(task.getBillNo())
                .platform(task.getPlatform())
                .shopId(task.getShopId())
                .shopName(task.getShopName())
                .taskStatus(task.getTaskStatus())
                .taskStatusLabel(getTaskStatusLabel(task.getTaskStatus()))
                .progress(task.getProgress())
                .currentStep(task.getCurrentStep())
                .startTime(task.getStartTime())
                .endTime(task.getEndTime())
                .durationSeconds(task.getDurationSeconds())
                .resultMessage(task.getResultMessage())
                .errorDetail(task.getErrorDetail())
                .triggerUserId(task.getTriggerUserId())
                .triggerUserName(task.getTriggerUserName())
                .remark(task.getRemark())
                .createdAt(task.getCreatedAt())
                .build();
    }

    private String getDifferenceTypeLabel(String type) {
        return switch (type) {
            case ReconciliationDifference.TYPE_AMOUNT_DIFFERENCE -> "金额差异";
            case ReconciliationDifference.TYPE_MISSING_PLATFORM -> "平台缺失";
            case ReconciliationDifference.TYPE_MISSING_INTERNAL -> "内部缺失";
            case ReconciliationDifference.TYPE_STATUS_MISMATCH -> "状态不匹配";
            default -> type;
        };
    }

    private String getHandleStatusLabel(String status) {
        return switch (status) {
            case ReconciliationDifference.HANDLE_PENDING -> "待处理";
            case ReconciliationDifference.HANDLE_INVESTIGATING -> "调查中";
            case ReconciliationDifference.HANDLE_RESOLVED -> "已解决";
            case ReconciliationDifference.HANDLE_WRITE_OFF -> "已核销";
            case ReconciliationDifference.HANDLE_WRITE_BACK -> "已冲正";
            default -> status;
        };
    }

    private String getTaskTypeLabel(String type) {
        return switch (type) {
            case ReconciliationTask.TYPE_AUTO -> "自动对账";
            case ReconciliationTask.TYPE_MANUAL -> "手动对账";
            case ReconciliationTask.TYPE_SCHEDULED -> "定时对账";
            default -> type;
        };
    }

    private String getTaskStatusLabel(String status) {
        return switch (status) {
            case ReconciliationTask.STATUS_PENDING -> "待执行";
            case ReconciliationTask.STATUS_RUNNING -> "执行中";
            case ReconciliationTask.STATUS_COMPLETED -> "已完成";
            case ReconciliationTask.STATUS_FAILED -> "失败";
            case ReconciliationTask.STATUS_CANCELLED -> "已取消";
            default -> status;
        };
    }
}
