package com.xinelu.quartz.task;

import com.xinelu.common.constant.Constants;
import com.xinelu.common.constant.PaymentStatusConstants;
import com.xinelu.common.enums.BillSourceEnum;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.manage.domain.billinfo.BillInfo;
import com.xinelu.manage.domain.phonedialrecord.PhoneDialRecord;
import com.xinelu.manage.domain.shortmessagesendrecord.ShortMessageSendRecord;
import com.xinelu.manage.mapper.billinfo.BillInfoMapper;
import com.xinelu.manage.mapper.phonedialrecord.PhoneDialRecordMapper;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description: 月初生成上月的的账单任务
 * @author: zh
 * @create: 2026-06-23
 **/
@Slf4j
@Component("BillTask")
public class BillTask {

    @Resource
    private ShortMessageSendRecordMapper shortMessageSendRecordMapper;
    @Resource
    private PhoneDialRecordMapper phoneDialRecordMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private BillInfoMapper billInfoMapper;

    @Transactional(rollbackFor = Exception.class)
    public void generateBillTask() {
        // 1.1 获取上个月的 YearMonth 对象
        YearMonth lastMonth = YearMonth.now().minusMonths(1);
        // 1.2 获取上个月第一天 00:00:00（开始）
        LocalDateTime startOfLastMonth = lastMonth.atDay(1).atStartOfDay();
        // 1.3 获取上个月最后一天 23:59:59（结束）
        LocalDateTime endOfLastMonth = lastMonth.atEndOfMonth().atTime(23, 59, 59);
        //2.查询上月短信推送记录
        BillInfo shortBillInfo = new BillInfo();
        shortBillInfo.setBillCode(Constants.BILL_CODE + generateSystemCodeUtil.generateSystemCode(Constants.AGENCY_CODE));
        shortBillInfo.setBillName(lastMonth.getMonthValue() + "月份短信账单");
        shortBillInfo.setBillMonth(lastMonth.toString());
        shortBillInfo.setPaymentStatus(PaymentStatusConstants.UNPAID_FEES);
        shortBillInfo.setBillSource(BillSourceEnum.MESSAGE.getInfo());
        List<ShortMessageSendRecord> shortMessageSendRecords = shortMessageSendRecordMapper.selectRecordBySendTime(startOfLastMonth, endOfLastMonth);
        if (CollectionUtils.isNotEmpty(shortMessageSendRecords)) {
            long sum = shortMessageSendRecords.stream().filter(Objects::nonNull)
                    .mapToLong(ShortMessageSendRecord::getMessageQuantity)
                    .sum();
            shortBillInfo.setPushLength(new BigDecimal(sum));

            BigDecimal totalAmount = shortMessageSendRecords.stream().filter(Objects::nonNull)
                    .map(ShortMessageSendRecord::getMessageExpense)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            shortBillInfo.setBillExpense(totalAmount);
            billInfoMapper.insertBillInfo(shortBillInfo);
            List<Long> shortIds = shortMessageSendRecords.stream().filter(Objects::nonNull).map(ShortMessageSendRecord::getId).collect(Collectors.toList());
            shortMessageSendRecordMapper.updateShortMessageSendRecordByIds(shortIds, shortBillInfo.getId());
        }
        //2.查询上月电话推送记录
        BillInfo phoneBillInfo = new BillInfo();
        phoneBillInfo.setBillCode(Constants.BILL_CODE + generateSystemCodeUtil.generateSystemCode(Constants.AGENCY_CODE));
        phoneBillInfo.setBillName(lastMonth.getMonthValue() + "月份电话账单");
        phoneBillInfo.setBillMonth(lastMonth.toString());
        phoneBillInfo.setPaymentStatus(PaymentStatusConstants.UNPAID_FEES);
        phoneBillInfo.setBillSource(BillSourceEnum.TELEPHONE.getInfo());
        List<PhoneDialRecord> phoneDialRecords = phoneDialRecordMapper.selectPhoneDialBySendTime(startOfLastMonth, endOfLastMonth);
        if (CollectionUtils.isNotEmpty(phoneDialRecords)) {
            BigDecimal sum = phoneDialRecords.stream().filter(Objects::nonNull)
                    .map(PhoneDialRecord::getPhoneDuration)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            phoneBillInfo.setPushLength(sum);

            BigDecimal totalAmount = phoneDialRecords.stream().filter(Objects::nonNull)
                    .map(PhoneDialRecord::getPhoneExpense)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            phoneBillInfo.setBillExpense(totalAmount);
            billInfoMapper.insertBillInfo(phoneBillInfo);
            List<Long> phoneIds = phoneDialRecords.stream().filter(Objects::nonNull).map(PhoneDialRecord::getId).collect(Collectors.toList());
            phoneDialRecordMapper.updatePhoneDialRecordByIds(phoneIds, phoneBillInfo.getId());
        }
    }
}