package cn.pluss.platform.realFans.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.fans.FansService;
import cn.pluss.platform.mapper.*;
import cn.pluss.platform.merchantOrder.MerchantOrderService;
import cn.pluss.platform.merchantProfit.MerchantProfitService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.realFans.RealFansService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.userAccount.impl.UserAccountFlowServiceImpl;
import cn.pluss.platform.userAccount.impl.UserAccountServiceImpl;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.userIntegral.UserIntegralService;
import cn.pluss.platform.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@RequiredArgsConstructor
@Slf4j
@Service
public class RealFansServiceImpl extends ServiceImpl<RealFansMapper, RealFans> implements RealFansService {

    private final FansService fansService;
    private final MerchantBaseInfoMapper merchantBaseInfoMapper;
    private final UserAppService userAppService;
    private final NoticeService noticeService;
    private final MerchantOrderService merchantOrderService;
    private final MerchantProfitService merchantProfitService;
    private final UserIntegralService userIntegralService;

    @Resource
    private UserAppMapper userAppMapper;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Autowired
    UserAccountServiceImpl userAccountService;

    @Autowired
    UserAccountFlowServiceImpl userAccountFlowService;

    @Override
    public void removeProfit(MerchantOrder order) {
        if(ObjectUtil.isEmpty(order)){
            log.error("订单信息不存在");
            return;
        }
        cancelUserProfitV2(order);

    }




    private void cancelUserProfitV2(MerchantOrder order) {
        Vector<MerchantProfit> profitList = new Vector<MerchantProfit>();
        Vector<UserAccount> userAccounts=new Vector<>();
        Vector<UserAccountFlow> accountFlows=new Vector<>();

        UserPromotion userPromotion= userPromotionMapper.selectByUserId(order.getUserId().toString());
        if(ObjectUtil.isEmpty(userPromotion)){
            log.error("订单号:{},用户信息不存在",order.getOrderNumber());
            return;
        }

        if("SO".equals(userPromotion.getTypeCode())||"FO".equals(userPromotion.getTypeCode())||"MG".equals(userPromotion.getTypeCode())){
            log.error("此为系统用户不参与分润");
            return;
        }

        createUserV3Profit(order,userPromotion.getParentUserId(),profitList,userAccounts,accountFlows,order.getRate().divide(BigDecimal.valueOf(100)));

        if (!profitList.isEmpty()) {
            log.info("【去除分润计算完成】开始批量插入分润数据,生成分润的订单编号：{}，分润条数：{}", order.getOrderNumber(), profitList.size());
            try {
                merchantProfitService.batchInsert(profitList);

                userAccountService.updateBatchById(userAccounts);

                userAccountFlowService.saveBatch(accountFlows);
                log.info("【去除分润插入】插入分润成功！");
            } catch (Exception e) {
                e.printStackTrace();
                log.info("【去除分润插入】插入分润异常，异常信息:{}", e.getMessage());
            }
            //累计生成分润的总额
            BigDecimal sumProfitMoney = BigDecimal.ZERO;
            for (MerchantProfit p : profitList) {
                sumProfitMoney = sumProfitMoney.add(new BigDecimal(String.valueOf(p.getPrice())));
            }
            order.setProfitShareMoney(new BigDecimal(order.getProfitShareMoney()).add(sumProfitMoney.abs().negate().setScale(4, BigDecimal.ROUND_DOWN)).doubleValue());
            log.info("【去除分润结算结束】订单号：{}产生的分润总额：{}", order.getOrderNumber(), sumProfitMoney);
        }
    }

    @Autowired
    UserPromotionMapper userPromotionMapper;

    private void createUserV3Profit(MerchantOrder order,String userId,Vector<MerchantProfit> profits,Vector<UserAccount> userAccounts,Vector<UserAccountFlow> flows,BigDecimal nowRate){
        UserPromotion userPromotion= userPromotionMapper.selectByUserId(userId);
        if(ObjectUtil.isEmpty(userPromotion)){
            log.error("订单号:{},分润结束，获取分润数为:{}",order.getOrderNumber(),profits.size());
            return;
        }

        if(ObjectUtil.isEmpty(order.getRefundAmt())||N.egt(BigDecimal.ZERO,order.getRefundAmt())){
            log.error("退款金额为0 ：{},{}",order.getOrderNumber(),order.getRefundAmt());
            return;
        }


        if("MC".equals(userPromotion.getTypeCode())){
            if("1".equals(userPromotion.getIsExtend())){
                userPromotion= getUserPromotion(Long.valueOf(userPromotion.getParentUserId()));

                BigDecimal profitRate = BigDecimal.ZERO;

                if (nowRate.compareTo(new BigDecimal(userPromotion.getCurrentFee())) >= 0) {
                    profitRate = nowRate.subtract(new BigDecimal(userPromotion.getCurrentFee()));
                    nowRate = new BigDecimal(userPromotion.getCurrentFee());
                }else {
                    return;
                }

                UserApp nowUserApp = userAppMapper.selectByUserId(userPromotion.getUserId());
                if(ObjectUtil.isEmpty(nowUserApp)){
                    log.error("订单号:{},分润结束，获取分润数为:{}",order.getOrderNumber(),profits.size());
                    return;
                }

                log.info("userId:{},rate:{},amount:{}",nowUserApp.getUserId(),profitRate,order.getConsumeFee());



                BigDecimal profitAmt = profitRate.divide(BigDecimal.valueOf(100)).multiply(order.getRefundAmt()).setScale(4, BigDecimal.ROUND_DOWN);


                UserAccount userAccount= userAccountService.initUserAccount(nowUserApp.getUserId().intValue());
                userAccount.setBalance(userAccount.getBalance().subtract(profitAmt));
                userAccount.setUpdateTime(new Date());
                UserAccountFlow flow=new UserAccountFlow();

                flow.setUserId(nowUserApp.getUserId().intValue());
                flow.setBizCode("103");
                flow.setBizName("退款扣除收益");
                flow.setAmount(profitAmt);
                flow.setBalance(userAccount.getBalance());
                flow.setCreateTime(new Date());
                userAccounts.add(userAccount);
                flows.add(flow);


                MerchantProfit profit = new MerchantProfit(nowUserApp, nowUserApp, order, profitAmt.negate(), profitRate, "5", "1");
                profits.add(profit);
//                sendProfitMessage(nowUserApp, profitAmt, order.getOrderNumber());
                createUserV3Profit(order,userPromotion.getParentUserId(),profits,userAccounts,flows,nowRate);

            }else {
                createUserV3Profit(order,userPromotion.getParentUserId(),profits,userAccounts,flows,nowRate);
            }
        }else {
            BigDecimal profitRate = BigDecimal.ZERO;

            if (nowRate.compareTo(new BigDecimal(userPromotion.getCurrentFee())) >= 0) {
                profitRate = nowRate.subtract(new BigDecimal(userPromotion.getCurrentFee()));
                nowRate = new BigDecimal(userPromotion.getCurrentFee());
            }else {
                return;
            }



            UserApp nowUserApp = userAppMapper.selectByUserId(userId);
            if(ObjectUtil.isEmpty(nowUserApp)){
                log.error("订单号:{},去除分润结束，获取分润数为:{}",order.getOrderNumber(),profits.size());
                return;
            }
            log.info("userId:{},rate:{},amount:{}",nowUserApp.getUserId(),profitRate,order.getConsumeFee());
            BigDecimal profitAmt = profitRate.divide(BigDecimal.valueOf(100)).multiply(order.getRefundAmt()).setScale(4, BigDecimal.ROUND_DOWN);


            UserAccount userAccount= userAccountService.initUserAccount(nowUserApp.getUserId().intValue());
            userAccount.setBalance(userAccount.getBalance().subtract(profitAmt));
            userAccount.setUpdateTime(new Date());
            UserAccountFlow flow=new UserAccountFlow();

            flow.setUserId(nowUserApp.getUserId().intValue());
            flow.setBizCode("103");
            flow.setBizName("退款扣除收益");
            flow.setAmount(profitAmt);
            flow.setBalance(userAccount.getBalance());
            flow.setCreateTime(new Date());
            userAccounts.add(userAccount);
            flows.add(flow);


            MerchantProfit profit = new MerchantProfit(nowUserApp,nowUserApp , order, profitAmt.abs().negate(), profitRate, "5", "1");
            profits.add(profit);
//            sendProfitMessage(nowUserApp, profitAmt, order.getOrderNumber());
            createUserV3Profit(order,userPromotion.getParentUserId(),profits,userAccounts,flows,nowRate);

        }

    }


    private UserPromotion getUserPromotion(Long userId){

        UserPromotion userPromotion=  userPromotionMapper.selectByPrimaryKey(userId);
        if(ObjectUtil.isNotEmpty(userPromotion)&&"MC".equals(userPromotion.getTypeCode())){
            getUserPromotion(Long.valueOf(userPromotion.getParentUserId()));
        }
        return userPromotion;


    }


    @Override
    public void removeProfit(MerchantOrder order, BigDecimal refundAmt,BigDecimal useRefundAmt) {
        BigDecimal consumeFee = BigDecimal.valueOf(order.getConsumeFee());
        if(refundAmt.compareTo(consumeFee) == 0){
            removeProfit(order);
        }else{
            QueryWrapper<MerchantProfit> queryWrapper = new QueryWrapper<MerchantProfit>();
            queryWrapper.eq("orderNumber",order.getOrderNumber());
            merchantProfitService.remove(queryWrapper);
            BigDecimal fee = consumeFee.subtract(refundAmt).subtract(useRefundAmt);
            order.setConsumeFee(fee.doubleValue());
            merchantProfitService.createOrderProfitV2(order,"1");
        }
    }

    @Override
    public Page<RealFans> pageData(Page<RealFans> page, RealFans realFans) {
        return baseMapper.pageData(page,realFans);
    }

    /**
     * @description:创建粉丝分润
     * @date: 2021/8/19 17:24
     * @param order:
     */
    @Override
    public void createFansProfit(MerchantOrder order) {
        log.info("【粉丝分润计算】创建粉丝分润开始，待创建粉丝分润的订单号为:{},订单类型为：{}",order.getOrderNumber(),order.getOrderType());
        if(StringUtil.isNotEmpty(order.getMercUserId())){
            if("2".equals(order.getOrderType()) || "7".equals(order.getOrderType()) || "9".equals(order.getOrderType()) || "10".equals(order.getOrderType())){
                //插入粉丝和消费记录
                insertRealFansAndFans(order);
            }
            log.info("【粉丝分润计算】创建粉丝分润结束，订单号为:{}的订单分润创建成功！",order.getOrderNumber());
        }else{
            log.info("【粉丝分润计算】创建粉丝分润结束，订单号为:{}的订单mercUserId为空创建失败！",order.getOrderNumber());
        }
    }
    /**
     * @description:插入粉丝分润
     * @date: 2021/8/23 14:08
     * @param order:
     */
    private void insertRealFansAndFans(MerchantOrder order) {
        List<RealFans> realFansList = baseMapper.queryBySoleId(order.getMercUserId());
        if (realFansList.isEmpty()) {
            RealFans realFans = order.convertRealFans();
            baseMapper.insert(realFans);
            insertFans(order);
        }else{
            Fans f = fansService.getByLockOrderNumber(order.getOrderNumber());
            if(f == null){
                Fans lastFans = fansService.queryLastFansByUserId(order.getMercUserId());
                Fans fans = new Fans();
                fans.convert(order);
                if (lastFans!= null && StringUtil.isNotEmpty(lastFans.getConsumTime())
                        && DateUtils.differentDaysByHours(lastFans.getConsumTime(),DateUtils.currentDate()) < 24
                        && !order.getMerchantCode().equals(lastFans.getMerchantCode())) {
                    // 说明有上次的记录并且上次消费时间跟本次消费是在同一天 本次消费给上一次消费的商家分润
                    fans.setLastconsumTime(lastFans.getConsumTime());
                    if (StringUtil.isNotEmpty(lastFans.getMerchantCode())) {
                        fans.setLastMerchantCode(lastFans.getMerchantCode());
                    }
                    if (StringUtil.isNotEmpty(lastFans.getOrderNumber())) {
                        fans.setLastOrderNumber(lastFans.getOrderNumber());
                    }
                    String lastMerchantCode = fans.getLastMerchantCode();
                    MerchantBaseInfo merchantBaseInfo = merchantBaseInfoMapper.queryByMerchantCode(lastMerchantCode);
                    if (StringUtil.isNotEmpty(lastMerchantCode)) {
                        String userId = merchantBaseInfo.getUserId();// 当前商户的userId
                        UserApp userApp = new UserApp();
                        userApp.setUserId(Long.parseLong(userId));
                        if (StringUtil.isNotEmpty(userId)) {
                            userApp = userAppService.queryUserApp(userApp);// 当前商户的信息
                            if (Double.parseDouble(fans.getShareMoney()) >= 0.0001d ) {
                                List<String> alias = new ArrayList<String>();
                                alias.add(userApp.getUserId() + "");
                                try {
                                    String notificationContent = "本次分润金额：" + fans.getShareMoney() + "元";
                                    generalPushUtil.sendAllPlatByAlias(alias, "粉丝分润通知", notificationContent, "0");
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                Notice notice = new Notice(0, 6, userApp);
                                notice.setConrtent("您有一笔" + fans.getShareMoney() + "元的粉丝分润");
                                notice.setUniqueKey(order.getMercUserId() + order.getOrderNumber() + "fansProft");
                                noticeService.saveNotice(notice);
                            }
                        }
                    }
                }else{
                    fans.setShareMoney("0");
                }
                order.setFansShareMoney(Double.parseDouble(fans.getShareMoney()));
                fansService.saveFans(fans);
            }
        }
    }

    private void insertFans(MerchantOrder order) {
        Fans fans = new Fans();
        fans.setShareMoney("0");
        fans.convert(order);
        fansService.saveFans(fans);
    }
}
