package com.github.wxiaoqi.security.admin.biz;

import com.github.wxiaoqi.security.admin.bo.UserIncomeBo;
import com.github.wxiaoqi.security.admin.dto.OrderGoodsDTO;
import com.github.wxiaoqi.security.admin.dto.OrderWaterDTO;
import com.github.wxiaoqi.security.admin.entity.*;
import com.github.wxiaoqi.security.admin.entity.AppUserRelation;
import com.github.wxiaoqi.security.admin.vo.AppUserVo;
import com.github.wxiaoqi.security.admin.vo.SellingWalletVo;
import com.github.wxiaoqi.security.admin.vo.SellingWalletPagVo;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.wxiaoqi.security.admin.mapper.AppUserSellingWaterMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 拥金明细表
 *
 * @author zjw
 * @email 18178966185@163.com
 * @date 2019-07-11 14:14:54
 */
@Service
@Slf4j
public class AppUserSellingWaterBiz extends BaseBiz<AppUserSellingWaterMapper, AppUserSellingWater> {


    @Autowired
    AppUserRelationBiz relationBiz;

    @Autowired
    BaseGoodCommissionBiz commissionBiz;

    @Autowired
    AppUserPositionBiz positionBiz;

    @Autowired
    AppUserDetailBiz detailBiz;

    @Autowired
    private AppUserLoginBiz appUserLoginBiz;

    @Autowired
    private AppUserDetailBiz appUserDetailBiz;

    @Autowired
    MyWaterBiz myWaterBiz;


    //计算用户拥金

    public void orderWater(OrderWaterDTO orderWaterDTO) {
        if (orderWaterDTO == null) {
            log.info("计算用户拥金----orderWater----次数不能为空----");
            return;
        }
        //订单状态
        Integer status = orderWaterDTO.getStatus();
        if (status == null || status == 0) {
            log.info("购买计算用户拥金----payOrderWater----参数不能为空----status===" + status);
            return;
        }
        if (status == 1) {
            payOrderWater(orderWaterDTO);
        } else if (status == 2) {
            finishOrderWater(orderWaterDTO);
        } else {
            refundOrderWater(orderWaterDTO);
        }
    }

    //购买计算用户拥金
    public void payOrderWater(OrderWaterDTO orderWaterDTO) {
        //订单id
        Integer orderId = orderWaterDTO.getOrderId();
        //订单号
        String orderNo = orderWaterDTO.getOrderNo();
        //用户id
        Integer userId = orderWaterDTO.getUserId();
        List<OrderGoodsDTO> goodsDTOList = orderWaterDTO.getGoodsDTOList();
        log.info("购买计算用户拥金----payOrderWater----userId====" + userId + "---orderId===" + orderId + "---orderNo===" + orderNo);
        if (orderId == null || orderId == 0 || userId == null || userId == 0 | CollectionUtils.isEmpty(goodsDTOList)) {
            log.info("购买计算用户拥金----payOrderWater----参数不能为空----orderId===" + orderId);
            return;
        }
        AppUserRelation relation = relationBiz.getRelationByUserId(userId);
        if (relation == null || relation.getParentId() == null || relation.getParentId() == 0) {
            log.info("购买计算用户拥金----payOrderWater--------userId===" + userId + "---无上线");
            return;
        }

        Integer parentId = relation.getParentId();
        log.info("购买计算用户拥金----payOrderWater--------userId===" + userId + "---parentId===" + parentId);
        Integer positionId = 6;
        Integer level = 0;
        AppUserPosition position=positionBiz.getExtract(parentId);
        if (position!=null){
            positionId=position.getId();
        }
        AppUserPosition position1=positionBiz.getExtract(userId);
        if (position!=null){
            level=position1.getLevel();
        }
        log.info("购买计算用户拥金----payOrderWater--------userId===" + userId + "---positionId===" + positionId+"---level==="+level);
        if(level!=0){
            log.info("购买计算用户拥金----payOrderWater--------userId===" + userId +"----无法享受拥金");
            return;
        }
        BigDecimal amount = new BigDecimal("0.00");
        //商品类型
        Integer orderType=0;
        for (OrderGoodsDTO goodsDto : goodsDTOList) {
            //商品id
            Integer goodId = goodsDto.getGoodId();
            //商品价格
            BigDecimal price = goodsDto.getPrice();

            orderType = goodsDto.getType();
            //商品比例
            Integer extract = commissionBiz.getExtract(orderType, goodId);

            if (extract == null || extract == 0) {
                extract = position.getExtract();
            }
            log.info("购买计算用户拥金----payOrderWater--------userId===" + userId + "---extract===" + extract);
            if (extract != null && extract > 0) {
                AppUserSellingWater sellingWater = new AppUserSellingWater();
                sellingWater.setOrderId(orderId);
                sellingWater.setGoodId(goodId);
                sellingWater = selectOne(sellingWater);
                if (sellingWater != null) {
                    continue;
                }
                BigDecimal commission = price.multiply(new BigDecimal(extract + "")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
                log.info("购买计算用户拥金----payOrderWater--------userId===" + userId + "---commission===" + commission);
                sellingWater = new AppUserSellingWater();
                sellingWater.setUserId(parentId);
                sellingWater.setSourceId(userId);
                sellingWater.setPositionId(positionId);
                sellingWater.setOrderId(orderId);
                sellingWater.setOrderNo(orderNo);
                sellingWater.setOrderType(orderType);
                sellingWater.setGoodId(goodId);
                sellingWater.setTitle(goodsDto.getTitle());
                sellingWater.setImg(goodsDto.getImg());
                sellingWater.setPrice(price);
                sellingWater.setExtract(extract);
                sellingWater.setGoodNumber(goodsDto.getGoodNumber());
                sellingWater.setCommission(commission);
                insertSelective(sellingWater);
                log.info("购买计算用户拥成功----payOrderWater--------userId===" + userId);
                amount = amount.add(commission);
            }
        }
        log.info("购买计算用户未入账----payOrderWater--------userId===" + parentId+"----amount===="+amount+"--orderType==="+orderType);
        if(orderType==3){
            finishOrderWater(orderWaterDTO);
        }else  if(orderType==1||orderType==2){
            myWaterBiz.updMyWalletUnbooked(parentId,amount,1);
        }
    }

    //订单完成计算用户拥金
    public void finishOrderWater(OrderWaterDTO orderWaterDTO) {
        //订单id
        Integer orderId = orderWaterDTO.getOrderId();
        log.info("订单完成计算用户拥金----finishOrderWater----orderId====" + orderId);
        if (orderId == null || orderId == 0) {
            return;
        }
        List<AppUserSellingWater> list = getWaterList(orderId);
        BigDecimal amount = new BigDecimal("0.00");
        Integer userId = 0;
        Integer orderType=0;
        if (list.size() > 0) {
            for (AppUserSellingWater sellingWater : list) {
                Integer id = sellingWater.getId();
                orderType=sellingWater.getOrderType();
                userId = sellingWater.getUserId();
                sellingWater.setWaiting(1);
                updateById(sellingWater);
                BigDecimal commission = sellingWater.getCommission();
                log.info("订单完成计算用户拥金----finishOrderWater----id====" + id + "---commission==" + commission+"----orderType==="+orderType);
                amount = amount.add(commission);
            }

            log.info("订单完成计算用户拥金----finishOrderWater----orderId====" + orderId + "---amount==" + amount);
            int r = amount.compareTo(BigDecimal.ZERO);
            //更新钱包
            if (r == 1 && userId > 0) {
                MyWalletDetail detail=new MyWalletDetail();
                detail.setUserId(userId);
                detail.setAmount(amount);
                detail.setCono(orderId);
                detail.setSource(1);
                myWaterBiz.updMyWater(detail);
                if(orderType==1||orderType==2){
                    myWaterBiz.updMyWalletUnbooked(userId,amount,2);
                }

            }
        }


    }

    //订单退款计算用户拥金
    public void refundOrderWater(OrderWaterDTO orderWaterDTO) {
        //订单id
        Integer orderId = orderWaterDTO.getOrderId();
        log.info("订单完成计算用户拥金----refundOrderWater----orderId====" + orderId);
        if (orderId == null || orderId == 0) {
            return;
        }
        List<AppUserSellingWater> list = getWaterList(orderId);
        BigDecimal amount = new BigDecimal("0.00");
        BigDecimal unbooked = new BigDecimal("0.00");
        Integer userId = 0;
        Integer orderType=0;
        if (list.size() > 0) {
            for (AppUserSellingWater sellingWater : list) {
                Integer id = sellingWater.getId();
                orderType=sellingWater.getOrderType();
                userId = sellingWater.getUserId();
                sellingWater.setWaiting(1);
                updateById(sellingWater);
                sellingWater.setId(null);
                sellingWater.setStatus(1);
                insertSelective(sellingWater);
                BigDecimal commission = sellingWater.getCommission();
                log.info("订单完成计算用户拥金----refundOrderWater----id====" + id + "---commission==" + commission+"---orderType===="+orderType);
                unbooked=unbooked.add(commission);
            }
            log.info("订单完成计算用户拥金----refundOrderWater----orderId====" + orderId + "---amount==" + amount+"---unbooked==="+unbooked);
            int r = amount.compareTo(BigDecimal.ZERO);
            //更新钱包
            if (r == 1 && userId > 0) {
                MyWalletDetail detail=new MyWalletDetail();
                detail.setUserId(userId);
                detail.setAmount(amount);
                detail.setCono(orderId);
                detail.setSource(1);
                myWaterBiz.updMyWater(detail);
            }
            if(orderType==1||orderType==2){
                myWaterBiz.updMyWalletUnbooked(userId,unbooked,2);
            }
        }

    }


    //获取拥金列表
    public List<AppUserSellingWater> getWaterList(Integer orderId) {
        Example example = new Example(AppUserSellingWater.class);
        example.createCriteria().andEqualTo("orderId", orderId).andEqualTo("waiting", 0).andEqualTo("status", 0);
        return mapper.selectByExample(example);

    }


    public Map<Integer, BigDecimal> findMemberIdAndIncomeMapByMemberIds(List<Integer> memberIds) {
        Map<Integer, BigDecimal> memberIdAndIncomeMap = new HashMap<>();
        List<UserIncomeBo> userIncomeBos = mapper.accquireIncomeByMemberIds(memberIds);
        if (CollectionUtils.isNotEmpty(userIncomeBos)) {
            memberIdAndIncomeMap = userIncomeBos.stream().collect(Collectors.toMap(UserIncomeBo::getUserId, userIncomeBo -> userIncomeBo.getIncome() == null ? new BigDecimal(0) : userIncomeBo.getIncome()));
        }
        return memberIdAndIncomeMap;
    }

    public SellingWalletPagVo findSellingWaterPageByWaiting(Integer waiting, Integer userId, Integer pageNo, Integer pageSize) {

        SellingWalletPagVo sellingWalletPagVo = new SellingWalletPagVo();
        Example example = new Example(AppUserSellingWater.class);
        example.setOrderByClause("crt_time DESC");
        Example.Criteria criteria = example.createCriteria();
        if (waiting != null) {
            criteria.andEqualTo("waiting", waiting);
        }
        criteria.andEqualTo("userId", userId);
        PageDataVO<AppUserSellingWater> appUserSellingWaterPageDataVO = PageDataVO.pageInfo(pageNo, pageSize, () -> mapper.selectByExample(example));
        List<AppUserSellingWater> appUserSellingWaters = appUserSellingWaterPageDataVO.getData();
        if (CollectionUtils.isEmpty(appUserSellingWaters)) {
            sellingWalletPagVo.setPageNum(pageNo);
            sellingWalletPagVo.setPageSize(pageSize);
            sellingWalletPagVo.setTotalCount(0);
            sellingWalletPagVo.setTotalPage(0);
            sellingWalletPagVo.setTotalIncome(new BigDecimal(0));
            sellingWalletPagVo.setSellingWaters(Collections.EMPTY_LIST);
            return sellingWalletPagVo;
        }

        List<Integer> memberIds = appUserSellingWaters.stream().map(AppUserSellingWater::getSourceId).collect(Collectors.toList());

        Map<Integer, AppUserLogin> userIdAndAppUserLoginMap = appUserLoginBiz.findUserIdAndUserLoginMapByMemberIds(memberIds);
        Map<Integer, AppUserDetail> userIdAndAppUserDetailMap = appUserDetailBiz.findUserIdAndUserDetailMapByMemberIds(memberIds);

        List<SellingWalletVo> sellingWaterVos = new ArrayList<>();
        SellingWalletVo sellingWaterVo;
        BigDecimal totalIncome = new BigDecimal(0);
        for (AppUserSellingWater appUserSellingWater : appUserSellingWaters) {
            sellingWaterVo = new SellingWalletVo();
            BeanUtils.copyProperties(appUserSellingWater, sellingWaterVo);

            sellingWaterVo.setUsername(userIdAndAppUserLoginMap.get(appUserSellingWater.getSourceId()).getUsername());
            if (userIdAndAppUserDetailMap != null) {
                AppUserDetail appUserDetail = userIdAndAppUserDetailMap.get(appUserSellingWater.getSourceId());
                sellingWaterVo.setNickName(appUserDetail == null ? "" : appUserDetail.getNickname());
                sellingWaterVo.setHeadUrl(appUserDetail == null ? "" : appUserDetail.getHeadimgurl());
            }
            totalIncome = totalIncome.add(sellingWaterVo.getCommission());
            sellingWaterVos.add(sellingWaterVo);
        }
        if (waiting == null) {
            Supplier<Stream<AppUserSellingWater>> commissionStream = () -> appUserSellingWaters.stream();
            BigDecimal total = commissionStream.get().filter(x -> x.getStatus() == 0).map(AppUserSellingWater::getCommission).reduce(new BigDecimal(0), (x, y) -> x.add(y));
            BigDecimal refund = commissionStream.get().filter(x -> x.getStatus() == 1).map(AppUserSellingWater::getCommission).reduce(new BigDecimal(0), (x, y) -> x.add(y));
            totalIncome = total.subtract(refund);
        }

        sellingWaterVos.sort(Comparator.comparing(SellingWalletVo::getCrtTime).reversed());
        sellingWalletPagVo.setPageNum(pageNo);
        sellingWalletPagVo.setPageSize(pageSize);
        sellingWalletPagVo.setTotalCount(appUserSellingWaterPageDataVO.getTotalCount().intValue());
        sellingWalletPagVo.setTotalPage(appUserSellingWaterPageDataVO.getTotalPage());
        sellingWalletPagVo.setTotalIncome(totalIncome);
        sellingWalletPagVo.setSellingWaters(sellingWaterVos);

        return sellingWalletPagVo;
    }

    public BigDecimal selectTotalIncomeByUserId(Integer userId) {
        return mapper.selectTotalIncomeByUserId(userId);
    }

    public void deleteByMemberIds(Collection<Integer> userIds) {
         Example example = new Example(AppUserSellingWater.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("sourceId",userIds);
        mapper.deleteByExample(example);
    }
}