package com.pcloud.book.cultivate.biz.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.applet.biz.AppletNewsBiz;
import com.pcloud.book.applet.dto.AppletNewsDTO;
import com.pcloud.book.applet.dto.ServeItemInfoDTO;
import com.pcloud.book.applet.enums.AppletRecordTypeEnum;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.dao.BookDao;
import com.pcloud.book.book.dao.SearchRecordDao;
import com.pcloud.book.book.dto.AdviserBookInfoDTO;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.content.ResourceConsr;
import com.pcloud.book.consumer.message.TemplateConsr;
import com.pcloud.book.consumer.reader.ReaderConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.cultivate.biz.CultivateNotifyBiz;
import com.pcloud.book.cultivate.check.NotifyParamCheck;
import com.pcloud.book.cultivate.dao.CultivateNotifyDao;
import com.pcloud.book.cultivate.dao.CultivateNotifyItemDao;
import com.pcloud.book.cultivate.dao.CultivateNotifySendDao;
import com.pcloud.book.cultivate.dto.CultivateNotifyDTO;
import com.pcloud.book.cultivate.dto.CultivateNotifyPageDTO;
import com.pcloud.book.cultivate.dto.CultivateNotifyTypeDTO;
import com.pcloud.book.cultivate.dto.NotifyItemDTO;
import com.pcloud.book.cultivate.dto.NotifySendDTO;
import com.pcloud.book.cultivate.dto.SearchNotifyDTO;
import com.pcloud.book.cultivate.dto.SearchSendUserDTO;
import com.pcloud.book.cultivate.dto.WechatUserDTO;
import com.pcloud.book.cultivate.entity.AppletNotifySendDTO;
import com.pcloud.book.cultivate.entity.CultivateNotify;
import com.pcloud.book.cultivate.entity.CultivateNotifyItem;
import com.pcloud.book.cultivate.entity.CultivateNotifySend;
import com.pcloud.book.cultivate.enums.NotifySendTypeEnum;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.book.util.properties.BookProps;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.dto.AppletTemplateMessageDto;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.BeanUtils;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ServeLinkUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.contentcenter.resource.dto.ResourceDTO;
import com.pcloud.readercenter.applet.entity.AppletQuestion;
import com.pcloud.readercenter.wechat.dto.MiniUserDto;
import com.pcloud.readercenter.wechat.dto.ReaderMessageDto;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.usercenter.party.adviser.dto.AdviserBaseInfoDto;
import com.pcloud.wechatgroup.selfrobot.dto.SendMessageDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@Component("cultivateNotifyBiz")
@Slf4j
public class CultivateNotifyBizImpl implements CultivateNotifyBiz {

    @Autowired
    private NotifyParamCheck notifyParamCheck;
    @Autowired
    private CultivateNotifyDao cultivateNotifyDao;
    @Autowired
    private CultivateNotifyItemDao cultivateNotifyItemDao;
    @Autowired
    private CultivateNotifySendDao cultivateNotifySendDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private ReaderConsr readerConsr;

    @Autowired
    private ResourceConsr resourceConsr;
    @Autowired
    private SearchRecordDao searchRecordDao;
    @Autowired
    private BookDao bookDao;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private TemplateConsr templateConsr;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;

    private final Integer SEND_BATCH_NUM=100;
    @Autowired
    private AppletNewsBiz appletNewsBiz;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createNotify(CultivateNotifyDTO cultivateNotifyDTO) {
        notifyParamCheck.createNotifyCheck(cultivateNotifyDTO);
        CultivateNotify cultivateNotify=new CultivateNotify();
        cultivateNotify.setMessageType(cultivateNotifyDTO.getMessageType());
        cultivateNotify.setTitle(cultivateNotifyDTO.getTitle());
        cultivateNotify.setSendType(cultivateNotifyDTO.getSendType());
        cultivateNotify.setShowHome(cultivateNotifyDTO.getShowHome());
        cultivateNotify.setAgentId(null==cultivateNotifyDTO.getAgentId()?0L:cultivateNotifyDTO.getAgentId());
        cultivateNotifyDao.insert(cultivateNotify);
        cultivateNotifyDTO.getCultivateNotifyItems().forEach(a->a.setMessageId(cultivateNotify.getMessageId()));
        cultivateNotifyItemDao.insert(cultivateNotifyDTO.getCultivateNotifyItems());
        ThreadPoolUtils.SEND_NOTIFY_POOL.execute(()->{
            addSendNotify(cultivateNotifyDTO,cultivateNotify);
        });
    }

    @Override
    public CultivateNotifyDTO getFirstNoReadNotify(Long wechatUserId) {
        Long messageId= cultivateNotifySendDao.getFirstNoReadNotify(wechatUserId);
        if(messageId==null){
            return new CultivateNotifyDTO();
        }
        CultivateNotifyDTO notifyDTO= new CultivateNotifyDTO();
        List<CultivateNotifyItem> list=cultivateNotifyItemDao.getNotifyItemsByMessageId(messageId);
        fillResource(list);
        fillAppOrProduct4Notify(list);
        notifyDTO.setCultivateNotifyItems(list);
        CultivateNotify byId = cultivateNotifyDao.getById(messageId);
        notifyDTO.setMessageType(byId.getMessageType());
        notifyDTO.setTitle(byId.getTitle());
        // cultivateNotifySendDao.updateIsRead(wechatUserId,messageId);
        // 更新之前的所有未读消息都不显示到主页
        cultivateNotifySendDao.updateShowHome(wechatUserId);
        return notifyDTO;
    }

    @Override
    public List<CultivateNotifyTypeDTO> getNotify4Type(Long wechatUserId) {
        return cultivateNotifySendDao.getNotify4Type(wechatUserId);
    }

    @Override
    public PageBeanNew<CultivateNotifyDTO> getNotifyListByType(Long wechatUserId, Integer messageType,Integer currentPage,Integer numPerPage) {
        Map<String,Object> map=new HashMap<>();
        map.put("wechatUserId",wechatUserId);
        map.put("messageType",messageType);
        PageBeanNew<CultivateNotifyDTO> pageBeanNew= cultivateNotifySendDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getNotifyListByType");
        List<CultivateNotifyItem> cultivateNotifyItemList = new ArrayList<>();
        for (CultivateNotifyDTO cultivateNotifyDTO:pageBeanNew.getRecordList()) {
            List<CultivateNotifyItem> list1=cultivateNotifyItemDao.getNotifyItemsByMessageId(cultivateNotifyDTO.getMessageId());
            fillResource(list1);
            cultivateNotifyDTO.setCultivateNotifyItems(list1);
            cultivateNotifyItemList.addAll(list1);
        }
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
            //批量更新消息已读未读
            List<CultivateNotifySend> notifySends=cultivateNotifySendDao.getNotifySendsByType(wechatUserId,messageType);
            for (CultivateNotifySend notifySend:notifySends) {
                notifySend.setIsRead(true);
                notifySend.setReadTime(new Date());
                notifySend.setUpdateTime(new Date());
                cultivateNotifySendDao.update(notifySend);
            }
        });
        //填充资讯应用作品
        fillAppOrProduct4Notify(cultivateNotifyItemList);
        return pageBeanNew;
    }

    private void fillResource(List<CultivateNotifyItem> list){
        List<Long> resourceIds=new ArrayList<>();
        for (CultivateNotifyItem notifyItem : list){
            Integer type = notifyItem.getContentType();
            if (type==3){
                resourceIds.add(notifyItem.getResourceId());
            }
        }
        Map<Long, ResourceDTO> resourceDTOMap=new HashMap<>();
        if (!ListUtils.isEmpty(resourceIds)){
            resourceDTOMap = resourceConsr.mapByIds(resourceIds);
        }
        for (CultivateNotifyItem notifyItem : list) {
            Integer type = notifyItem.getContentType();
            if (type == 3) {
                ResourceDTO resourceDTO = resourceDTOMap.get(notifyItem.getResourceId());
                if (resourceDTO != null) {
                    notifyItem.setResourceName(resourceDTO.getResourceName());
                    notifyItem.setResourceUrl(resourceDTO.getFileUrl());
                    notifyItem.setResourceTypeCode(resourceDTO.getTypeCode());
                    notifyItem.setResourceTypeName(resourceDTO.getTypeName());
                    notifyItem.setFileType(resourceDTO.getFileType());
                    notifyItem.setFileSize(resourceDTO.getFileSize());
                    notifyItem.setResourcePdfItems(resourceDTO.getResourcePdfItems());
                    notifyItem.setResourceOfficeItemDTOs(resourceDTO.getResourceOfficeItemDTOs());
                    notifyItem.setDuration(resourceDTO.getDuration());
                }
            }
        }
    }


    private void addSendNotify(CultivateNotifyDTO cultivateNotifyDTO,CultivateNotify cultivateNotify){
        List<CultivateNotifySend> list=new ArrayList<>();
        //指定用户发送
        if (NotifySendTypeEnum.APPOINT_USER.value.equals(cultivateNotifyDTO.getSendType())) {
            CultivateNotifySend cultivateNotifySend = null;
            for (WechatUserDTO wechatUserDTO : cultivateNotifyDTO.getWechatUserDTOS()) {
                cultivateNotifySend = new CultivateNotifySend();
                cultivateNotifySend.setMessageId(cultivateNotify.getMessageId());
                cultivateNotifySend.setMessageType(cultivateNotifyDTO.getMessageType());
                cultivateNotifySend.setSendType(cultivateNotifyDTO.getSendType());
                cultivateNotifySend.setWxUserId(wechatUserDTO.getWxUserId());
                cultivateNotifySend.setWechatUserId(wechatUserDTO.getWechatUserId());
                cultivateNotifySend.setShowHome(cultivateNotifyDTO.getShowHome());
                cultivateNotifySend.setTitle(cultivateNotify.getTitle());
                list.add(cultivateNotifySend);
            }
            cultivateNotifySendDao.insert(list);
            sendAppletTemplateMessage(list, cultivateNotify.getAgentId(), null);
        }
        //分类用户发送
        if (NotifySendTypeEnum.CLASSIFY_USER.value.equals(cultivateNotifyDTO.getSendType())) {
            SendMessageDTO sendMessageDTO = new SendMessageDTO();
            sendMessageDTO.setClassifyId(cultivateNotifyDTO.getClassifyId());
            sendMessageDTO.setMessageId(cultivateNotify.getMessageId());
            sendMessageDTO.setMessageType(cultivateNotify.getMessageType());
            sendMessageDTO.setSendType(cultivateNotifyDTO.getSendType());
            sendMessageDTO.setWxId(cultivateNotifyDTO.getWxId());
            wechatGroupConsr.sendMessageToMiniUser(sendMessageDTO);
        }
        //书刊发送
        if(NotifySendTypeEnum.BOOK_USER.value.equals(cultivateNotifyDTO.getSendType())){
            List<Long> wechatUserIds = readerConsr.getMiniUsersByBookIds(cultivateNotifyDTO.getBookIds());
            if(ListUtils.isEmpty(wechatUserIds)){
                return;
            }
            for (int i = 0; i <= wechatUserIds.size() / SEND_BATCH_NUM; i++) {
                int beginIndex = i * SEND_BATCH_NUM;
                int endIndex = beginIndex + SEND_BATCH_NUM;
                if (i == (wechatUserIds.size() - 1)/SEND_BATCH_NUM){
                    endIndex = wechatUserIds.size();
                }
                List<Long> subList = wechatUserIds.subList(beginIndex, endIndex);
                List<CultivateNotifySend> cultivateNotifySendList=new ArrayList<>();
                if(!ListUtils.isEmpty(subList)){
                    for (Long wechatUserId : subList) {
                        CultivateNotifySend cultivateNotifySend=new CultivateNotifySend();
                        cultivateNotifySend.setMessageId(cultivateNotify.getMessageId());
                        cultivateNotifySend.setMessageType(cultivateNotifyDTO.getMessageType());
                        cultivateNotifySend.setSendType(cultivateNotifyDTO.getSendType());
                        cultivateNotifySend.setWechatUserId(wechatUserId);
                        cultivateNotifySend.setShowHome(cultivateNotifyDTO.getShowHome());
                        cultivateNotifySendList.add(cultivateNotifySend);
                    }
                    cultivateNotifySendDao.insert(cultivateNotifySendList);
                    sendAppletTemplateMessage(cultivateNotifySendList, cultivateNotify.getAgentId(), null);
                }
            }
        }
        //全局发送
        if(NotifySendTypeEnum.ALL_USER.value.equals(cultivateNotifyDTO.getSendType())){
            ReaderMessageDto readerMessageDto=new ReaderMessageDto();
            readerMessageDto.setMessageId(cultivateNotify.getMessageId());
            readerMessageDto.setSendType(cultivateNotifyDTO.getSendType());
            readerMessageDto.setMessageType(cultivateNotifyDTO.getMessageType());
            Long accountSettingId = qrcodeSceneConsr.getAccountSettingIdByAgentId(cultivateNotify.getAgentId());
            readerMessageDto.setOfficialAccountsId(accountSettingId);
            readerConsr.sendNotifyMiniUser(readerMessageDto);
        }
        //用户画像发送
        if (NotifySendTypeEnum.USER_PROFILE.value.equals(cultivateNotifyDTO.getSendType())) {
            List<Long> wechatUserIds = readerConsr.getWechatUserIdsByUserProfile(cultivateNotifyDTO.getCityCode(), cultivateNotifyDTO.getStartTime(), cultivateNotifyDTO.getEndTime());
            if(ListUtils.isEmpty(wechatUserIds)){
                return;
            }
            for (int i = 0; i <= wechatUserIds.size() / SEND_BATCH_NUM; i++) {
                int beginIndex = i * SEND_BATCH_NUM;
                int endIndex = beginIndex + SEND_BATCH_NUM;
                if (i == (wechatUserIds.size() - 1)/SEND_BATCH_NUM){
                    endIndex = wechatUserIds.size();
                }
                List<Long> subList = wechatUserIds.subList(beginIndex, endIndex);
                List<CultivateNotifySend> cultivateNotifySendList=new ArrayList<>();
                if(!ListUtils.isEmpty(subList)){
                    for (Long wechatUserId : subList) {
                        CultivateNotifySend cultivateNotifySend=new CultivateNotifySend();
                        cultivateNotifySend.setMessageId(cultivateNotify.getMessageId());
                        cultivateNotifySend.setMessageType(cultivateNotifyDTO.getMessageType());
                        cultivateNotifySend.setSendType(cultivateNotifyDTO.getSendType());
                        cultivateNotifySend.setWechatUserId(wechatUserId);
                        cultivateNotifySend.setShowHome(cultivateNotifyDTO.getShowHome());
                        cultivateNotifySendList.add(cultivateNotifySend);
                    }
                    cultivateNotifySendDao.insert(cultivateNotifySendList);
                    sendAppletTemplateMessage(cultivateNotifySendList, cultivateNotify.getAgentId(), null);
                }
            }
        }
        // 按用户学龄段发送
        if (NotifySendTypeEnum.USER_GRADE.value.equals(cultivateNotifyDTO.getSendType())) {
            List<Long> wechatUserIds = readerConsr.getWechatUserIdsByGradeIds(cultivateNotifyDTO.getUserGradeLabelIds());
            if(ListUtils.isEmpty(wechatUserIds)){
                return;
            }
            for (int i = 0; i <= wechatUserIds.size() / SEND_BATCH_NUM; i++) {
                int beginIndex = i * SEND_BATCH_NUM;
                int endIndex = beginIndex + SEND_BATCH_NUM;
                if (i == (wechatUserIds.size() - 1)/SEND_BATCH_NUM){
                    endIndex = wechatUserIds.size();
                }
                List<Long> subList = wechatUserIds.subList(beginIndex, endIndex);
                List<CultivateNotifySend> cultivateNotifySendList=new ArrayList<>();
                if(!ListUtils.isEmpty(subList)){
                    for (Long wechatUserId : subList) {
                        CultivateNotifySend cultivateNotifySend=new CultivateNotifySend();
                        cultivateNotifySend.setMessageId(cultivateNotify.getMessageId());
                        cultivateNotifySend.setMessageType(cultivateNotifyDTO.getMessageType());
                        cultivateNotifySend.setSendType(cultivateNotifyDTO.getSendType());
                        cultivateNotifySend.setWechatUserId(wechatUserId);
                        cultivateNotifySend.setShowHome(cultivateNotifyDTO.getShowHome());
                        cultivateNotifySendList.add(cultivateNotifySend);
                    }
                    cultivateNotifySendDao.insert(cultivateNotifySendList);
                    sendAppletTemplateMessage(cultivateNotifySendList, cultivateNotify.getAgentId(), null);
                }
            }
        }
    }

    /**
     * 发送小程序模板消息
     * @param list
     * @param agentId
     * @param accountSettingId
     */
    @Override
    public void sendAppletTemplateMessage(List<CultivateNotifySend> list, Long agentId, Long accountSettingId) {
        AppletTemplateMessageDto appletTemplateMessage;
        Map<String, String> tempMap;
        if (null != agentId) {
           accountSettingId = qrcodeSceneConsr.getAccountSettingIdByAgentId(agentId);
        }
        for (CultivateNotifySend cultivateNotifySend : list) {
            if(cultivateNotifySend.getMessageType() == 1){ continue;}
            appletTemplateMessage = new AppletTemplateMessageDto();
            appletTemplateMessage.setAccountSettingId(accountSettingId);
            appletTemplateMessage.setWechatUserId(cultivateNotifySend.getWechatUserId());
            appletTemplateMessage.setTempalteTypeCode("xiaorui_unread_message_remind");
            appletTemplateMessage.setPage("pages/index/index");
            tempMap = Maps.newHashMap();
            tempMap.put("thing2", cultivateNotifySend.getTitle());
            tempMap.put("time3", DateUtils.getLongDateStr());
            tempMap.put("thing7", "您有一条新未读消息");
            appletTemplateMessage.setData(tempMap);
            templateConsr.sendAppletMessageQueue(appletTemplateMessage);
        }
    }


    @Override
    public PageBeanNew<CultivateNotifyPageDTO> listPage4CultivateNotify(SearchNotifyDTO searchNotifyDTO) {
        if(null==searchNotifyDTO || Objects.isNull(searchNotifyDTO.getNumPerPage()) || Objects.isNull(searchNotifyDTO.getPageNum())){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"分页参数有误！");
        }
        Map<String,Object> map=new HashMap<>();
        map.put("keyword",searchNotifyDTO.getKeyword());
        map.put("sendType",searchNotifyDTO.getSendType());
        map.put("messageType",searchNotifyDTO.getMessageType());
        map.put("agentId", searchNotifyDTO.getAgentId());
        PageBeanNew<CultivateNotifyPageDTO> pageBeanNew= cultivateNotifySendDao.listPageNew(new PageParam(searchNotifyDTO.getPageNum(), searchNotifyDTO.getNumPerPage()), map, "listPage4CultivateNotify");
        if(null==pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())){
            return new PageBeanNew<>(searchNotifyDTO.getPageNum(), searchNotifyDTO.getNumPerPage(),pageBeanNew.getTotalCount(), new ArrayList<>());
        }
        buildSendInfo(pageBeanNew.getRecordList());
        return pageBeanNew;
    }

    private void buildSendInfo(List<CultivateNotifyPageDTO> list) {
        List<Long> messageIds = list.stream().filter(a -> null != a.getMessageId()).map(a -> a.getMessageId()).distinct().collect(Collectors.toList());
        Map<Long, String> titleMap=new HashMap<>();
        Map<Long, List<CultivateNotifyItem>> itemMap=new HashMap<>();
        if(!ListUtils.isEmpty(messageIds)){
           /* List<CultivateNotify> cultivateNotifies = cultivateNotifyDao.getByIds(messageIds);
            titleMap= cultivateNotifies.stream().collect(Collectors.toMap(a -> a.getMessageId(), a -> a.getTitle(), (k1, k2) -> k2));*/
            List<CultivateNotifyItem> cultivateNotifyItems = cultivateNotifyItemDao.getByMessageIds(messageIds);
            itemMap= cultivateNotifyItems.stream().collect(Collectors.groupingBy(a -> a.getMessageId()));
        }
        List<CultivateNotifyItem> cultivateNotifyItems = new ArrayList<>();
        for (CultivateNotifyPageDTO cultivateNotifyPageDTO : list) {
         /*   if(MapUtils.isNotEmpty(titleMap) && titleMap.containsKey(cultivateNotifyPageDTO.getMessageId())){
                cultivateNotifyPageDTO.setTitle(titleMap.get(cultivateNotifyPageDTO.getMessageId()));
            }*/
            if(MapUtils.isNotEmpty(itemMap) && itemMap.containsKey(cultivateNotifyPageDTO.getMessageId())){
                cultivateNotifyPageDTO.setCultivateNotifyItems(itemMap.get(cultivateNotifyPageDTO.getMessageId()));
            }
            if(!ListUtils.isEmpty(cultivateNotifyPageDTO.getCultivateNotifyItems())){
                fillResource(cultivateNotifyPageDTO.getCultivateNotifyItems());
                cultivateNotifyItems.addAll(cultivateNotifyPageDTO.getCultivateNotifyItems());
            }
        }
        //填充资讯应用作品
        fillAppOrProduct4Notify(cultivateNotifyItems);
    }

    private void fillAppOrProduct4Notify(List<CultivateNotifyItem> cultivateNotifyItems) {
        if(ListUtils.isEmpty(cultivateNotifyItems)) {
            return;
        }
        // 获取资讯信息
        Map<Long, AppletNewsDTO> newsDTOMap = new HashMap<>();
        CompletableFuture<List<Long>> newsBannerFuture = CompletableFuture.supplyAsync(() -> cultivateNotifyItems.stream()
                .filter(x -> Objects.nonNull(x) && Objects.equals(x.getJumpType(), 3))
                .map(CultivateNotifyItem::getServeId).filter(Objects::nonNull).distinct()
                .collect(Collectors.toList())).whenComplete((list, throwable) -> {
            if (Objects.nonNull(throwable)) {
                log.error("[fillServeInfo] banner 图填充资讯信息失败，err：{}", throwable.getMessage(), throwable);
            } else {
                if (CollUtil.isEmpty(list)){
                    return;
                }
                Map<Long, AppletNewsDTO> dtoMap = appletNewsBiz.getByIds(list);
                newsDTOMap.putAll(Objects.nonNull(dtoMap) ? dtoMap : new HashMap<>());
            }
        });

        // 获取应用信息
        Map<Long, AppDto> appDtoMap = new HashMap<>();
        CompletableFuture<List<Long>> appBannerFuture = CompletableFuture.supplyAsync(() -> cultivateNotifyItems.stream()
                .filter(x -> Objects.nonNull(x) && Objects.equals(x.getServeType(), AppletRecordTypeEnum.APP.value))
                .map(CultivateNotifyItem::getServeId).collect(Collectors.toList())).whenComplete((list, throwable) -> {
            if (Objects.nonNull(throwable)) {
                log.error("[fillServeInfo] banner 图填充应用信息失败，err：{}", throwable.getMessage(), throwable);
            } else {
                Map<Long, AppDto> dtoMap = !ListUtils.isEmpty(list) ? appConsr.mapByIds4AuditPass(list) : new HashMap<>();
                appDtoMap.putAll(dtoMap);
            }
        });

        // 获取作品信息
        Map<Long, ProductDto> productDtoMap = new HashMap<>();
        CompletableFuture<List<Long>> productBannerFuture = CompletableFuture.supplyAsync(() -> cultivateNotifyItems.stream()
                .filter(x -> Objects.nonNull(x) && Objects.equals(x.getServeType(), AppletRecordTypeEnum.PRODUCT.value))
                .map(CultivateNotifyItem::getServeId).collect(Collectors.toList())).whenComplete((list, throwable) -> {
            if (Objects.nonNull(throwable)) {
                log.error("[fillServeInfo] banner 图填充作品信息失败，err：{}", throwable.getMessage(), throwable);
            } else {
                Map<Long, ProductDto> dtoMap = !ListUtils.isEmpty(list) ? productConsr.getProBasesByIds(list) : new HashMap<>();
                productDtoMap.putAll(dtoMap);
            }
        });

        // 获取问题
        Map<Long, AppletQuestion> questionMap = new HashMap<>();
        CompletableFuture<List<Long>> questionFuture = CompletableFuture.supplyAsync(() -> cultivateNotifyItems.stream()
                .filter(x -> Objects.nonNull(x) && Objects.equals(x.getServeType(), AppletRecordTypeEnum.RAISE_QUESTION.value))
                .map(CultivateNotifyItem::getServeId).distinct().collect(Collectors.toList())).whenComplete((list, throwable) -> {
            if (Objects.nonNull(throwable)) {
                log.error("[fillServeInfo]  填充小睿互助问题信息失败，err：{}", throwable.getMessage(), throwable);
            } else {
                Map<Long, AppletQuestion> appletQuestionMap = !ListUtils.isEmpty(list) ? readerConsr.getQuestionMap(list) : new HashMap<>();
                questionMap.putAll(appletQuestionMap);
            }
        });

        try {
            CompletableFuture.allOf(newsBannerFuture, appBannerFuture, productBannerFuture, questionFuture).get();
        } catch (InterruptedException | ExecutionException e) {
            log.error("[fillServeInfo] banner 填充信息失败，err：{}", e.getMessage(), e);
        }

        // 填充信息
        for (CultivateNotifyItem banner : cultivateNotifyItems) {
            if (Objects.nonNull(banner) && Objects.nonNull(banner.getServeId()) && Objects.nonNull(banner.getServeType())) {
                Integer serveType = banner.getServeType();
                if (Objects.equals(banner.getJumpType(), 3) && Objects.nonNull(newsDTOMap.get(banner.getServeId()))) {
                    banner.setNewsItem(newsDTOMap.get(banner.getServeId()));
                } else if (Objects.equals(serveType, AppletRecordTypeEnum.APP.value) && Objects.nonNull(appDtoMap.get(banner.getServeId()))) {
                    AppDto appDto = appDtoMap.get(banner.getServeId());
                    String resultLinkUrl = null;
                    if (Objects.nonNull(appDto.getChannelId())) {
                        AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(appDto.getChannelId());
                        // 根据 APP 拼接 linkUrl
                        String linkUrl = ServeLinkUtils.getServeLink("APP", appDto.getTypeCode(), appDto.getAppId().toString(),
                                appDto.getSceneCode(), appDto.getChannelId().toString(), appDto.getCreatedUser().toString(), null);
                        if (Objects.nonNull(accountSettingDto)) {
                            resultLinkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, linkUrl);
                        }
                    }
                    ServeItemInfoDTO build = ServeItemInfoDTO.builder().serveId(appDto.getAppId()).serveType(serveType)
                            .serveName(appDto.getTitle()).servePic(appDto.getSquareImg()).transverseImg(appDto.getTransverseImg())
                            .resultUrl(resultLinkUrl).hasThirdLink(StrUtil.isNotBlank(appDto.getTurnUrl()))
                            .serveTypeName(appDto.getTypeName()).build();
                    banner.setAppItem(build);
                } else if (Objects.equals(serveType, AppletRecordTypeEnum.PRODUCT.value) && Objects.nonNull(productDtoMap.get(banner.getServeId()))) {
                    ProductDto productDto = productDtoMap.get(banner.getServeId());
                    String resultLinkUrl = null;
                    if (Objects.nonNull(productDto.getChannelId())) {
                        AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(productDto.getChannelId());
                        if (null != accountSettingDto) {
                            resultLinkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, productDto.getTurnUrl());
                        }
                    }
                    ServeItemInfoDTO build = ServeItemInfoDTO.builder().serveId(productDto.getProductId()).serveType(serveType)
                            .serveName(productDto.getProductName()).servePic(productDto.getCoverImg()).transverseImg(productDto.getPicture1())
                            .resultUrl(resultLinkUrl).hasThirdLink(StrUtil.isNotBlank(productDto.getSkipUrl()))
                            .serveTypeName(productDto.getShortName()).build();
                    banner.setAppItem(build);
                } else if (Objects.equals(serveType, AppletRecordTypeEnum.RAISE_QUESTION.value) && Objects.nonNull(questionMap.get(banner.getServeId()))) {
                    if (MapUtils.isNotEmpty(questionMap) && null !=  questionMap.get(banner.getServeId())) {
                        banner.setAppletQuestion(questionMap.get(banner.getServeId()));
                    }
                }
            }
        }
    }

    @Override
    public PageBeanNew<MiniUserDto> listPage4SendUser(SearchSendUserDTO searchSendUserDTO) {
        if(null==searchSendUserDTO || null==searchSendUserDTO.getMessageId() || null==searchSendUserDTO.getCurrentPage() || null==searchSendUserDTO.getNumPerPage()){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数有误！");
        }
        Integer count = cultivateNotifySendDao.getSendUserCount(searchSendUserDTO.getMessageId());
        if(count<=0){
            return new PageBeanNew<>(searchSendUserDTO.getCurrentPage(), searchSendUserDTO.getNumPerPage(), new ArrayList<>());
        }
        List<Long> sendUserIds = cultivateNotifySendDao.getSendUserIds(searchSendUserDTO.getMessageId(), searchSendUserDTO.getCurrentPage(), searchSendUserDTO.getNumPerPage());
        List<MiniUserDto> list = readerConsr.getSendUserInfo(sendUserIds);
        return new PageBeanNew<>(searchSendUserDTO.getCurrentPage(), searchSendUserDTO.getNumPerPage(),count,list);
    }

    @Override
    public PageBeanNew<AdviserBookInfoDTO> listPage4SearchBook(SearchSendUserDTO searchSendUserDTO) {
        if(null==searchSendUserDTO  || null==searchSendUserDTO.getCurrentPage() || null==searchSendUserDTO.getNumPerPage()){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"参数有误！");
        }
        Integer count = searchRecordDao.getBookSearchCount(searchSendUserDTO.getKeyword());
        if(count<=0){
            return new PageBeanNew<>(searchSendUserDTO.getCurrentPage(), searchSendUserDTO.getNumPerPage(), new ArrayList<>());
        }
        List<AdviserBookInfoDTO> infos = searchRecordDao.getBookSearchIds(searchSendUserDTO.getKeyword(),searchSendUserDTO.getCurrentPage(), searchSendUserDTO.getNumPerPage());
        //Map<Long, AdviserBookInfoDTO> adviserBookInfoDTOMap = infos.stream().collect(Collectors.toMap(a -> a.getBookId(), a -> a, (k1, k2) -> k2));
        List<Long> adviserIds = infos.stream().filter(s -> s.getAdviserId() != null).map(AdviserBookInfoDTO::getAdviserId).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> adviserMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        for (AdviserBookInfoDTO dto : infos) {
            if (!MapUtils.isEmpty(adviserMap) && null != dto.getAdviserId() && adviserMap.containsKey(dto.getAdviserId())) {
                AdviserBaseInfoDto adviserBaseInfoDto = adviserMap.get(dto.getAdviserId());
                if (null != adviserBaseInfoDto){
                    dto.setAdviserName(adviserBaseInfoDto.getPartyName());
                    dto.setAgentName(adviserBaseInfoDto.getAgentName());
                }
            }
        }
        return  new PageBeanNew<>(searchSendUserDTO.getCurrentPage(), searchSendUserDTO.getNumPerPage(),count, infos);
    }

    @Override
    public void batchSendMiniUser(List<CultivateNotifySend> list) {
        if (ListUtils.isEmpty(list)){
            return;
        }
        cultivateNotifySendDao.insert(list);
        CultivateNotify cultivateNotify = cultivateNotifyDao.getById(list.get(0).getMessageId());
        if (null == cultivateNotify){
            return;
        }
        this.sendAppletTemplateMessage(list, cultivateNotify.getAgentId(), null);
    }

    @Override
    public void sendAppletUserNotify(List<CultivateNotifySend> list) {
        if (ListUtils.isEmpty(list)){
            return;
        }
        cultivateNotifySendDao.insert(list);
        //发送模板消息
        sendAppletTemplateMessage(list, null, BookProps.getMiniOfficialAccountsId());
    }

    @Override
    @ParamLog("小睿互助新增站内信")
    public Long createNotify4Question(AppletNotifySendDTO newSendDTO) {
        if (null == newSendDTO || null == newSendDTO.getSendType() || null == newSendDTO.getMessageType() || StringUtil.isEmpty(newSendDTO.getTitle())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"新建站内信消息参数为空");
        }
        CultivateNotify cultivateNotify=new CultivateNotify();
        cultivateNotify.setMessageType(newSendDTO.getMessageType());
        cultivateNotify.setTitle(newSendDTO.getTitle());
        cultivateNotify.setSendType(newSendDTO.getSendType());
        cultivateNotify.setAgentId(0L);
        cultivateNotifyDao.insert(cultivateNotify);
        CultivateNotifyItem cultivateNotifyItem = new CultivateNotifyItem();
        cultivateNotifyItem.setMessageId(cultivateNotify.getMessageId());
        cultivateNotifyItem.setContentType(4);
        cultivateNotifyItem.setServeId(newSendDTO.getFromId());
        if(newSendDTO.getServeType()!=null){
            cultivateNotifyItem.setServeType(newSendDTO.getServeType());
        }else {
            cultivateNotifyItem.setServeType(AppletRecordTypeEnum.RAISE_QUESTION.value);
        }
        cultivateNotifyItemDao.insert(Lists.newArrayList(cultivateNotifyItem));
        return cultivateNotify.getMessageId();
    }

    @Override
    @ParamLog("获取最近消息列表")
    public PageBeanNew<CultivateNotifyDTO> getLatestNotifyList(Long wechatUserId, Integer currentPage, Integer numPerPage) {
        Map<String,Object> map=new HashMap<>();
        map.put("wechatUserId",wechatUserId);
        PageBeanNew<CultivateNotifyDTO> pageBeanNew= cultivateNotifySendDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getNotifyListByType");
        List<CultivateNotifyItem> cultivateNotifyItemList = new ArrayList<>();
        for (CultivateNotifyDTO cultivateNotifyDTO:pageBeanNew.getRecordList()) {
            List<CultivateNotifyItem> list1=cultivateNotifyItemDao.getNotifyItemsByMessageId(cultivateNotifyDTO.getMessageId());
            fillResource(list1);
            cultivateNotifyDTO.setCultivateNotifyItems(list1);
            cultivateNotifyItemList.addAll(list1);
        }
        //填充资讯应用作品问题
        fillAppOrProduct4Notify(cultivateNotifyItemList);
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
            //批量更新消息已读未读
            if (null != pageBeanNew && !ListUtils.isEmpty(pageBeanNew.getRecordList())) {
                List<Long> messageIds = pageBeanNew.getRecordList().stream().map(e -> e.getMessageId()).collect(Collectors.toList());
                cultivateNotifySendDao.updateIsRead(wechatUserId,messageIds);
            }
        });
        return pageBeanNew;
    }

    @Override
    public Long createNotify4App(AppletNotifySendDTO newSendDTO) {
        if (null == newSendDTO || null == newSendDTO.getSendType() || null == newSendDTO.getMessageType() || StringUtil.isEmpty(newSendDTO.getTitle())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"新建站内信消息参数为空");
        }
        CultivateNotify cultivateNotify=new CultivateNotify();
        cultivateNotify.setMessageType(newSendDTO.getMessageType());
        cultivateNotify.setTitle(newSendDTO.getTitle());
        cultivateNotify.setSendType(newSendDTO.getSendType());
        cultivateNotify.setAgentId(0L);
        cultivateNotifyDao.insert(cultivateNotify);
        CultivateNotifyItem cultivateNotifyItem = new CultivateNotifyItem();
        cultivateNotifyItem.setMessageId(cultivateNotify.getMessageId());
        cultivateNotifyItem.setContentType(4);
        cultivateNotifyItem.setServeId(newSendDTO.getFromId());
        cultivateNotifyItem.setServeType(AppletRecordTypeEnum.APP.value);
        cultivateNotifyItem.setExtJson(newSendDTO.getExtJson());
        cultivateNotifyItemDao.insert(Lists.newArrayList(cultivateNotifyItem));
        return cultivateNotify.getMessageId();
    }

    @Override
    public void clearExpireNotifies() {
        cultivateNotifySendDao.clearExpireNotifies();
    }

    @Override
    public Long sendNotifyToUser(NotifySendDTO notifySendDTO) {
        if (null == notifySendDTO || null == notifySendDTO.getSendType() || null == notifySendDTO.getMessageType() || StringUtil.isEmpty(notifySendDTO.getTitle()) || null == notifySendDTO.getWechatUserId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"新建站内信消息参数为空");
        }
        CultivateNotify cultivateNotify=new CultivateNotify();
        cultivateNotify.setMessageType(notifySendDTO.getMessageType());
        cultivateNotify.setTitle(notifySendDTO.getTitle());
        cultivateNotify.setSendType(notifySendDTO.getSendType());
        cultivateNotify.setAgentId(0L);
        cultivateNotifyDao.insert(cultivateNotify);
        Long messageId = cultivateNotify.getMessageId();
        if(!ListUtils.isEmpty(notifySendDTO.getNotifyItemDTOS())) {
            List<CultivateNotifyItem> items = new ArrayList<>();
            for (NotifyItemDTO itemDTO: notifySendDTO.getNotifyItemDTOS()){
                CultivateNotifyItem item = new CultivateNotifyItem();
                BeanUtils.copyProperties(itemDTO,item);
                item.setMessageId(messageId);
                items.add(item);
            }
            cultivateNotifyItemDao.insert(items);
        }
        //发给用户
        CultivateNotifySend notifySend = new CultivateNotifySend();
        notifySend.setMessageId(messageId);
        notifySend.setWechatUserId(notifySendDTO.getWechatUserId());
        notifySend.setSendType(notifySendDTO.getSendType());
        notifySend.setMessageType(notifySendDTO.getMessageType());
        cultivateNotifySendDao.insert(notifySend);
        return messageId;
    }

    @Override
    @ParamLog("最近三条未读首页弹窗消息")
    public List<CultivateNotifyDTO> getLastNoReadNotify(Long wechatUserId) {
        List<Long> messageIds = cultivateNotifySendDao.getLastNoReadNotify(wechatUserId);
        if(ListUtils.isEmpty(messageIds)){
            return new ArrayList<>();
        }

        List<CultivateNotifyItem> list=cultivateNotifyItemDao.getByMessageIds(messageIds);
        fillResource(list);
        fillAppOrProduct4Notify(list);
        Map<Long, List<CultivateNotifyItem>> cultivateNotifyItemMap = list.stream().collect(Collectors.groupingBy(CultivateNotifyItem::getMessageId));
        List<CultivateNotify> cultivateNotifyList = cultivateNotifyDao.getByIds(messageIds);
        List<CultivateNotifyDTO> cultivateNotifyDTOList = new ArrayList<>();
        cultivateNotifyList.stream().forEach(e -> {
            CultivateNotifyDTO notifyDTO= new CultivateNotifyDTO();
            BeanUtils.copyProperties(e, notifyDTO);
            notifyDTO.setCultivateNotifyItems(cultivateNotifyItemMap.get(e.getMessageId()));
            cultivateNotifyDTOList.add(notifyDTO);
        });
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
            //批量更新消息已读未读
            cultivateNotifySendDao.updateIsRead(wechatUserId,messageIds);
            // 更新之前的所有未读消息都不显示到主页
            cultivateNotifySendDao.updateShowHome(wechatUserId);
        });

        return cultivateNotifyDTOList;
    }
}
