/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.distribution.comment.listener;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.ShopWalletChangeReason;
import com.yami.shop.bean.event.PaySuccessOrderEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.ShopWallet;
import com.yami.shop.bean.order.PaySuccessOrderOrder;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponse;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.Json;
import com.yami.shop.distribution.comment.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.comment.model.*;
import com.yami.shop.distribution.comment.po.DistributionProdPO;
import com.yami.shop.distribution.comment.service.*;
import com.yami.shop.distribution.comment.vo.DistributionAwardDataVO;
import com.yami.shop.distribution.comment.vo.DistributionBindSetRobVO;
import com.yami.shop.service.OrderItemService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.ShopWalletLogService;
import com.yami.shop.service.ShopWalletService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 支付成功事件
 */
@Slf4j
@Component("distributionPaySuccessOrderListener")
@AllArgsConstructor
public class PaySuccessOrderListener {

    private final DistributionUserIncomeService distributionUserIncomeService;

    private final DistributionBasicSetService distributionBasicSetService;

    private final DistributionBindSetService distributionBindSetService;

    private final DistributionBindUserService distributionBindUserService;

    private final DistributionUserService distributionUserService;

    private final DistributionProdService distributionProdService;

    private final DistributionUserWalletService distributionUserWalletService;

    private final DistributionUserWalletBillService distributionUserWalletBillService;

    private final OrderItemService orderItemService;

    private final ShopWalletService shopWalletService;

    private final MapperFacade mapperFacade;

    private final OrderService orderService;

    private final ShopWalletLogService shopWalletLogService;

    private final DistributionUserBindMapper distributionUserBindMapper;




    @EventListener(PaySuccessOrderEvent.class)
    @org.springframework.core.annotation.Order(PaySuccessOrderOrder.DISTRIBUTION)
    public void distributionPaySuccessOrderEvent(PaySuccessOrderEvent event) {
        if(Objects.equals(event.getOrders().get(0).getShopId(),Constant.PLATFORM_SHOP_ID)){
            return;
        }
        // 店铺分销基础设置
        DistributionBasicSet basicSet = distributionBasicSetService.getByShopId();
        // 没有开启分销
        if (basicSet == null || basicSet.getDistributionSwitch() == 0) {
            log.debug("平台没有开启分销，跳过分销的流程");
            return;
        }

        // 设置为分销的订单项
        List<OrderItem> distributionOrderItems = new ArrayList<>();

        //根据店铺id获取分销绑定设置
        DistributionBindSet distributionBindSet = distributionBindSetService.getByShopId();
        distributionBindSet.setRob(Json.parseObject(distributionBindSet.getRobJson(), DistributionBindSetRobVO.class));


        List<Order> orders = event.getOrders();

        // 所有的订单项
        for (Order order : orders) {
            // 所有的订单项
            List<OrderItem> orderItems = order.getOrderItems();

            boolean isFirstGetBindUser = true;

            DistributionUser oldDistributionUser = null;
            for (OrderItem orderItem : orderItems) {
                // 如果该订单项有分销信息，则将该订单项放入distributionOrderItems中
                if (StrUtil.isNotBlank(orderItem.getDistributionCardNo())) {
                    distributionOrderItems.add(orderItem);
                    doDistribution(oldDistributionUser,orderItem, distributionBindSet);
                    continue;
                }
                // 初始化用户的旧绑定分销员
                if (isFirstGetBindUser) {

                    isFirstGetBindUser = false;

                    // 查询该用户以前绑定的分享人
                    DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>()
                            .eq(DistributionUserBind::getShopId, Constant.PLATFORM_SHOP_ID)
                            .eq(DistributionUserBind::getState, 1)
                            .eq(DistributionUserBind::getUserId, order.getUserId())
                    );

                    // 并且该用户以前也没有绑定分享人
                    if (distributionUserBind != null) {
                        // 查询以前的绑定的用户信息
                        oldDistributionUser = distributionUserService.getById(distributionUserBind.getDistributionUserId());
                    }
                }

                if (oldDistributionUser == null) {
                    continue;
                }
                if (!Objects.equals(oldDistributionUser.getState(), 1)) {
                    continue;
                }
                // 将订单项设为分销项
                orderItem.setDistributionCardNo(oldDistributionUser.getCardNo());
                distributionOrderItems.add(orderItem);
                doDistribution(oldDistributionUser,orderItem, distributionBindSet);

            }

            //TODO FBJ注释（线上报错）
            // 分销订单需要在商家的未结算金额扣除用户分销金额
//            ShopWallet shopWallet = shopWalletService.getShopWalletByShopId(order.getShopId());
//            ShopWallet newShopWallet = mapperFacade.map(shopWallet, ShopWallet.class);
//            newShopWallet.setUpdateTime(new Date());
//
//            // 订单分销金额
//            double totalDistributionAmount = orderService.sumTotalDistributionAmountByOrderItem(distributionOrderItems);
//            // 商家待结算金额 = 商家待结算金额 - 订单分销佣金
//            newShopWallet.setUnsettledAmount(Arith.sub(shopWallet.getUnsettledAmount(), totalDistributionAmount));
//            // 插入扣除分销费用记录
//            shopWalletLogService.saveShopWalletLog(shopWallet, newShopWallet, ShopWalletChangeReason.DISTRIBUTION_AMOUNT, order.getOrderNumber());
//            // 使用乐观锁进行更新
//            if (!shopWalletService.updateById(newShopWallet)) {
//                throw new GlobalException("更新店铺钱包信息失败");
//            }
        }
        // 更新分销订单项
        if (CollectionUtils.isNotEmpty(distributionOrderItems)) {
            orderItemService.updateBatchById(distributionOrderItems);
        }
    }

    /**
     * 进行分销操作
     * @param oldShareUser 用户已绑定的分销员
     * @param orderItem 订单项
     */
    private void doDistribution(DistributionUser oldShareUser, OrderItem orderItem,DistributionBindSet distributionBindSet){
        DistributionUser shareUser;
        DistributionUser bindUser;
        if (oldShareUser != null && Objects.equals(orderItem.getDistributionCardNo(), oldShareUser.getCardNo())){
            shareUser = oldShareUser;
            bindUser = oldShareUser;
        } else {
            shareUser = distributionUserService.getByCardNo(orderItem.getDistributionCardNo());
            // 绑定绑定销售员信息
            ServerResponse<DistributionUser> serverResponse = distributionBindUserService.bindDistribution(shareUser, orderItem.getUserId(), 1);
            if (!serverResponse.isSuccess() && !Objects.equals(serverResponse.getCode(), 200)) {
                log.info("绑定销售员信息失败，跳过分销流程,订单号：{}, 订单项Id：{}",orderItem.getOrderNumber(),orderItem.getOrderItemId());
            }
            // 绑定的用户
            bindUser = serverResponse.getObj();
        }

        // 添加收入流水记录并将收入添加到待结算金额到钱包中
        createIncomeByOrderItem(distributionBindSet, shareUser, bindUser, orderItem);
    }

    /**
     * 创建订单项收入记录添加待结算金额到钱包中
     */
    private void createIncomeByOrderItem(DistributionBindSet distributionBindSet, DistributionUser shareUser, DistributionUser bindUser, OrderItem orderItem) {

        //判断是否会产生分销业绩
        if (Objects.isNull(bindUser) && Objects.isNull(shareUser)) {
            log.error("没有分享人，没有关系人，不产生业绩");
            return;
        }
        //获取该分销商品的设置数据
        DistributionProdPO distributionProdPO = distributionProdService.getDistributionProdPOByProdId(orderItem.getProdId());

        // 这件商品原本是分销商品被加入了购物车，后来又不是了
        if (distributionProdPO == null) {
            return;
        } else {
            distributionProdPO.setShopId(orderItem.getShopId());
            // 计算佣金，用实付金额计算
            distributionProdPO.setPrice(orderItem.getActualTotal());
        }

        //定义一个最终的业绩归属人变量
        DistributionUser finalDistributionUser;

        //判断是分享人优先还是关系链优先 0 允许绑定,关系优先,1,不绑定 分享人优先
        if (distributionBindSet.getAttribution() == 0) {
            //关系链优先
            log.info("关系链优先,关系人获得业绩");
            finalDistributionUser = bindUser;
        } else {
            //分享人优先
            log.info("分享人优先,分享人获得业绩");
            finalDistributionUser = shareUser;
        }

        if (finalDistributionUser == null) {
            log.info("没有找到业绩归属者");
            return;
        }


        //计算佣金金额
        DistributionAwardDataVO distributionAwardDataVO = distributionProdService.getAwardDataVO(distributionProdPO, finalDistributionUser.getDistributionUserId(),orderItem);

        log.error(distributionAwardDataVO.toString() + "计算好的佣金金额");

        double totalDistributionAmount = Arith.add(distributionAwardDataVO.getAwardNumber(), distributionAwardDataVO.getParentAwardNumber());

        if (totalDistributionAmount >= orderItem.getActualTotal()) {
            log.info("分销金额比实付金额要大，无法完成分销的操作");
            return;
        }


        DistributionUserIncome distributionUserIncome = new DistributionUserIncome();
        distributionUserIncome.setOrderNumber(orderItem.getOrderNumber());
        distributionUserIncome.setOrderItemId(orderItem.getOrderItemId());
        // 如果系统设置为交易完毕后结算，则记录为结算状态，否则为未结算状态
        distributionUserIncome.setState(1);
        distributionUserIncome.setCreateTime(new Date());
        distributionUserIncome.setUpdateTime(new Date());


        //创建插入业绩记录对象
        if (!Arith.isEquals(distributionAwardDataVO.getAwardNumber(), 0.0)) {
            // 查询该推广员钱包信息
            DistributionUserWallet distributionUserWallet = distributionUserWalletService.getOne(new LambdaQueryWrapper<DistributionUserWallet>().eq(DistributionUserWallet::getDistributionUserId, finalDistributionUser.getDistributionUserId()));

            distributionUserIncome.setDistributionUserId(finalDistributionUser.getDistributionUserId());
            distributionUserIncome.setWalletId(distributionUserWallet.getWalletId());
            distributionUserIncome.setIncomeAmount(distributionAwardDataVO.getAwardNumber());

            // 收入类型为一级奖励
            distributionUserIncome.setIncomeType(1);
            distributionUserIncomeService.save(distributionUserIncome);

            // 订单项添加分佣奖励
            orderItem.setDistributionAmount(distributionAwardDataVO.getAwardNumber());


            // 给钱包增加待结算金额
            distributionUserWallet.setUnsettledAmount(Arith.add(distributionUserWallet.getUnsettledAmount(), distributionAwardDataVO.getAwardNumber()));
            distributionUserWalletBillService.save(new DistributionUserWalletBill(distributionUserWallet, "客户支付获取待结算金额", distributionAwardDataVO.getAwardNumber(), 0.0, 0.0, 0.0, 0));

            //更新钱包
            boolean distributionUserWalletUpdateSuccess = distributionUserWalletService.updateById(distributionUserWallet);

            if (!distributionUserWalletUpdateSuccess) {
                throw new GlobalException("更新推广员钱包信息失败");
            }
        } else {
            log.info("默认奖励为0，不结算");
        }
        //不使用默认奖励
        if (Objects.equals(distributionProdPO.getDefaultReward(),0)){
            //是否开启了上级奖励(0 关闭 1开启)
            if (!Objects.equals(distributionProdPO.getParentAwardSet(), 1)) {
                log.info("没有开启上级奖励");
                return;
            }
        }
        //获取上级id
        if (Objects.isNull(finalDistributionUser.getParentId())) {
            log.info("无法获取推广员的上级id");
            return;
        }
        if (Arith.isEquals(distributionAwardDataVO.getParentAwardNumber(), 0.0)) {
            log.info("商品上级奖励为0，不结算");
            return;
        }
        log.info("进入上级奖励流程");

        //添加二级佣金给上级邀请人
        DistributionUserWallet parentDistributionUserWallet = distributionUserWalletService.getOne(new LambdaQueryWrapper<DistributionUserWallet>().eq(DistributionUserWallet::getDistributionUserId, finalDistributionUser.getParentId()));
        //如果上级不为空,则创建上级奖励业绩记录
        distributionUserIncome.setIncomeId(null);
        //类型为二级奖励
        distributionUserIncome.setIncomeType(2);
        distributionUserIncome.setDistributionUserId(finalDistributionUser.getParentId());
        distributionUserIncome.setIncomeAmount(distributionAwardDataVO.getParentAwardNumber());
        distributionUserIncome.setWalletId(parentDistributionUserWallet.getWalletId());
        distributionUserIncomeService.save(distributionUserIncome);

        //给邀请人钱包增加待结算金额
        parentDistributionUserWallet.setUnsettledAmount(Arith.add(parentDistributionUserWallet.getUnsettledAmount(), distributionAwardDataVO.getParentAwardNumber()));
        //增加钱包流水记录
        distributionUserWalletBillService.save(new DistributionUserWalletBill(parentDistributionUserWallet, "佣金结算", distributionAwardDataVO.getParentAwardNumber(), 0.0, 0.0, 0.0, 0));

        // 订单项添加上级奖励
        orderItem.setDistributionParentAmount(distributionAwardDataVO.getParentAwardNumber());

        //更新邀请人钱包
        boolean parentDistributionUserWalletUpdateSuccess = distributionUserWalletService.updateById(parentDistributionUserWallet);
        if (!parentDistributionUserWalletUpdateSuccess) {
            throw new GlobalException("更新推广员的邀请人钱包失败");
        }

    }

}
