package cn.wisenergy.service.Manager;

import cn.wisenergy.common.utils.DateUtil;
import cn.wisenergy.mapper.*;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.enums.RebateStatusEnum;
import cn.wisenergy.model.enums.TradeRecordEnum;
import cn.wisenergy.model.enums.TradeStatusEnum;
import cn.wisenergy.model.vo.TeamPerformanceSortVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 86187
 * @ Description: 账户管理公共类
 * @ Author     : 86187
 * @ Date       : 2021/2/23 10:43
 */
@Component
@Slf4j
public class AccountManager {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private TradeRecordMapper recordMapper;

    @Autowired
    private TeamPerformanceMapper teamPerformanceMapper;

    @Autowired
    private ProgressPrizeMapper progressPrizeMapper;

    @Autowired
    private TradeRecordMapper tradeRecordMapper;

    @Autowired
    private MonthManureMapper monthManureMapper;


    private static final String PATTERN = "yyyy-MM";


    /**
     * 保存用户佣金
     *
     * @param orderInfo     订单信息
     * @param accountInfo   账户信息
     * @param memberPercent 会员等级百比分
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderAddMoney(OrderInfo orderInfo, AccountInfo accountInfo, MemberPercent memberPercent) {
        //1、计算返佣金额
        BigDecimal bigDecimal = orderInfo.getPayment().multiply(memberPercent.getPercent());
        BigDecimal extractMoney = accountInfo.getExtractMoney().add(bigDecimal);
        accountInfo.setExtractMoney(extractMoney.setScale(2, RoundingMode.HALF_UP));

        BigDecimal performanceMonth = accountInfo.getEarningsMonth().add(bigDecimal);
        accountInfo.setEarningsMonth(performanceMonth.setScale(2, RoundingMode.HALF_UP));

        BigDecimal performanceTotal = accountInfo.getEarningsTotal().add(bigDecimal);
        accountInfo.setEarningsTotal(performanceTotal.setScale(2, RoundingMode.HALF_UP));

        //2、修改订单返佣状态:已返佣 1
        orderInfo.setRebateStatus(RebateStatusEnum.ALREADY_REBATE.getCode());

        orderMapper.updateById(orderInfo);
        String time = DateUtil.convertDateToStr(new Date(), "yyyy-MM-dd hh:mm:ss");
        log.info("订单" + orderInfo.getTid() + "在" + time + "时返佣:" + bigDecimal);

        //3、更新账户可用金额
        accountMapper.edit(accountInfo);

        //4、添加交易流水记录
        TradeRecord tradeRecord = new TradeRecord();
        tradeRecord.setUserId(orderInfo.getUserId());
        tradeRecord.setTradeType(TradeRecordEnum.ORDER_REBATE.getCode());
        tradeRecord.setTradeNo(orderInfo.getTid());
        tradeRecord.setStatus(TradeStatusEnum.ALREADY_SETTLE_ACCOUNTS.getCode());
        tradeRecord.setMoney(bigDecimal);
        recordMapper.add(tradeRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAccountPerformanceMonth(List<TeamPerformance> addList, List<TeamPerformance> updateList) {

        //1、新增
        if (!CollectionUtils.isEmpty(addList)) {
            for (TeamPerformance teamPerformance : addList) {
                int count = teamPerformanceMapper.add(teamPerformance);
                if (count == 0) {
                    return false;
                }
                log.info("月度肥料新增用户" + teamPerformance.getUserId() + "团队绩效:" + teamPerformance.getMonthTeamPerformance());
            }
        }

        //2、更新
        if (!CollectionUtils.isEmpty(updateList)) {
            for (TeamPerformance teamPerformance : updateList) {
                int count = teamPerformanceMapper.edit(teamPerformance);
                if (count == 0) {
                    return false;
                }
                log.info("月度肥料更新用户" + teamPerformance.getUserId() + "团队绩效为:" + teamPerformance.getMonthTeamPerformance());
            }
        }
        return true;
    }

    /**
     * 修改 或新增  删除 最大进步奖实体类
     *
     * @param addList         最新的进步奖 对象
     * @param accountInfoList 要更新的最大进步奖账户收益
     * @param prizes          上一次统计的进步奖 对象
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateOrSavePrize(List<AccountInfo> accountInfoList,
                                     List<ProgressPrize> prizes, List<ProgressPrize> addList,
                                     List<ProgressPrize> updateList, int flag) {

        //1、存在的修改,不存在的新增,多余的,删除
        List<String> userIds = prizes.stream().map(ProgressPrize::getUserId).collect(Collectors.toList());
        List<ProgressPrize> deleteList = new ArrayList<>();

        //遍历:要删除的数据
        for (ProgressPrize progressPrize : prizes) {
            if (!userIds.contains(progressPrize.getUserId())) {
                deleteList.add(progressPrize);
            }
        }

        for (ProgressPrize deletePrize : deleteList) {
            int count = progressPrizeMapper.delById(deletePrize.getId());
            if (count == 0) {
                return false;
            }
        }

        //更新
        for (ProgressPrize updatePrize : updateList) {
            int count = progressPrizeMapper.edit(updatePrize);
            log.info("更新最大进步奖用户" + updatePrize.getUserId() + "奖金为:" + updatePrize.getAwardMoney());
            if (count == 0) {
                return false;
            }
        }

        //新增
        for (ProgressPrize addPrize : addList) {
            int count = progressPrizeMapper.add(addPrize);
            log.info("新增最大进步奖用户" + addPrize.getUserId() + "奖金:" + addPrize.getAwardMoney());
            if (count == 0) {
                return false;
            }
        }


        //3、添加账户获得的收益
        for (AccountInfo accountInfo : accountInfoList) {
            accountMapper.edit(accountInfo);
            log.info("最大进步奖更新用户" + accountInfo.getUserId() + "月收益:" + accountInfo.getEarningsMonth());

            //添加交易流水记录
            TradeRecord tradeRecord = new TradeRecord();
            tradeRecord.setUserId(accountInfo.getUserId());
            tradeRecord.setTradeType(TradeRecordEnum.PROGRESS_PRIZE.getCode());
            tradeRecord.setTradeNo(null);
            if (flag == 1) {
                tradeRecord.setStatus(TradeStatusEnum.NO_SETTLE_ACCOUNTS.getCode());
            } else {
                tradeRecord.setStatus(TradeStatusEnum.ALREADY_SETTLE_ACCOUNTS.getCode());
            }

            int count = recordMapper.add(tradeRecord);
            if (count == 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 更新账户信息和保存交易流水记录
     *
     * @param accountInfoList 账户列表
     * @param recordList      交易流水信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAccountAddRecord(List<AccountInfo> accountInfoList, List<TradeRecord> recordList) {

        //更新月收益
        if (!CollectionUtils.isEmpty(accountInfoList)) {
            for (AccountInfo accountInfo : accountInfoList) {
                int count = accountMapper.edit(accountInfo);
                if (count == 0) {
                    return false;
                }
                log.info("月度肥料更新用户" + accountInfo.getUserId() + "月收益" + accountInfo.getEarningsMonth());
            }
        }

        //新增交易流水记录
        if (!CollectionUtils.isEmpty(recordList)) {
            for (TradeRecord tradeRecord : recordList) {
                int count = tradeRecordMapper.add(tradeRecord);
                if (count == 0) {
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 运营中心更新账户信息和保存交易流水记录
     *
     * @param accountInfoList 账户列表
     * @param recordList      交易流水信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean runCenterUpdateAccountAddRecord(List<AccountInfo> accountInfoList, List<TradeRecord> recordList) {

        //更新月收益
        if (!CollectionUtils.isEmpty(accountInfoList)) {
            for (AccountInfo accountInfo : accountInfoList) {
                int count = accountMapper.edit(accountInfo);
                if (count == 0) {
                    return false;
                }
                log.info("运营中心更新用户" + accountInfo.getUserId() + "月收益" + accountInfo.getEarningsMonth());
            }
        }

        //新增交易流水记录
        if (!CollectionUtils.isEmpty(recordList)) {
            for (TradeRecord tradeRecord : recordList) {
                int count = tradeRecordMapper.add(tradeRecord);
                if (count == 0) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 更新账户信息和保存交易流水记录保存最大进步奖信息
     *
     * @param accountInfoList 账户列表
     * @param recordList      交易流水信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAccountAddRecordAddPrize(List<AccountInfo> accountInfoList, List<TradeRecord> recordList,
                                                  List<ProgressPrize> addPrizeList, List<ProgressPrize> updatePrizeList) {

        //更新月收益
        if (!CollectionUtils.isEmpty(accountInfoList)) {
            for (AccountInfo accountInfo : accountInfoList) {
                int count = accountMapper.edit(accountInfo);
                if (count == 0) {
                    return false;
                }
                log.info("最大进步奖更新用户" + accountInfo.getUserId() + "月收益" + accountInfo.getEarningsMonth());
            }
        }

        //新增交易流水记录
        if (!CollectionUtils.isEmpty(recordList)) {
            for (TradeRecord tradeRecord : recordList) {
                int count = tradeRecordMapper.add(tradeRecord);
                if (count == 0) {
                    return false;
                }
            }
        }

        //新增最大进步奖信息
        if (!CollectionUtils.isEmpty(addPrizeList)) {
            for (ProgressPrize progressPrize : addPrizeList) {
                int count = progressPrizeMapper.add(progressPrize);
                if (count == 0) {
                    return false;
                }
                log.info("用户" + progressPrize.getUserId() + "新增最大进步奖奖金:" + progressPrize.getAwardMoney());
            }
        }

        //编辑最大进步奖信息
        if (!CollectionUtils.isEmpty(updatePrizeList)) {
            for (ProgressPrize progressPrize : updatePrizeList) {
                int count = progressPrizeMapper.edit(progressPrize);
                if (count == 0) {
                    return false;
                }
                log.info("用户" + progressPrize.getUserId() + "更新最大进步奖奖金为:" + progressPrize.getAwardMoney());
            }
        }
        return true;
    }

    /**
     * 更新账户信息和保存交易流水记录、保存上月剩余月度肥料奖金
     *
     * @param accountInfoList 账户列表
     * @param recordList      交易流水信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAccountAddRecordAndManure(List<AccountInfo> accountInfoList,
                                                   List<TradeRecord> recordList,
                                                   MonthManure manure, MonthManure monthManure) {

        //更新月收益
        if (!CollectionUtils.isEmpty(accountInfoList)) {
            for (AccountInfo accountInfo : accountInfoList) {
                int count = accountMapper.edit(accountInfo);
                if (count == 0) {
                    return false;
                }
                log.info("月定时任务月度肥料更新用户" + accountInfo.getUserId() + "月收益:" + accountInfo.getEarningsMonth());
            }
        }

        //新增交易流水记录
        if (!CollectionUtils.isEmpty(recordList)) {
            for (TradeRecord tradeRecord : recordList) {
                int count = tradeRecordMapper.add(tradeRecord);
                if (count == 0) {
                    return false;
                }
            }
        }

        //判断是否存在月度肥料剩余奖金信息
        if (null == monthManure) {
            //新增上月剩余月度肥料奖金
            int count = monthManureMapper.add(manure);
            return count != 0;
        } else {
            //编辑
            monthManure.setManureAward(manure.getManureAward());
            monthManure.setYearMonth(manure.getYearMonth());
            int count = monthManureMapper.edit(monthManure);
            return count != 0;
        }
    }
}