package com.njzscloud.supervisory.money.quartz;

import com.njzscloud.supervisory.money.mapper.MoneyBillMapper;
import com.njzscloud.supervisory.money.pojo.entity.MoneyBillEntity;
import com.njzscloud.supervisory.money.pojo.result.MoneyBillResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ljw
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MoneyBillQuartz {

    private final MoneyBillMapper moneyBillMapper;

    // @Scheduled(cron = "0 0/5 * * * ?")//每1分钟一次
    @Scheduled(cron = "0 0 1 1 * ?")// 每月1号凌晨1点执行
    public void syncAssetsDiscover() {
        generateMoneyBill();
    }

    public void generateMoneyBill() {
        // 计算上个月的时间范围
        LocalDateTime now = LocalDateTime.now();
        // 上个月1号0点0分0秒
        LocalDateTime lastMonthStart = now.minusMonths(1).withDayOfMonth(1).with(LocalTime.MIN);
        // 上个月月末23点59分59秒
        LocalDateTime lastMonthEnd = now.minusMonths(1).withDayOfMonth(now.minusMonths(1).toLocalDate().lengthOfMonth())
                .with(LocalTime.MAX);

        // 创建查询条件
        MoneyBillResult queryCondition = new MoneyBillResult();
        queryCondition.setStartTime(lastMonthStart);
        queryCondition.setEndTime(lastMonthEnd);

        // 执行查询
        List<MoneyBillResult> billResults = moneyBillMapper.selectMoneyBillList(queryCondition);
        // 仅保留订单类型为 PuTong 或 DuanBoRu 的记录
        billResults = billResults.stream()
                .filter(r -> "PuTong".equals(r.getOrderCategory()) || "DuanBoRu".equals(r.getOrderCategory()))
                .collect(Collectors.toList());

        log.info("查询到上个月账单数据 {} 条", billResults.size());

        if (!billResults.isEmpty()) {
            // 先按transCompanyId、originExpenseItemId、orderCategory三层分组，区分不同订单类型（如 DuanBoRu 与 PuTong）
            Map<Long, Map<Long, Map<String, List<MoneyBillResult>>>> groupedResults = billResults.stream()
                    .collect(Collectors.groupingBy(
                            MoneyBillResult::getTransCompanyId,
                            Collectors.groupingBy(MoneyBillResult::getOriginExpenseItemId,
                                    Collectors.groupingBy(MoneyBillResult::getOrderCategory))
                    ));

            log.info("按transCompanyId、originExpenseItemId和orderCategory三级分组后共 {} 个公司分组", groupedResults.size());

            // 处理每个公司分组的数据
            List<MoneyBillEntity> entityList = Lists.newArrayList();
            for (Map.Entry<Long, Map<Long, Map<String, List<MoneyBillResult>>>> companyEntry : groupedResults.entrySet()) {
                Long transCompanyId = companyEntry.getKey();
                Map<Long, Map<String, List<MoneyBillResult>>> companyGroupResults = companyEntry.getValue();

                log.info("transCompanyId: {}, 该公司包含 {} 个originExpenseItemId分组",
                        transCompanyId, companyGroupResults.size());

                // 处理该公司下的每个originExpenseItemId分组
                for (Map.Entry<Long, Map<String, List<MoneyBillResult>>> itemEntry : companyGroupResults.entrySet()) {
                    Long originExpenseItemId = itemEntry.getKey();
                    Map<String, List<MoneyBillResult>> categoryGroupMap = itemEntry.getValue();

                    for (Map.Entry<String, List<MoneyBillResult>> categoryEntry : categoryGroupMap.entrySet()) {
                        String orderCategoryStr = categoryEntry.getKey();
                        List<MoneyBillResult> itemGroupResults = categoryEntry.getValue();

                        log.info("transCompanyId: {}, originExpenseItemId: {}, orderCategory: {}, 该分组包含 {} 条数据",
                                transCompanyId, originExpenseItemId, orderCategoryStr, itemGroupResults.size());

                        // 创建账单实体并计算汇总字段
                        MoneyBillEntity entity = new MoneyBillEntity();
                        entity.setStationId(transCompanyId);
                        entity.setStartTime(lastMonthStart.toLocalDate());
                        entity.setEndTime(lastMonthEnd.toLocalDate());
                        entity.setGoodsId(originExpenseItemId);

                        // 1. 订单数量：通过orderId分组，条数就是订单数
                        long orderCount = itemGroupResults.stream()
                                .map(MoneyBillResult::getOrderId)
                                .distinct()
                                .count();
                        entity.setOrderCount((int) orderCount);

                        // 2. 车数=订单数
                        entity.setCarCount((int) orderCount);

                        // 3. 总质量
                        int totalWeight = itemGroupResults.stream()
                                .mapToInt(MoneyBillResult::getSettleWeight)
                                .sum();
                        entity.setTotalWeight(totalWeight);

                        // 4. 优惠金额：discountMoney求和，可能是负数
                        BigDecimal totalDiscountMoney = itemGroupResults.stream()
                                .map(MoneyBillResult::getDiscountMoney)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        entity.setDiscountMoney(totalDiscountMoney);

                        // 5. 账单金额：settleMoney求和，可能是负数
                        BigDecimal totalSettleMoney = itemGroupResults.stream()
                                .map(MoneyBillResult::getSettleMoney)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        entity.setTotalMoney(totalSettleMoney);

                        // 设置其他基本信息（取第一条记录的信息）
                        MoneyBillResult firstResult = itemGroupResults.get(0);
                        entity.setUserId(firstResult.getUserId());
                        entity.setGoodsName(firstResult.getExpenseItemName());

                        // 如果存在订单类型字符串，则直接设置（实体中为 String 类型）
                        if (orderCategoryStr != null) {
                            entity.setOrderCategory(orderCategoryStr);
                        }

                        entityList.add(entity);
                        log.info("生成账单实体: transCompanyId={}, originExpenseItemId={}, orderCategory={}, 订单数={}, 总质量={}, 车数={}, 优惠金额={}, 账单金额={}",
                                transCompanyId, originExpenseItemId, orderCategoryStr, orderCount, totalWeight, orderCount, totalDiscountMoney, totalSettleMoney);
                    }
                }
            }
            // 账单入库
            moneyBillMapper.insert(entityList);
        }

    }

}
