package com.njzscloud.supervisory.money.quartz;

import com.njzscloud.supervisory.goods.contant.MoneyStrategy;
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;

@Slf4j
@Component
@RequiredArgsConstructor
public class MoneyBillQuartz {

    private final MoneyBillMapper moneyBillMapper;

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

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

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

        // 执行查询
        List<MoneyBillResult> billResults = moneyBillMapper.selectMoneyBillList(queryCondition);

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

        if (billResults.size() > 0) {
            // 先按transCompanyId分组，再按originExpenseItemId分组
            Map<Long, Map<Long, List<MoneyBillResult>>> groupedResults = billResults.stream()
                    .collect(Collectors.groupingBy(
                            MoneyBillResult::getTransCompanyId,
                            Collectors.groupingBy(MoneyBillResult::getOriginExpenseItemId)
                    ));

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

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

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

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

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

                    // 这里可以根据业务需求处理每个分组的数据
                    // 例如：计算总金额、创建MoneyBillEntity等
                    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. 总质量：quantity求和，条件是计费策略不等于"车"
                    int totalWeight = itemGroupResults.stream()
                            .filter(result -> !MoneyStrategy.Che.getVal().equals(result.getMoneyStrategy()))
                            .mapToInt(MoneyBillResult::getQuantity)
                            .sum();
                    entity.setTotalWeight(totalWeight);

                    // 3. 车数：quantity求和，条件是计费策略等于"车"
                    int totalCars = itemGroupResults.stream()
                            .filter(result -> MoneyStrategy.Che.getVal().equals(result.getMoneyStrategy()))
                            .mapToInt(MoneyBillResult::getQuantity)
                            .sum();
                    entity.setCarCount(totalCars);

                    // 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());
                    entityList.add(entity);
                    log.info("生成账单实体: transCompanyId={}, originExpenseItemId={}, 订单数={}, 总质量={}, 车数={}, 优惠金额={}, 账单金额={}",
                            transCompanyId, originExpenseItemId, orderCount, totalWeight, totalCars, totalDiscountMoney, totalSettleMoney);
                }
            }
            // 账单入库
            moneyBillMapper.insert(entityList);
        }

    }

}
