package co.yixiang.yshop.module.distributor.service.distributorlevel;

import cn.hutool.core.collection.CollUtil;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.distributor.controller.admin.distributor.vo.DistributorExportReqVO;
import co.yixiang.yshop.module.distributor.controller.admin.distributor.vo.DistributorUpdateReqVO;
import co.yixiang.yshop.module.distributor.controller.admin.distributorlevel.vo.*;
import co.yixiang.yshop.module.distributor.controller.admin.distributoruser.vo.DistributorUserExportReqVO;
import co.yixiang.yshop.module.distributor.convert.distributorlevel.DistributorLevelConvert;
import co.yixiang.yshop.module.distributor.dal.dataobject.distributor.DistributorDO;
import co.yixiang.yshop.module.distributor.dal.dataobject.distributorlevel.DistributorLevelDO;
import co.yixiang.yshop.module.distributor.dal.dataobject.distributororder.DistributorOrderDO;
import co.yixiang.yshop.module.distributor.dal.dataobject.distributoruser.DistributorUserDO;
import co.yixiang.yshop.module.distributor.enums.DistributorConstants;
import co.yixiang.yshop.module.distributor.enums.DistributorLevelUpTypeEnum;
import co.yixiang.yshop.module.distributor.enums.DistributorStatusEnum;
import co.yixiang.yshop.module.distributor.enums.ErrorCodeConstants;
import co.yixiang.yshop.module.distributor.service.distributor.DistributorService;
import co.yixiang.yshop.module.distributor.service.distributoruser.DistributorUserService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;

@Service
@Validated
public class DistributorLevelFacadeImpl implements DistributorLevelFacade {

    @Resource
    private DistributorLevelService distributorLevelService;

    @Resource
    private DistributorService distributorService;

    @Resource
    private DistributorUserService distributorUserService;

    @Override
    public Long createLevel(DistributorLevelCreateReqVO createReqVO) {
        Integer level = createReqVO.getLevel();
        // 校验是否重复
        List<DistributorLevelDO> levelList = distributorLevelService.getLevelList(new DistributorLevelExportReqVO().setLevel(level));
        if (CollUtil.isNotEmpty(levelList)) {
            throw exception(ErrorCodeConstants.LEVEL_EXISTS);
        }
        // 不是第一级
        if (level > DistributorConstants.DEFAULT_LEVEL) {
            // 获取上级分销等级
            List<DistributorLevelDO> superiorLevelList = distributorLevelService.getLevelList(new DistributorLevelExportReqVO().setLevel(level - 1));
            if (CollUtil.isEmpty(superiorLevelList)) {
                throw exception(ErrorCodeConstants.LEVEL_SUPERIOR_NOT_EXISTS);
            }
            DistributorLevelDO superiorLevelDO = superiorLevelList.get(0);
            if (superiorLevelDO.getUserCount() > createReqVO.getUserCount()) {
                throw exception(ErrorCodeConstants.LEVEL_USERCOUNT_ERROR);
            }

            if (superiorLevelDO.getAmount().compareTo(createReqVO.getAmount()) > 0) {
                throw exception(ErrorCodeConstants.LEVEL_AMOUNT_ERROR);
            }

            if (superiorLevelDO.getWages().compareTo(createReqVO.getWages()) > 0) {
                throw exception(ErrorCodeConstants.LEVEL_WAGES_ERROR);
            }
        }

        Long id = distributorLevelService.createLevel(createReqVO);
        return id;
    }

    @Override
    public void updateLevel(DistributorLevelUpdateReqVO updateReqVO) {
        // 校验
        Integer level = updateReqVO.getLevel();
        // 不是第一级
        if (level > DistributorConstants.DEFAULT_LEVEL) {
            // 获取上级分销等级
            List<DistributorLevelDO> superiorLevelList = distributorLevelService.getLevelList(new DistributorLevelExportReqVO().setLevel(level - 1));
            if (CollUtil.isEmpty(superiorLevelList)) {
                throw exception(ErrorCodeConstants.LEVEL_SUPERIOR_NOT_EXISTS);
            }
            DistributorLevelDO superiorLevelDO = superiorLevelList.get(0);
            if (superiorLevelDO.getUserCount() > updateReqVO.getUserCount()) {
                throw exception(ErrorCodeConstants.LEVEL_USERCOUNT_ERROR);
            }

            if (superiorLevelDO.getAmount().compareTo(updateReqVO.getAmount()) > 0) {
                throw exception(ErrorCodeConstants.LEVEL_AMOUNT_ERROR);
            }

            if (superiorLevelDO.getWages().compareTo(updateReqVO.getWages()) > 0) {
                throw exception(ErrorCodeConstants.LEVEL_WAGES_ERROR);
            }
        }
        // 获取下级
        List<DistributorLevelDO> subordinateLevelList = distributorLevelService.getLevelList(new DistributorLevelExportReqVO().setLevel(level + 1));
        if (CollUtil.isNotEmpty(subordinateLevelList)) {
            DistributorLevelDO subordinateLevelDO = subordinateLevelList.get(0);
            if (subordinateLevelDO.getUserCount() < updateReqVO.getUserCount()) {
                throw exception(ErrorCodeConstants.LEVEL_USERCOUNT_LESS_ERROR);
            }

            if (subordinateLevelDO.getAmount().compareTo(updateReqVO.getAmount()) < 0) {
                throw exception(ErrorCodeConstants.LEVEL_AMOUNT_LESS_ERROR);
            }

            if (subordinateLevelDO.getWages().compareTo(updateReqVO.getWages()) < 0) {
                throw exception(ErrorCodeConstants.LEVEL_WAGES_LESS_ERROR);
            }
        }

        distributorLevelService.updateLevel(updateReqVO);
    }

    @Override
    public PageResult<DistributorLevelRespVO> getLevelPage(DistributorLevelPageReqVO pageVO) {
        List<DistributorDO> distributorList = distributorService.getList(new DistributorExportReqVO().setStatus(DistributorStatusEnum.PASSED.getStatus()));
        Map<Long, List<DistributorDO>> map = distributorList.stream().collect(Collectors.groupingBy(DistributorDO::getLevelId));
        PageResult<DistributorLevelRespVO> resp = DistributorLevelConvert.INSTANCE.convertPage(distributorLevelService.getLevelPage(pageVO));
        resp.getList().forEach(x -> {
            List<DistributorDO> distributorDOList = map.get(x.getId());
            if (CollUtil.isNotEmpty(distributorDOList)) {
                x.setCount(distributorDOList.size());
            } else {
                x.setCount(0);
            }
        });
        return resp;
    }

    @Async
    @Override
    public void levelUp(Long id) {
        // 获取分销商
        DistributorDO distributorDO = distributorService.get(id);
        // 获取等级
        DistributorLevelDO level = distributorLevelService.getLevel(distributorDO.getLevelId());
        List<DistributorLevelDO> subordinateLevelList = distributorLevelService.getLevelList(new DistributorLevelExportReqVO().setLevel(level.getLevel() + 1));
        if (CollUtil.isNotEmpty(subordinateLevelList)) {
            // 团队
            List<DistributorUserDO> p1UserList = distributorUserService.getUserList(new DistributorUserExportReqVO().setSuperiorIdP1(distributorDO.getId()));
            List<DistributorUserDO> p2UserList = distributorUserService.getUserList(new DistributorUserExportReqVO().setSuperiorIdP2(distributorDO.getId()));
            Integer userCount = p1UserList.size() + p2UserList.size();

            DistributorLevelDO distributorLevelDO = subordinateLevelList.get(0);
            DistributorUpdateReqVO distributorUpdateReqVO = new DistributorUpdateReqVO();
            distributorUpdateReqVO.setId(distributorDO.getId()).setLevelId(distributorLevelDO.getId());
            if (distributorLevelDO.getUpType().equals(DistributorLevelUpTypeEnum.ONLY.getType())) {
                // 任意
                if (distributorLevelDO.getUserCount() != -1 && userCount >= distributorLevelDO.getUserCount()) {
                    distributorService.update(distributorUpdateReqVO);
                } else if (!distributorLevelDO.getWages().equals(new BigDecimal(-1)) && distributorDO.getAddUpWages().compareTo(distributorLevelDO.getWages()) >= 0) {
                    distributorService.update(distributorUpdateReqVO);
                } else if (!distributorLevelDO.getAmount().equals(new BigDecimal(-1)) && distributorDO.getAddUpAmount().compareTo(distributorLevelDO.getAmount()) >= 0) {
                    distributorService.update(distributorUpdateReqVO);
                }
            } else {
                // 全部
                if (userCount >= distributorLevelDO.getUserCount()
                        && distributorDO.getAddUpWages().compareTo(distributorLevelDO.getWages()) >= 0
                        && distributorDO.getAddUpAmount().compareTo(distributorLevelDO.getAmount()) >= 0
                ) {
                    // 升级
                    distributorService.update(distributorUpdateReqVO);
                }
            }

        }
    }
}
