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

import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.newfeifan.mall.module.distri.dal.dataobject.ordercalc.OrderCalcDO;
import cn.newfeifan.mall.module.distri.service.duser.DuserService;
import cn.newfeifan.mall.module.distri.service.ordercalc.OrderCalcService;
import cn.newfeifan.mall.module.member.dal.dataobject.user.MemberUserDO;
import cn.newfeifan.mall.module.member.service.user.MemberUserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.newfeifan.mall.module.distri.controller.admin.sharepath.vo.*;
import cn.newfeifan.mall.module.distri.dal.dataobject.sharepath.SharePathDO;
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.sharepath.SharePathMapper;

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 SharePathServiceImpl implements SharePathService {

    @Resource
    private SharePathMapper sharePathMapper;

    @Resource
    @Lazy
    private DuserService duserService;
    @Resource
    private MemberUserService memberUserService;
    @Resource
    private OrderCalcService orderCalcService;

    @Override
    public Long createSharePath(SharePathSaveReqVO createReqVO) {
        // 插入
        SharePathDO sharePath = BeanUtils.toBean(createReqVO, SharePathDO.class);
        sharePathMapper.insert(sharePath);
        // 返回
        return sharePath.getId();
    }


    @Override
    public void createSharePathByUserId(SharePathSaveReqVO createReqVO) {

        // 如果直推人为空, 则直接结束
        if (createReqVO.getDescendant() == null) {
            return;
        }

        // 判断当前直推人是否有父亲
        Boolean has = hasParent(createReqVO.getDescendant());
        if (has) {
            throw exception(HAS_PARENT);
        }
        if (createReqVO.getAncestor() == null) {
            createReqVO.setAncestor(PT_ID);
        }
        MemberUserDO ancestor = memberUserService.getUser(createReqVO.getAncestor());
        MemberUserDO descendant = memberUserService.getUser(createReqVO.getDescendant());

        // 创建直推人以及推荐人的关系
        // 需要判断当前推荐人跟直推人是否已经存在于用户表(duser)了
        duserService.hasUserAndCreat(createReqVO);

        // 存储他们之间的关系
        sharePathMapper.addNode(
                createReqVO.getAncestor(),
                ancestor.getName(),
                ancestor.getNickname(),
                ancestor.getMobile(),

                createReqVO.getDescendant(),
                descendant.getName(),
                descendant.getNickname(),
                descendant.getMobile());
    }

    @Override
    public void createSharePathByUserId(List<Long> userIds) {

        for (Long userId : userIds) {
            Boolean has = hasParent(userId);
            if (has) {
                continue;
            }
            // 如果是没有父亲, 将其推荐人设置为平台
            SharePathSaveReqVO build = SharePathSaveReqVO.builder()
                    .ancestor(PT_ID)
                    .descendant(userId)
                    .build();
            createSharePathByUserId(build);
        }
    }

    private Boolean hasParent(Long descendant) {
        SharePathDO sharePathDO = sharePathMapper.selectOne(new LambdaQueryWrapperX<SharePathDO>()
                .eqIfPresent(SharePathDO::getDescendant, descendant)
                .eqIfPresent(SharePathDO::getDepth, 1));
        return sharePathDO != null;
    }

    @Override
    public void updateSharePath(SharePathSaveReqVO updateReqVO) {
        // 校验存在
        validateSharePathExists(updateReqVO.getId());
        // 更新
        SharePathDO updateObj = BeanUtils.toBean(updateReqVO, SharePathDO.class);
        sharePathMapper.updateById(updateObj);
    }

    @Override
    public void deleteSharePath(Long id) {
        // 校验存在
        validateSharePathExists(id);
        // 删除
        sharePathMapper.deleteById(id);
    }

    private void validateSharePathExists(Long id) {
        if (sharePathMapper.selectById(id) == null) {
            throw exception(SHARE_PATH_NOT_EXISTS);
        }
    }

    @Override
    public SharePathDO getSharePath(Long id) {
        return sharePathMapper.selectById(id);
    }

    @Override
    public PageResult<SharePathDO> getSharePathPage(SharePathPageReqVO pageReqVO) {
        return sharePathMapper.selectPage(pageReqVO);
    }

    @Override
    public TreeNode getTree() {


        return null;
    }

    @Override
    public void transferenceRela(SharePathtransFerenceRelaReqVO sharePathtransFerenceRelaReqVO) {
        // todo 转让用户关系
    }

    @Override
    public SharePathDO getSharePathByDescendant(Long userId) {

        List<SharePathDO> sharePathDOS = sharePathMapper.selectList(new LambdaQueryWrapperX<SharePathDO>().eqIfPresent(SharePathDO::getDescendant, userId)
                .eqIfPresent(SharePathDO::getDepth, 1));
        if (sharePathDOS.isEmpty()) {
            return null;
        }
        return sharePathDOS.get(0);
    }

    @Override
    public List<OrderCalcDO> selectSons(Long userId, List<Long> userIds) {
        List<Long> allDescendants = sharePathMapper.findAllDescendants(userId);
        if (allDescendants.isEmpty()) {
            return Collections.emptyList();
        }
        // 查询出两个list的并集
        List<Long> unionList = unionList(userIds, allDescendants);
        if (unionList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取这个分区的所有订单的合赢奖
        return calcQuota(unionList);

    }

    private List<OrderCalcDO> calcQuota(List<Long> unionList) {

        // 根据当前userId， 查询当日，计算出来的订单
        // 创建日期
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT); // 今天的开始时间，即午夜12点
        LocalDateTime todayEnd = todayStart.plusDays(1);

        return orderCalcService.queryTodayCalcByUserIds(todayStart, todayEnd);

    }

    @Override
    public List<OrderCalcDO> selectBrothers(Long userId, List<Long> userIds) {

        List<Long> sortedSiblings = sharePathMapper.findLessSortedSiblings(userId);
        if (sortedSiblings.isEmpty()) {
            return Collections.emptyList();
        }
        // 查询出两个list的并集
        List<Long> unionList = unionList(userIds, sortedSiblings);
        if (unionList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取这个分区的所有订单的合赢奖
        return calcQuota(unionList);
    }

    @Override
    public Long queryParentBySonUserId(Long userId) {

        SharePathDO sharePathDO = sharePathMapper.selectOne(new LambdaQueryWrapperX<SharePathDO>()
                .eqIfPresent(SharePathDO::getDescendant, userId).eqIfPresent(SharePathDO::getDepth, 1));
        if (sharePathDO == null) {
            return 1L;
        } else {
            return sharePathDO.getAncestor();
        }


    }


    public List<Long> unionList(List<Long> orderUserId, List<Long> userId) {
        return Stream.concat(orderUserId.stream(), userId.stream()).distinct().collect(Collectors.toList());

    }


}