package com.leromro.core.ttl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.leromro.core.domain.*;
import com.leromro.core.mapper.*;
import com.leromro.core.utils.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component("monitor")
public class Monitor {
    @Autowired
    private PlatformFinanceMapper platformFinanceMapper;
    @Autowired
    private SecondOrdersMapper secondOrdersMapper;
    @Autowired
    private OrderFrozenFundsMapper orderFrozenFundsMapper;
    @Autowired
    private VolunteerAccountMapper volunteerAccountMapper;
    @Autowired
    private VolunteerAccountChangeMapper volunteerAccountChangeMapper;

    /**
     * 定时任务定时调用的任务
     */
    @Transactional
    public void orderMonitor() {
        System.out.println("开始查询解冻时间");
        //查询数据库，查到需要解冻的数据的集合
        QueryWrapper<OrderFrozenFunds> queryFrozenWrapper = new QueryWrapper<OrderFrozenFunds>().eq("status", 0).lt("frozen_end_time", DateTimeUtil.getNowTime());
        //万物起源：查到冻结的订单，
        List<OrderFrozenFunds> needThawMoneyList = orderFrozenFundsMapper.selectList(queryFrozenWrapper);
        if (needThawMoneyList.isEmpty()) {
            System.out.println("没有需要解冻的订单");
            return;
        }
        List<Long> orderFrozenFundsIdList = needThawMoneyList.stream().map(OrderFrozenFunds::getOrderFrozenFundsId).collect(Collectors.toList());
        List<Long> seconderOrderIdList = needThawMoneyList.stream().map(OrderFrozenFunds::getSecondOrderId).collect(Collectors.toList());
        List<Long> volunteerIdList = needThawMoneyList.stream().map(OrderFrozenFunds::getVolunteerId).distinct().collect(Collectors.toList());

        //向 有 小订单列表中添加金额，区域公司抽成金额 = 解冻金额中的抽成金额 * 区域公司的抽成比例 服务中心抽成金额 = 解冻金额中的抽成金额 * 服务中心抽成金额的抽成比例


        //查到旧的志愿者账户表的余额（用来存放志愿者月变更记录）
        //更新表，直接解冻。
        UpdateWrapper<OrderFrozenFunds> updateFrozenWrapper = new UpdateWrapper<OrderFrozenFunds>().in("order_frozen_funds_id", orderFrozenFundsIdList).set("status", 1);
        orderFrozenFundsMapper.update(null, updateFrozenWrapper);
        //志愿者订单表  已完成订单 默认评价
        UpdateWrapper<SecondOrder> updateSecondOrderWrapper = new UpdateWrapper<SecondOrder>().eq("order_status", "4").in("second_order_id", seconderOrderIdList).set("score", 1).setSql("remark = CASE WHEN score IS NULL OR score = '' THEN '用户未评价，系统默认一星' ELSE remark END");
        secondOrdersMapper.update(null, updateSecondOrderWrapper);
        //解冻后，向平台流水表中添加数据
        // 1.先添加志愿者变更金额
        List<PlatformFinance> volunteerPlatformList = needThawMoneyList.stream().map(orderFrozenFunds -> new PlatformFinance(null, orderFrozenFunds.getVolunteerMoney(), 1, 2, 3, orderFrozenFunds.getSecondOrderId(), orderFrozenFunds.getVolunteerId())).collect(Collectors.toList());
        //platformFinanceMapper.insertPlatformFinanceList(volunteerPlatformList);
        // 2.然后添加平台变更金额
        List<PlatformFinance> platformPlatformList = needThawMoneyList.stream().map(orderFrozenFunds -> new PlatformFinance(null, orderFrozenFunds.getPlatformBrokerage(), 1, 3, 3, orderFrozenFunds.getSecondOrderId(), orderFrozenFunds.getVolunteerId())).collect(Collectors.toList());

        //查出所有已分配服务中心的需要解冻的小订单
        List<SecondOrder> secondOrderList = secondOrdersMapper.selectList(new LambdaQueryWrapper<SecondOrder>().in(SecondOrder::getSecondOrderId, seconderOrderIdList));

        // 构建map 拿到secondOrderId 和 金额
        Map<Long, BigDecimal> brokerageMap = platformPlatformList.stream() .collect(Collectors.toMap(PlatformFinance::getSecondOrderId, PlatformFinance::getChangeMoney));

        // 遍历 secondOrderList 更新区域公司的钱并且当平台已分配服务中心时，设置服务中心的分成
        for (SecondOrder secondOrder : secondOrderList) {
            BigDecimal platformBrokerage = brokerageMap.get(secondOrder.getSecondOrderId());
            if (secondOrder.getAllotStatus().equals("20")) {
                BigDecimal serviceCentreDistributionRatio = secondOrder.getServiceCentreDistributionRatio();
                BigDecimal distributionAmount1 = platformBrokerage.multiply(serviceCentreDistributionRatio);
                secondOrder.setServiceCentreDistributionAmount(distributionAmount1);
            }
            BigDecimal areaDistributionRatio = secondOrder.getAreaDistributionRatio();
            BigDecimal distributionAmount2 = platformBrokerage.multiply(areaDistributionRatio);
            secondOrder.setAreaDistributionAmount(distributionAmount2);
            secondOrder.setVolunteerSettlementStatus("20");
        }

        secondOrdersMapper.updatedeptAmountList(secondOrderList);

        //platformFinanceMapper.insertPlatformFinanceList(platformPlatformList);
        // 3.然后添加奖金 并且添加备注
        List<PlatformFinance> sourceTypePlatformList = needThawMoneyList.stream().filter(orderFrozenFunds -> orderFrozenFunds.getScoreMoney() != null).map(orderFrozenFunds -> new PlatformFinance(null, orderFrozenFunds.getScoreMoney(), 1, 2, 3, orderFrozenFunds.getSecondOrderId(), orderFrozenFunds.getVolunteerId())).peek(pf -> pf.setRemark("奖金"))
                .collect(Collectors.toList());
        // 合并三个集合
        List<PlatformFinance> mergedList = Stream.of(volunteerPlatformList, platformPlatformList, sourceTypePlatformList)
                .flatMap(List::stream)
                .collect(Collectors.toList());

        platformFinanceMapper.insertPlatformFinanceList(mergedList);
        /*System.out.println("只剩change记录和余额变动了");*/
        // ---------------------------
        //解冻后：
        //判断，如果志愿者有多个订单？？？？？？？？？？？
        //查出志愿者id集合


        //首先将志愿者id和志愿者账户余额封装成map集合
        Map<Long, List<VolunteerAccount>> volunteerAccountMap = volunteerAccountMapper.selectList(new LambdaQueryWrapper<VolunteerAccount>().in(VolunteerAccount::getVolunteerId, volunteerIdList)).stream().collect(Collectors.groupingBy(VolunteerAccount::getVolunteerId));
        //遍历其中一个集合，然后用键来匹配值，进行操作
        if (volunteerAccountMap.isEmpty()) {
            throw new RuntimeException("志愿者账户异常，该志愿者未创建账户");
        }

        //还是获取map<userId,list<解冻数据>>
        Map<Long, List<OrderFrozenFunds>> volunteerAccountChangeGroupByVId = needThawMoneyList.stream().collect(Collectors.groupingBy(OrderFrozenFunds::getVolunteerId));
        //生成所有的记录
        //List<Object[]> volunteerAccountChanges = new ArrayList<>();
        List<VolunteerAccountChange> volunteerAccountChangeList = new ArrayList<>();

        //生成所有的记录对象
        //改！  这里我们根据map的键 去取出余额的集合，
        volunteerAccountChangeGroupByVId.forEach((volunteerId, orderFrozenFunds) -> {
            //


            //查看用户当前的余额 其实没必要再循环中写sql了，因为每一个用户都是一次单独的遍历，
           /* BigDecimal oldVolunteerBalance = jdbcTemplate.queryForObject("select balance from l_volunteer_account where volunteer_id = ? ",
                    BigDecimal.class, volunteerId);*/
            BigDecimal oldVolunteerBalance = volunteerAccountMap.get(volunteerId).get(0).getBalance();
            BigDecimal beforeChangeBalance = BigDecimal.valueOf(0);

            for (OrderFrozenFunds orderFrozenFund : orderFrozenFunds) {
                VolunteerAccountChange volunteerAccountChange1 = new VolunteerAccountChange(null, volunteerId, "1", "1", orderFrozenFund.getVolunteerMoney(), beforeChangeBalance.add(oldVolunteerBalance), orderFrozenFund.getVolunteerMoney().add(beforeChangeBalance).add(oldVolunteerBalance), orderFrozenFund.getSecondOrderId());
                volunteerAccountChange1.setCreateTime(DateTimeUtil.getNowTime());
                volunteerAccountChangeList.add(volunteerAccountChange1);
               /* volunteerAccountChanges.add(new Object[]{volunteerId,1,1,orderFrozenFund.getVolunteerMoney(),beforeChangeBalance.add(oldVolunteerBalance),orderFrozenFund.getVolunteerMoney().add(beforeChangeBalance).add(oldVolunteerBalance)
                });*/
                beforeChangeBalance = beforeChangeBalance.add(orderFrozenFund.getVolunteerMoney());

                if (orderFrozenFund.getScoreMoney() != null && orderFrozenFund.getScoreMoney().compareTo(BigDecimal.ZERO) != 0) {
                    VolunteerAccountChange volunteerAccountChange2 = new VolunteerAccountChange(null, volunteerId, "1", "2", orderFrozenFund.getScoreMoney(), beforeChangeBalance.add(oldVolunteerBalance), orderFrozenFund.getScoreMoney().add(beforeChangeBalance).add(oldVolunteerBalance), orderFrozenFund.getSecondOrderId());
                    volunteerAccountChange2.setCreateTime(DateTimeUtil.getNowTime());
                    volunteerAccountChangeList.add(volunteerAccountChange2);
                    /*volunteerAccountChanges.add(new Object[]{volunteerId,1,1,orderFrozenFund.getScoreMoney(),beforeChangeBalance.add(oldVolunteerBalance),orderFrozenFund.getScoreMoney().add(beforeChangeBalance).add(oldVolunteerBalance)
                    });*/
                }
                beforeChangeBalance = beforeChangeBalance.add(orderFrozenFund.getScoreMoney());
            }
            // 插入记录
            /*  jdbcTemplate.batchUpdate("insert into l_volunteer_account_change (volunteer_id,change_type,source_type,change_money,before_balance,after_balance) values (?,?,?,?,?,?)" , volunteerAccountChanges);*/
            //直接插入一个集合，不用在循环中写sql了
        });

        volunteerAccountChangeMapper.insertList(volunteerAccountChangeList);

        //还是获取map<userId,list<解冻数据>>

/*
        //生成所有的奖金记录对象
        volunteerAccountChangeGroupByVId.forEach((volunteerId,orderFrozenFunds) -> {
            //查看用户当前的余额
            BigDecimal oldVolunteerBalance = jdbcTemplate.queryForObject("select balance from l_volunteer_account where volunteer_id = ? ",
                    BigDecimal.class, volunteerId);
            //生成所有的记录
            List<Object[]> volunteerAccountChanges = new ArrayList<>();
            BigDecimal beforeChangeBalance = BigDecimal.valueOf(0);
            for (OrderFrozenFunds orderFrozenFund : orderFrozenFunds) {
                if (orderFrozenFund.getScoreMoney() != null && orderFrozenFund.getScoreMoney().compareTo(BigDecimal.ZERO) != 0){
                volunteerAccountChanges.add(new Object[]{volunteerId,1,1,orderFrozenFund.getScoreMoney(),beforeChangeBalance.add(oldVolunteerBalance),orderFrozenFund.getScoreMoney().add(beforeChangeBalance).add(oldVolunteerBalance)
                });
                }
                beforeChangeBalance = beforeChangeBalance.add(orderFrozenFund.getScoreMoney());
            }
            //批量插入记录
            jdbcTemplate.batchUpdate("insert into l_volunteer_account_change (volunteer_id,change_type,source_type,change_money,before_balance,after_balance) values (?,?,?,?,?,?)" , volunteerAccountChanges);
        });
*/

        /* */

        //解冻后：
        //获取冻结表中的志愿者id和志愿者总共需要解冻到账户的金额 封装成map集合 有相同的 也直接加起来。
        Map<Long, BigDecimal> totalMoneyMap = needThawMoneyList.stream().collect(Collectors.toMap(OrderFrozenFunds::getVolunteerId, orderFrozenFunds -> orderFrozenFunds.getVolunteerMoney().add(orderFrozenFunds.getScoreMoney()), (existingValue, newValue) -> existingValue.add(newValue)));
        //解冻后，向志愿者账户表中＋钱（基本+奖金） //首先取出要修改的志愿者账户集合，算出每个账户 遍历这些集合，，可提现金额 = 旧可提现金额 + 总；累计可提现金额 = 旧可体现金额 + 总；订单中冻结金额 = 旧冻结金额 - 总
        List<VolunteerAccount> newVolunteerAccountList = new ArrayList<>();
        totalMoneyMap.forEach((volunteerId, totalChangMoney) -> {
            VolunteerAccount vact = new VolunteerAccount().builder().volunteerId(volunteerId).balance(totalChangMoney).totalBalance(totalChangMoney).orderFrozenBalance(totalChangMoney).build();
            newVolunteerAccountList.add(vact);
        });
        //向志愿者记录表中修改
        volunteerAccountMapper.updateVolunteerAccountList(newVolunteerAccountList);

        System.out.println("全部更新完毕");

    }
}
