
package com.tmerclub.cloud.distribution.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.order.vo.SumAmountVO;
import com.tmerclub.cloud.api.platform.feign.SysUserFeignClient;
import com.tmerclub.cloud.api.platform.vo.SysUserVO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.SendTypeEnum;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.order.vo.SendNotifyBO;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.rocketmq.config.RocketMqConstant;
import com.tmerclub.cloud.distribution.constant.DistributionAuditingState;
import com.tmerclub.cloud.distribution.constant.DistributionUserStateEnum;
import com.tmerclub.cloud.distribution.dto.DistributionAuditingDTO;
import com.tmerclub.cloud.distribution.mapper.DistributionAuditingMapper;
import com.tmerclub.cloud.distribution.mapper.DistributionUserBindMapper;
import com.tmerclub.cloud.distribution.mapper.DistributionUserMapper;
import com.tmerclub.cloud.distribution.model.DistributionAuditing;
import com.tmerclub.cloud.distribution.model.DistributionUser;
import com.tmerclub.cloud.distribution.service.DistributionAuditingService;
import com.tmerclub.cloud.distribution.vo.DistributionAuditingVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 分销员申请信息
 *
 * @author cl
 * @date 2021-08-09 14:14:05
 */
@Service
public class DistributionAuditingServiceImpl implements DistributionAuditingService {

    @Autowired
    private DistributionAuditingMapper distributionAuditingMapper;
    @DubboReference
    private SysUserFeignClient sysUserFeignClient;
    @DubboReference
    private OrderFeignClient orderFeignClient;
    @Autowired
    private DistributionUserMapper distributionUserMapper;
    @Autowired
    private DistributionUserBindMapper distributionUserBindMapper;
    @Autowired
    private RocketMQTemplate sendNotifyToUserTemplate;

    @Override
    public PageVO<DistributionAuditingVO> pageDistributionAuditing(PageDTO pageDTO, DistributionAuditingDTO distributionAuditingDTO) {
        PageVO<DistributionAuditingVO> distributionAuditingPage = PageUtil.doPage(pageDTO, () -> distributionAuditingMapper.listDistributionAuditing(distributionAuditingDTO));
        List<DistributionAuditingVO> auditingPageList = distributionAuditingPage.getList();
        if (CollUtil.isEmpty(auditingPageList)) {
            return distributionAuditingPage;
        }
        List<Long> modifierIds = auditingPageList.stream().map(DistributionAuditingVO::getModifier).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> userIds = auditingPageList.stream().map(DistributionAuditingVO::getUserId).collect(Collectors.toList());
        if (CollUtil.isEmpty(modifierIds) || CollUtil.isEmpty(userIds)) {
            return distributionAuditingPage;
        }
        //根据修改人的用户id查询姓名以及订单信息[积累消费金额，积累消费笔数]
        ServerResponseEntity<List<SysUserVO>> sysUserData = sysUserFeignClient.getSysUserList(modifierIds);
        if (!sysUserData.isSuccess()) {
            throw new LuckException(sysUserData.getMsg());
        }
        ServerResponseEntity<List<SumAmountVO>> sumAmountData = orderFeignClient.listSumDataByUserIds(userIds);
        if (!sumAmountData.isSuccess()) {
            throw new LuckException(sumAmountData.getMsg());
        }
        List<SumAmountVO> sumDataList = sumAmountData.getData();
        List<SysUserVO> sysUserList = sysUserData.getData();
        Map<Long, SysUserVO> userMap = sysUserList.stream().collect(Collectors.toMap(SysUserVO::getSysUserId, s -> s));
        Map<Long, SumAmountVO> sumDataMap = sumDataList.stream().collect(Collectors.toMap(SumAmountVO::getUserId, s -> s));
        for (DistributionAuditingVO distributionAuditingVO : auditingPageList) {
            if (Objects.nonNull(distributionAuditingVO.getModifier())) {
                SysUserVO sysUserVO = userMap.get(distributionAuditingVO.getModifier());
                if (Objects.isNull(sysUserVO)) {
                    distributionAuditingVO.setModifierName("admin");
                } else {
                    distributionAuditingVO.setModifierName(sysUserVO.getNickName());
                }
            }
            if (Objects.nonNull(distributionAuditingVO.getUserId())) {
                SumAmountVO sumAmountVO = sumDataMap.get(distributionAuditingVO.getUserId());
                if (Objects.isNull(sumAmountVO)) {
                    //积累消费金额
                    distributionAuditingVO.setSumOfConsumption(0.00);
                    //积累消费笔数
                    distributionAuditingVO.setExpenseNumber(0);
                } else {
                    //积累消费金额
                    distributionAuditingVO.setSumOfConsumption(sumAmountVO.getSumOfConsumption());
                    //积累消费笔数
                    distributionAuditingVO.setExpenseNumber(Objects.isNull(sumAmountVO.getExpenseNumber()) ? 0 : sumAmountVO.getExpenseNumber());
                }
            }
        }
        return distributionAuditingPage;
    }

    @Override
    public DistributionAuditing getByAuditingId(Long auditingId) {
        return distributionAuditingMapper.getByAuditingId(auditingId);
    }

    @Override
    public void save(DistributionAuditing distributionAuditing) {
        distributionAuditingMapper.save(distributionAuditing);
    }

    @Override
    public void update(DistributionAuditing distributionAuditing) {
        distributionAuditingMapper.update(distributionAuditing);
    }

    @Override
    public void deleteById(Long auditingId) {
        distributionAuditingMapper.deleteById(auditingId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void examine(DistributionAuditing distributionAuditing) {
        DistributionUser distributionUser = new DistributionUser();
        distributionUser.setDistributionUserId(distributionAuditing.getDistributionUserId());
        distributionUser.setBindTime(new Date());
        distributionUser.setStateRecord(null);
        //判断是否通过
        if (Objects.equals(DistributionAuditingState.PASS.value(), distributionAuditing.getState())) {
            DistributionUser beforeDistributionUser = distributionUserMapper.getByDistributionUserId(distributionAuditing.getDistributionUserId());
            if (Objects.nonNull(beforeDistributionUser) && Objects.nonNull(beforeDistributionUser.getStateRecord())
                    && Objects.equals(beforeDistributionUser.getStateRecord(), DistributionUserStateEnum.BAN.value())) {
                //如果之前是暂时封禁状态，现在改成正常状态,恢复以前的绑定用户。将失效的绑定用户设为正常。
                distributionUserBindMapper.updateBindUserByDistributionUserId(distributionAuditing.getDistributionUserId());
            }
            //通过审核，设为正常状态
            distributionUser.setState(DistributionUserStateEnum.NORMAL.value());
            // 发送通知
            // 发送消息，分销员申请成功通知给用户
            List<SendNotifyBO> notifyList = new ArrayList<>(Constant.INITIAL_CAPACITY);
            SendNotifyBO sendNotifyBO = new SendNotifyBO();
            sendNotifyBO.setSendType(SendTypeEnum.DISTRIBUTION_APPLY_SUCCESS.getValue());
            sendNotifyBO.setUserId(beforeDistributionUser.getUserId());
            sendNotifyBO.setShopId(Constant.PLATFORM_SHOP_ID);
            notifyList.add(sendNotifyBO);
            // 分销员申请成功推送消息给用户
            SendStatus sendStockStatus = sendNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(notifyList)).getSendStatus();
            if (!Objects.equals(sendStockStatus, SendStatus.SEND_OK)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        } else if (Objects.equals(DistributionAuditingState.UN_PASS.value(), distributionAuditing.getState())) {
            //未通过审核
            distributionUser.setState(DistributionUserStateEnum.FAIL_AUDIT.value());
        }
        //更新分销员状态
        distributionUserMapper.updateStatus(distributionUser);
        distributionAuditingMapper.update(distributionAuditing);
    }

    @Override
    public void autoRejectBySwitchAllinpay() {
        // 查询所有待审核的分销员
        DistributionAuditingDTO distributionAuditingDTO = new DistributionAuditingDTO();
        distributionAuditingDTO.setState(DistributionAuditingState.UN_AUDIT.value());
        List<DistributionAuditingVO> distributionAuditingVOList = distributionAuditingMapper.listDistributionAuditing(distributionAuditingDTO);
        // 拒绝分销员申请
        DistributionAuditingService distributionAuditingService = (DistributionAuditingService) AopContext.currentProxy();
        DistributionAuditing distributionAuditing;
        for (DistributionAuditingVO distributionAuditingVO : distributionAuditingVOList) {
            distributionAuditing = new DistributionAuditing();
            distributionAuditing.setAuditingId(distributionAuditingVO.getAuditingId());
            distributionAuditing.setDistributionUserId(distributionAuditingVO.getDistributionUserId());
            distributionAuditing.setRemarks("平台支付系统切换，请重新申请");
            distributionAuditing.setReason(-1);
            distributionAuditing.setState(DistributionAuditingState.UN_PASS.value());
            distributionAuditingService.examine(distributionAuditing);
        }
    }
}
