package cn.newfeifan.mall.module.distri.service.duser;

import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.newfeifan.mall.module.distri.controller.admin.integral.vo.IntegralSaveReqVO;
import cn.newfeifan.mall.module.distri.controller.admin.sharepath.vo.SharePathSaveReqVO;
import cn.newfeifan.mall.module.distri.dal.dataobject.integral.IntegralDO;
import cn.newfeifan.mall.module.distri.dal.dataobject.sharepath.SharePathDO;
import cn.newfeifan.mall.module.distri.dal.mysql.sharepath.SharePathMapper;
import cn.newfeifan.mall.module.distri.service.integral.IntegralService;
import cn.newfeifan.mall.module.distri.service.socialstatus.SocialStatusService;
import cn.newfeifan.mall.module.member.dal.dataobject.user.MemberUserDO;
import cn.newfeifan.mall.module.member.dal.mysql.user.MemberUserMapper;
import cn.newfeifan.mall.module.member.service.user.MemberUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import cn.newfeifan.mall.module.distri.controller.admin.duser.vo.*;
import cn.newfeifan.mall.module.distri.dal.dataobject.duser.DuserDO;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.util.object.BeanUtils;

import cn.newfeifan.mall.module.distri.dal.mysql.duser.DuserMapper;

import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.newfeifan.mall.module.distri.enums.ErrorCodeConstants.*;

/**
 * 推荐用户 Service 实现类
 *
 * @author 非繁人
 */
@Service
@Validated
public class DuserServiceImpl implements DuserService {

    @Resource
    private DuserMapper duserMapper;

    @Resource
    private MemberUserService memberUserService;

    @Resource
    private SharePathMapper sharePathMapper;

    @Resource
    private MemberUserMapper memberUserMapper;


    @Override
    public Long createDuser(DuserSaveReqVO createReqVO) {
        // 插入
        DuserDO duser = BeanUtils.toBean(createReqVO, DuserDO.class);
        duserMapper.insert(duser);
        // 返回
        return duser.getId();
    }

    @Override
    public void updateDuser(DuserSaveReqVO updateReqVO) {
        // 校验存在
        validateDuserExists(updateReqVO.getId());
        // 更新
        DuserDO updateObj = BeanUtils.toBean(updateReqVO, DuserDO.class);
        duserMapper.updateById(updateObj);
    }

    @Override
    public void deleteDuser(Long id) {
        // 校验存在
        validateDuserExists(id);
        // 删除
        duserMapper.deleteById(id);
    }

    private void validateDuserExists(Long id) {
        if (duserMapper.selectById(id) == null) {
            throw exception(DUSER_NOT_EXISTS);
        }
    }

    @Override
    public DuserDO getDuser(Long id) {
        return duserMapper.selectById(id);
    }

    @Override
    public PageResult<DuserDO> getDuserPage(DuserPageReqVO pageReqVO) {
        return duserMapper.selectPage(pageReqVO);
    }

    @Resource
    private IntegralService integralService;

    @Resource
    private SocialStatusService socialStatusService;

    @Override
    public void hasUserAndCreat(SharePathSaveReqVO saveReqVO) {
        checkAndCreat(saveReqVO.getDescendant());
        checkAndCreat(saveReqVO.getAncestor());
    }

    @Override
    public void hasUserAndCreat(Long userId) {
        checkAndCreat(userId);
    }

    @Override
    public void hasUserAndCreat(List<Long> userIds) {
        if (userIds == null) {
            return;
        }
        userIds.forEach(this::hasUserAndCreat);
    }

    @Override
    public List<DuserDO> selectAllUser() {
        return duserMapper.selectList();
    }

    private void checkAndCreat(Long userId) {
        DuserDO duserDO = duserMapper.selectOne(new LambdaQueryWrapperX<DuserDO>().eqIfPresent(DuserDO::getUserId, userId));
        MemberUserDO user = memberUserService.getUser(userId);
        // 判断是否有钱包
        IntegralDO integralDO = integralService.selectByUser(userId);
        if (integralDO == null) {
            // 创建一个钱包
            IntegralSaveReqVO integralSaveReqVO = IntegralSaveReqVO.builder()
                    .currentQuota(0)
                    .nickName(user.getNickname())
                    .name(user.getName())
                    .freezeQuota(0)
                    .categoryId(3L)
                    .userId(userId).build();
            Long integralId = integralService.createIntegral(integralSaveReqVO);
            integralDO = new IntegralDO().setId(integralId);
        }
        if (duserDO == null) {
            // 创建一个新的营销用户
            DuserSaveReqVO duserSaveReqVO = DuserSaveReqVO.builder()
                    .userId(userId)
                    .mobile(user.getMobile())
                    .name(user.getName())
                    .nickName(user.getNickname())
                    .integralId(integralDO.getId())
                    .source(userId)
                    .socialStatus(1L)
                    .socialStatusPoint(0L)
                    .build();
            duserMapper.insert(BeanUtils.toBean(duserSaveReqVO, DuserDO.class));
        }
    }


    @Override
    public void getSharePathCount(PageResult<DuserRespVO> result) {
        List<DuserRespVO> list = result.getList();
        for (DuserRespVO duserRespVO : list) {
            duserRespVO.setDescendantCount(sharePathMapper.selectCount(new LambdaQueryWrapperX<SharePathDO>()
                    .eq(SharePathDO::getAncestor, duserRespVO.getUserId())
                    .eq(SharePathDO::getDepth,1)
            ));
            duserRespVO.setChildrenCount(sharePathMapper.selectCount(new LambdaQueryWrapperX<SharePathDO>()
                    .eq(SharePathDO::getAncestor, duserRespVO.getUserId())
                    .ne(SharePathDO::getDepth,1)
            ));
        }
    }

    @Override
    public List<MemberUserDO> getDescendants(Long userId, Long depth) {
        LambdaQueryWrapperX<SharePathDO> wrapper = new LambdaQueryWrapperX<SharePathDO>()
                .eq(SharePathDO::getAncestor, userId);
        if(depth != null){
            wrapper.eq(SharePathDO::getDepth, 1);
        }else {
            wrapper.ne(SharePathDO::getDepth, 1);
        }
        List<SharePathDO> sharePathDOS = sharePathMapper.selectList(wrapper);
        List<Long> userIds = sharePathDOS.stream().map(SharePathDO::getDescendant).collect(Collectors.toList());


        return memberUserMapper.selectList(new LambdaQueryWrapper<MemberUserDO>()
                .in(MemberUserDO::getId, userIds)
        );
    }

}