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

package com.yami.shop.distribution.comment.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.OfflineHandleEventStatus;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.Json;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.distribution.comment.Enums.DistributionProdStateEnum;
import com.yami.shop.distribution.comment.dao.DistributionProdMapper;
import com.yami.shop.distribution.comment.dao.DistributionUserMapper;
import com.yami.shop.distribution.comment.dto.DistributionProdDto;
import com.yami.shop.distribution.comment.model.*;
import com.yami.shop.distribution.comment.po.DistributionProdPO;
import com.yami.shop.distribution.comment.service.DistributionLevelService;
import com.yami.shop.distribution.comment.service.DistributionLevelSetService;
import com.yami.shop.distribution.comment.service.DistributionProdService;
import com.yami.shop.distribution.comment.vo.DistributionAwardDataVO;
import com.yami.shop.service.OfflineHandleEventService;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author lgh on 2019/04/01.
 */
@Service
@AllArgsConstructor
public class DistributionProdServiceImpl extends ServiceImpl<DistributionProdMapper, DistributionProd> implements DistributionProdService {

    private final DistributionProdMapper distributionProdMapper;

    private final DistributionLevelService distributionLevelService;

    private final DistributionLevelSetService distributionLevelSetService;

    private final DistributionUserMapper distributionUserMapper;

    private final OfflineHandleEventService offlineHandleEventService;

    @Override
    public IPage<DistributionProd> distributionProdsPage(Page page, DistributionProd distributionProd, String prodName) {
        return distributionProdMapper.distributionProdsPage(page, distributionProd, prodName);
    }

    @Override
    public List<DistributionProdDto> distributionProdDtoPage(Page<DistributionProdDto> page, String prodName, Integer sort, Integer orderBy, DistributionUser distributionUser) {
        Long shopId = distributionUser.getShopId();

        DistributionLevelSet distributionLevelSet = distributionLevelSetService.getByShopId();
        DistributionLevel levelInfo = distributionLevelService.getLevelInfo(distributionUser.getLevel(), distributionLevelSet.getDistributionLevels());

        // 商品默认
        DistributionAwardDataVO defaultAwardData = getDefaultAwardData(distributionLevelSet, levelInfo);


        IPage<DistributionProdPO> distributionProdPOPage = distributionProdMapper.distributionProdPOPage(page, prodName, sort, orderBy);

        // 获取商品的分佣金额，或分佣奖励
        List<DistributionProdDto> distributionProdDtoList = new ArrayList<>();
        for (DistributionProdPO distributionProdPO : distributionProdPOPage.getRecords()) {
            //po转dto
            DistributionProdDto distributionProdDto = new DistributionProdDto();
            distributionProdDto.setProdId(distributionProdPO.getProdId());
            distributionProdDto.setProdName(distributionProdPO.getProdName());
            distributionProdDto.setPic(distributionProdPO.getPic());
            distributionProdDto.setPrice(distributionProdPO.getPrice());
            //获取计算好的奖励
            DistributionAwardDataVO distributionAwardDataVO = getAwardDataVO(distributionProdPO, defaultAwardData, levelInfo.getLevel());

            distributionProdDto.setAwardProportion(distributionAwardDataVO.getAwardProportion());
            distributionProdDto.setAwardNumber(distributionAwardDataVO.getAwardNumber());
            distributionProdDto.setParentAwardNumber(distributionAwardDataVO.getParentAwardNumber());
            //添加到集合中
            distributionProdDtoList.add(distributionProdDto);
        }


        return distributionProdDtoList;
    }

    /**
     * 根据分销商品设置、分享人id，计算奖励数据
     *
     * @param distributionProdPO
     * @param distributionUserId
     * @param orderItem
     * @return
     */
    @Override
    public DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPO, Long distributionUserId, OrderItem orderItem) {
        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();
        distributionAwardDataVO.setAwardNumber(0.0);
        distributionAwardDataVO.setParentAwardNumber(0.0);

        //查看推广员信息
        DistributionUser distributionUser = distributionUserMapper.selectById(distributionUserId);

        //根据店铺id获取等级设置
        DistributionLevelSet distributionLevelSet = distributionLevelSetService.getByShopId();
        DistributionLevel levelInfo = distributionLevelService.getLevelInfo(distributionUser.getLevel(), distributionLevelSet.getDistributionLevels());
        //获取默认设置收益
        distributionAwardDataVO = getDefaultAwardData(distributionLevelSet, levelInfo);

        //如果为分销商品自定义奖励
        distributionAwardDataVO = getAwardDataVO(distributionProdPO, distributionAwardDataVO, distributionUser.getLevel());


        if (Objects.nonNull(distributionAwardDataVO.getAwardProportion())) {
            //如果计算为按比例计算，则转化为具体金额
            if(Objects.equals(distributionAwardDataVO.getAwardProportion(), 0)){
                distributionAwardDataVO.setAwardProportion(0);
                //根据商品价格,计算得到的佣金
    //            distributionAwardDataVO.setAwardNumber(Arith.mul(distributionProdPO.getPrice(), Arith.div(distributionAwardDataVO.getAwardNumber(), 100)));
                distributionAwardDataVO.setAwardNumber(Arith.div(Arith.mul(distributionProdPO.getPrice(),distributionAwardDataVO.getAwardNumber()),100));
                //查看是否开启邀请人奖励
//                if (distributionProdPO.getParentAwardSet() == 1) {
    //                distributionAwardDataVO.setParentAwardNumber(Arith.mul(distributionProdPO.getPrice(), Arith.div(distributionAwardDataVO.getParentAwardNumber(), 100)));
                    distributionAwardDataVO.setParentAwardNumber(Arith.div(Arith.mul(distributionProdPO.getPrice(),distributionAwardDataVO.getParentAwardNumber()),100));
//                }
            } else{
                distributionAwardDataVO.setAwardNumber(Arith.round(Arith.mul(distributionAwardDataVO.getAwardNumber(),orderItem.getProdCount()),2));
                distributionAwardDataVO.setParentAwardNumber(Arith.round(Arith.mul(distributionAwardDataVO.getParentAwardNumber(),orderItem.getProdCount()),2));
            }
        }
        return distributionAwardDataVO;

    }


    /**
     * 获取商品默认奖励设置
     *
     * @param distributionLevelSet
     * @param levelInfo
     * @return
     */
    private DistributionAwardDataVO getDefaultAwardData(DistributionLevelSet distributionLevelSet, DistributionLevel levelInfo) {

        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();

        distributionAwardDataVO.setAwardNumber(levelInfo.getAwardNumber());
        distributionAwardDataVO.setParentAwardNumber(levelInfo.getParentAwardNumber());
        // 奖励比例或数额
        distributionAwardDataVO.setAwardProportion(distributionLevelSet.getAwardProportion());
        //是否开启默认奖励
        if (distributionLevelSet.getAwardSwitch() == 0) {
            //没开启默认奖励,将奖励数额归零
            distributionAwardDataVO.setAwardNumber(0.0);
        }
        //是否开启了默认上级奖励
        if (distributionLevelSet.getParentAwardSwitch() == 0) {
            //如果没开启,就将奖励数额归零
            distributionAwardDataVO.setParentAwardNumber(0.0);
        }
        return distributionAwardDataVO;
    }

    /**
     * 根据分销商品对象和分销员等级计算出 奖励数据
     *
     * @param distributionProdPO
     * @return
     */
    private DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPO, DistributionAwardDataVO defaultDistributionAwardData, int level) {
        //判断商品奖励 是否为默认奖励
        if (distributionProdPO.getDefaultReward() == 1) {
            return defaultDistributionAwardData;
        }

        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();

        //奖励比例或数额
        distributionAwardDataVO.setAwardProportion(distributionProdPO.getAwardProportion());

        // 不按照等级进行设置
        if (distributionProdPO.getAwardNumberSet() == 0) {
            distributionAwardDataVO.setAwardNumber(Double.valueOf(distributionProdPO.getAwardNumbers()));
            distributionAwardDataVO.setParentAwardNumber(Double.valueOf(distributionProdPO.getParentAwardNumbers()));
            return distributionAwardDataVO;
        }
        List<Double> awardNumbers = Json.parseArray(distributionProdPO.getAwardNumbers(), Double[].class);
        distributionAwardDataVO.setAwardNumber(awardNumbers.get(level - 1));

        List<Double> parentAwardNumbers = Json.parseArray(distributionProdPO.getParentAwardNumbers(), Double[].class);
        distributionAwardDataVO.setParentAwardNumber(parentAwardNumbers.get(level - 1));

        return distributionAwardDataVO;
    }

    @Override
    @Cacheable(cacheNames = "DistributionProdPO", key = "#prodId")
    public DistributionProdPO getDistributionProdPOByProdId(Long prodId) {
        return distributionProdMapper.getDistributionProdPOByProdId(prodId);
    }

    @Override
    @CacheEvict(cacheNames = "DistributionProdPO", key = "#prodId")
    public void removeDistributionProdPOCacheByProdId(Long prodId) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offline(DistributionProd distributionProd, String offlineReason, Long sysUserId) {
        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setShopId(distributionProd.getShopId());
        offlineHandleEvent.setHandleId(distributionProd.getDistributionProdId());
        offlineHandleEvent.setHandleType(OfflineHandleEventType.DISTRIBUTION_PROD.getValue());
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);

        // 更新活动状态为下线
        if (distributionProdMapper.updateState(distributionProd.getDistributionProdId(), DistributionProdStateEnum.OFFLINE.getValue()) < 0) {
            throw new GlobalException("更新活动商品失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditDistributionProd(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            // 更新活动状态
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.PUT_OFF.getValue());
        }
        // 审核不通过
        else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.OFFLINE.getValue());
        }
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApply(Long eventId, Long distributionProdId, String reapplyReason) {
        // 更新活动为待审核状态
        distributionProdMapper.updateState(distributionProdId, DistributionProdStateEnum.WAIT_AUDIT.getValue());

        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }

    @Override
    public IPage<DistributionProdLog> getDistributionProdLogPage(PageParam<DistributionProdLog> page, DistributionProdLog distributionProdLog) {
        return distributionProdMapper.getDistributionProdLogPage(page,distributionProdLog);
    }

}
