package org.jebot.scheduled;

import cn.hutool.core.date.DateUtil;
import com.pengrad.telegrambot.TelegramBot;
import com.pengrad.telegrambot.request.SendMessage;
import com.pengrad.telegrambot.response.SendResponse;
import lombok.extern.slf4j.Slf4j;
import org.jebot.constant.Constant;
import org.jebot.models.jebot.BotAccountBook;
import org.jebot.models.jebot.BotGroup;
import org.jebot.models.jebot.BotWarn;
import org.jebot.models.xxpay.MchAccount;
import org.jebot.models.xxpay.PayOrder;
import org.jebot.repository.jebot.BotAccountBookRepository;
import org.jebot.repository.jebot.BotGroupRepository;
import org.jebot.repository.jebot.BotWarnRepository;
import org.jebot.repository.xxpay.MchAccountRepository;
import org.jebot.repository.xxpay.PayOrderRepository;
import org.jebot.repository.xxpay.TransOrderRepository;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.jebot.util.DateUtil.getTodayMidnight;

@Slf4j
@Configuration
public class MchScheduled {

    @Resource
    TelegramBot telegramBot;


    @Resource
    private BotWarnRepository botWarnRepository;

    @Resource
    private BotGroupRepository botGroupRepository;

    @Resource
    private PayOrderRepository payOrderRepository;

    @Resource
    private TransOrderRepository transOrderRepository;

    @Resource
    private MchAccountRepository mchAccountRepository;

    @Resource
    private BotAccountBookRepository botAccountBookRepository;

    @Scheduled(cron = "*/30 * * * * *")
    public void insufficientBalanceWarning() {
        log.info("定时任务开始执行");
        // 定时任务逻辑
        List<BotGroup> botGroups = botGroupRepository.findAllByAgentWarningThresholdOrPaymentWarningThresholdGreaterThanZero();
        // 过滤出商户群组
        List<BotGroup> mchGroups = botGroups.stream().filter(botGroup -> Constant.DATA_TYPE_MERCHANT.equals(botGroup.getDataType())).collect(Collectors.toList());
        if (!mchGroups.isEmpty()) {
            List<Long> mchIds = mchGroups.stream().map(BotGroup::getDataId).collect(Collectors.toList());
            List<MchAccount> mchAccounts = mchAccountRepository.findByMchIds(mchIds);
            if (mchAccounts.isEmpty()) {
                return;
            }
            Map<Long, MchAccount> mchAccountMap = mchAccounts.stream()
                    .collect(Collectors.toMap(MchAccount::getMchId, mchAccount -> mchAccount));

            for (BotGroup mchGroup : mchGroups) {
                MchAccount mchAccount = mchAccountMap.get(mchGroup.getDataId());
                if (mchAccount == null || mchAccount.getStatus() != 1) {
                    continue;
                }
                if (mchGroup.getPaymentWarningThreshold() < 1 && mchGroup.getAgentWarningThreshold() < 1) {
                    continue;
                }
                BotAccountBook accountBook = botAccountBookRepository.findByBelongIdAndType(mchGroup.getDataId(), Constant.DATA_TYPE_MERCHANT);
                if (accountBook == null) {
                    continue;
                }
                if (mchGroup.getPaymentWarningThreshold() > 0) {
                    BigDecimal totalPayOrderAmount = payOrderRepository.findPayOrderAmountByMchIdAndCreateTime(Long.valueOf(mchGroup.getDataId()), getTodayMidnight(new Date()));
                    if (totalPayOrderAmount == null) {
                        continue;
                    }

                    BigDecimal paymentBalance = BigDecimal.valueOf(accountBook.getPaymentBalance()).movePointRight(Constant.AMOUNT_MOVE_POINT);

                    // 计算差额
                    BigDecimal difference = paymentBalance.subtract(totalPayOrderAmount);

                    // 计算百分比
                    BigDecimal percentage = totalPayOrderAmount
                            .divide(paymentBalance, 2, RoundingMode.HALF_UP)
                            .movePointRight(Constant.AMOUNT_MOVE_POINT);
                    percentage = BigDecimal.valueOf(100).subtract(percentage);
                    if (percentage.doubleValue() < mchGroup.getPaymentWarningThreshold()) {
                        //30分钟内已经发送过预警消息，跳过预警
                        BotWarn botWarn = botWarnRepository.findByDataIdAndWarnType(mchGroup.getDataId(), Constant.PAYMENT, Constant.DATA_TYPE_MERCHANT);
                        if (botWarn != null && botWarn.getUpdateTime().after(DateUtil.offsetMinute(new Date(), -30))) {
                            continue;
                        }
                        SendMessage sendMessage = new SendMessage(mchGroup.getGroupId(), "预付余额不足,请及时充值 " +
                                "\n差额比例: " + percentage +
                                "%\n当前余额: " + accountBook.getPaymentBalance() +
                                "\n已用额度: " + totalPayOrderAmount.movePointLeft(Constant.AMOUNT_MOVE_POINT) +
                                "\n剩余额度: " + difference.movePointLeft(Constant.AMOUNT_MOVE_POINT));
                        SendResponse execute = telegramBot.execute(sendMessage);
                        if (execute.isOk()) {
                            if (botWarn == null) {
                                botWarn = new BotWarn();
                                botWarn.setDataId(mchGroup.getDataId());
                                botWarn.setWarnType(Constant.PAYMENT);
                                botWarn.setDataType(Constant.DATA_TYPE_MERCHANT);
                                botWarn.setUpdateTime(new Date());
                                botWarnRepository.save(botWarn);
                            } else {
                                botWarn.setUpdateTime(new Date());
                                botWarnRepository.save(botWarn);
                            }
                            log.info("成功发送余额不足预警消息,商户ID为:" + mchGroup.getDataId() + ",群组ID为:" + mchGroup.getGroupId());
                        } else {
                            log.error("发送余额不足预警消息失败,商户ID为:" + mchGroup.getDataId() + ",群组ID为:" + mchGroup.getGroupId());
                        }

                    }
                }
                if (mchGroup.getAgentWarningThreshold() > 0) {
                    BigDecimal totalTransOrderAmount = transOrderRepository.findTransOrderAmountByMchIdAndCreateTime(Long.valueOf(mchGroup.getDataId()), DateUtil.formatDateTime(getTodayMidnight(new Date())));
                    if (totalTransOrderAmount == null) {
                        continue;
                    }
                    BigDecimal agentBalance = BigDecimal.valueOf(accountBook.getAgentBalance()).movePointRight(Constant.AMOUNT_MOVE_POINT);
                    // 计算差额
                    BigDecimal difference = agentBalance.subtract(totalTransOrderAmount);
                    // 计算百分比
                    BigDecimal percentage = totalTransOrderAmount
                            .divide(agentBalance, 2, RoundingMode.HALF_UP)
                            .movePointRight(Constant.AMOUNT_MOVE_POINT);
                    percentage = BigDecimal.valueOf(100).subtract(percentage);
                    if (percentage.doubleValue() < mchGroup.getAgentWarningThreshold()) {
                        //15分钟内已经发送过预警消息，跳过预警
                        BotWarn botWarn = botWarnRepository.findByDataIdAndWarnType(mchGroup.getDataId(), Constant.AGENT, Constant.DATA_TYPE_MERCHANT);
                        if (botWarn != null && botWarn.getUpdateTime().after(DateUtil.offsetMinute(new Date(), -15))) {
                            continue;
                        }
                        SendMessage sendMessage = new SendMessage(mchGroup.getGroupId(), "代付余额不足,请及时充值 " +
                                "\n差额比例: " + percentage +
                                "%\n当前余额: " + accountBook.getAgentBalance() +
                                "\n已用额度: " + totalTransOrderAmount.movePointLeft(Constant.AMOUNT_MOVE_POINT) +
                                "\n剩余额度: " + difference.movePointLeft(Constant.AMOUNT_MOVE_POINT));
                        SendResponse execute = telegramBot.execute(sendMessage);
                        if (execute.isOk()) {
                            if (botWarn == null) {
                                botWarn = new BotWarn();
                                botWarn.setDataId(mchGroup.getDataId());
                                botWarn.setWarnType(Constant.AGENT);
                                botWarn.setDataType(Constant.DATA_TYPE_MERCHANT);
                                botWarn.setUpdateTime(new Date());
                                botWarnRepository.save(botWarn);
                            } else {
                                botWarn.setUpdateTime(new Date());
                                botWarnRepository.save(botWarn);
                            }
                            log.info("成功发送余额不足预警消息,商户ID为:" + mchGroup.getDataId() + ",群组ID为:" + mchGroup.getGroupId());
                        } else {
                            log.error("发送余额不足预警消息失败,商户ID为:" + mchGroup.getDataId() + ",群组ID为:" + mchGroup.getGroupId());
                        }

                    }

                }
            }

        }
    }

}
