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

import cn.hutool.core.collection.CollUtil;
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.controller.admin.socialstatus.bo.SocialStatusBO;
import cn.newfeifan.mall.module.distri.dal.dataobject.integral.IntegralDO;
import cn.newfeifan.mall.module.distri.dal.dataobject.orderpercentage.OrderPercentageDO;
import cn.newfeifan.mall.module.distri.dal.dataobject.sharepath.SharePathDO;
import cn.newfeifan.mall.module.distri.dal.dataobject.socialstatus.SocialStatusDO;
import cn.newfeifan.mall.module.distri.dal.mysql.orderpercentage.OrderPercentageMapper;
import cn.newfeifan.mall.module.distri.dal.mysql.sharepath.SharePathMapper;
import cn.newfeifan.mall.module.distri.enums.SocialStatusEnum;
import cn.newfeifan.mall.module.distri.service.integral.IntegralService;
import cn.newfeifan.mall.module.distri.service.ptprofitlog.PtProfitLogService;
import cn.newfeifan.mall.module.distri.service.sharepath.SharePathService;
import cn.newfeifan.mall.module.distri.service.socialstatus.SocialStatusService;
import cn.newfeifan.mall.module.distri.service.socialstatuschangelog.SocialStatusChangeLogService;
import cn.newfeifan.mall.module.member.controller.admin.user.vo.MemberUserPageReqVO;
import cn.newfeifan.mall.module.member.controller.admin.user.vo.MemberUserRespVO;
import cn.newfeifan.mall.module.member.convert.user.MemberUserConvert;
import cn.newfeifan.mall.module.member.dal.dataobject.user.MemberUserDO;
import cn.newfeifan.mall.module.member.service.user.MemberUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;

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.constant.DistriConstants.PT_ID;
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
    @Lazy
    private SharePathService sharePathService;

    @Resource
    private PtProfitLogService ptProfitLogService;

    @Resource
    private OrderPercentageMapper orderPercentageMapper;

    @Resource
    private SocialStatusChangeLogService socialStatusChangeLogService;


    @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);
    }

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

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

    @Override
    public DuserDO getDuserByUser(Long id) {
        return duserMapper.selectOne(new LambdaQueryWrapperX<DuserDO>().eq(DuserDO::getUserId, id));
    }

    @Override
    public DuserDO getDuserByMobile(String mobile) {
        return duserMapper.selectOne(new LambdaQueryWrapperX<DuserDO>()
                .eq(DuserDO::getMobile, mobile)
        );
    }

    @Override
    public DuserInfoVO initDuser() {

        List<MemberUserDO> memberUserDOS = memberUserService.getAllUser();
        for (MemberUserDO memberUserDO : memberUserDOS) {
            checkAndCreat(memberUserDO.getId());
        }
        return null;
    }

    @Override
    public void updateDuserSocial(Long userId, Long social, Integer socialStatus) {

        //平台不参与身价
        if (Objects.equals(userId, PT_ID)) {
            return;
        }

        //计算本次获得的身价
        DuserDO duser = getDuserByUser(userId);
        duser.setSocialStatusPoint(duser.getSocialStatusPoint() + social);

        SocialStatusBO socialStatusBO = socialStatusService.calculateSocial(duser.getSocialStatusPoint());
        duser.setSocialUpNeed(socialStatusBO.getSocialUpNeed());
        duser.setSocialStatusId(socialStatusBO.getId());

        duserMapper.updateById(duser);

        socialStatusChangeLogService.createSocialStatusChangeLog(userId, social, userId, SocialStatusEnum.getSocialStatusEnumByCode(socialStatus));
    }

    @Override
    public PageResult<MemberUserRespVO> getMemberUserPage(MemberUserPageReqVO pageVO) {
        PageResult<MemberUserDO> pageResult = memberUserService.getUserPage(pageVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return PageResult.empty();
        }
        PageResult<MemberUserRespVO> result = MemberUserConvert.INSTANCE.convertPage(pageResult);
        for (MemberUserRespVO memberUserRespVO : result.getList()) {
            //获取团队用户
            DuserDO duser = getDuserByUser(memberUserRespVO.getId());
            if (duser == null) continue;
            SocialStatusDO socialStatus = socialStatusService.getSocialStatus(duser.getSocialStatusId());
            memberUserRespVO.setCategoryId(duser.getCategoryId());
            if (socialStatus == null) continue;
            memberUserRespVO.setCurrentMemberWorthLevelName(socialStatus.getName());
            memberUserRespVO.setCurrentMemberWorthLevel(socialStatus.getLevel());
            //获取钱包
            IntegralDO integral = integralService.getIntegral(memberUserRespVO.getId());
            memberUserRespVO.setYellowCurrentQuota(integral.getYellowCurrentQuota());
            memberUserRespVO.setGreenCurrentQuota(integral.getGreenCurrentQuota());
            memberUserRespVO.setRedCurrentQuota(integral.getRedCurrentQuota());
//            if(integral == null) continue;
        }
        return result;
    }

    @Override
    public PageResult<DuserDO> getDuserPage(DuserPageReqVO pageReqVO) {

        if (pageReqVO.getUsername() != null && !pageReqVO.getUsername().isEmpty()) {
            MemberUserDO user = memberUserService.getUserByUsername(pageReqVO.getUsername());
            pageReqVO.setUserId(user == null ? -1 : user.getId());
        }

        return duserMapper.selectPage(pageReqVO);
    }

    @Resource
    private IntegralService integralService;

    @Resource
    private SocialStatusService socialStatusService;

    @Override
    public void hasUserAndCreat(SharePathSaveReqVO saveReqVO) {
        checkAndCreat(saveReqVO.getUserId());
        checkAndCreat(saveReqVO.getReferrerId());
    }

    @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();
    }

    @Override
    public List<DuserDO> selectUserByUserIds(List<Long> duserId) {
        return duserMapper.selectList(new LambdaQueryWrapperX<DuserDO>().inIfPresent(DuserDO::getUserId, duserId));
    }

    @Override
    public DuserInfoVO getDuserInfo(Long userId) {

        List<Long> sonsId = sharePathService.sonsId(userId);
        IntegralDO integral = integralService.getIntegral(userId);
        if (integral == null) {
            throw exception(INTEGRAL_NOT_EXISTS);
        }
        DuserInfoVO.DuserInfoVOBuilder duserInfoVOBuilder = DuserInfoVO.builder()
                .integralDO(integral)
                .descNo(sonsId.size());

        // 获取昨日贡献值 + 合赢奖
        String yesterday = ptProfitLogService.getYesterdayLog(sonsId);
        String totalLog = ptProfitLogService.getTotalLog(sonsId);
        return duserInfoVOBuilder.descPrice(Long.parseLong(yesterday))
                .descTotalPrice(Long.parseLong(totalLog)).build();

    }

    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()
                    .redCurrentQuota(0L)
                    .freezeQuota(0L)
                    .userId(userId).build();
            Long integralId = integralService.createIntegral(integralSaveReqVO);
            integralDO = new IntegralDO().setId(integralId);
        }
        if (duserDO == null) {
            OrderPercentageDO orderPercentageDO = orderPercentageMapper.selectList().get(0);
            SocialStatusBO socialStatusBO = socialStatusService.calculateSocial(Long.valueOf(orderPercentageDO.getRegisterSocialStatus()));

            // 创建一个新的营销用户
            DuserSaveReqVO duserSaveReqVO = DuserSaveReqVO.builder()
                    .userId(userId)
                    .mobile(user.getMobile())
                    .integralId(integralDO.getId())
                    .source(userId)
                    .socialStatusPoint(Long.valueOf(orderPercentageDO.getRegisterSocialStatus()))
                    .socialStatusId(socialStatusBO.getId())
                    .socialUpNeed(socialStatusBO.getSocialUpNeed())
                    .build();
            duserMapper.insert(BeanUtils.toBean(duserSaveReqVO, DuserDO.class));

            socialStatusChangeLogService.createSocialStatusChangeLog(userId, Long.valueOf(orderPercentageDO.getRegisterAncestorSocialStatus()), userId, SocialStatusEnum.REGISTER_SOCIAL);
        }
    }


    @Override
    public void getSharePathCount(PageResult<DuserRespVO> result) {
        List<DuserRespVO> list = result.getList();
        for (DuserRespVO duserRespVO : list) {
            SharePathDO sharePathDO = sharePathMapper.selectOne(new LambdaQueryWrapper<SharePathDO>()
                    .eq(SharePathDO::getUserId, duserRespVO.getUserId())
            );
            duserRespVO.setLeftChildId(sharePathDO.getLeftChildId());
            duserRespVO.setRightChildId(sharePathDO.getRightChildId());
            duserRespVO.setDescendantCount(sharePathMapper.selectCount(new LambdaQueryWrapperX<SharePathDO>()
                    .eq(SharePathDO::getReferrerId, duserRespVO.getUserId())
            ));
            duserRespVO.setLeftCount((long) sharePathMapper.selectListByUserId(sharePathDO.getLeftChildId(), 99999).size());
            duserRespVO.setRightCount((long) sharePathMapper.selectListByUserId(sharePathDO.getRightChildId(), 99999).size());

            SharePathDO referrer = sharePathMapper.selectOne(new LambdaQueryWrapper<SharePathDO>()
                    .eq(SharePathDO::getUserId, sharePathDO.getReferrerId())
            );
            duserRespVO.setAncUsername(referrer == null ? "" : referrer.getUserName());

            MemberUserDO user = memberUserService.getUser(duserRespVO.getUserId());
            duserRespVO.setAvatar(user.getAvatar());
            duserRespVO.setUsername(user.getUsername());


            IntegralDO integral = integralService.getIntegral(duserRespVO.getUserId());
            if (integral != null) {
                duserRespVO.setRedCurrentQuota(integral.getRedCurrentQuota());
                duserRespVO.setYellowCurrentQuota(integral.getYellowCurrentQuota());
                duserRespVO.setGreenCurrentQuota(integral.getGreenCurrentQuota());
            }
        }
    }
}