package com.cool.store.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dto.notice.CommonDTO;
import com.cool.store.dto.notice.MessageTemplateCountDTO;
import com.cool.store.dto.notice.NoticeDTO;
import com.cool.store.dto.store.AuthStoreUserDTO;
import com.cool.store.dto.store.StoreAreaDTO;
import com.cool.store.dto.wechat.ServiceAccountOpenIdDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.notice.*;
import com.cool.store.enums.wechat.WechatTemplateDetailEnum;
import com.cool.store.enums.wechat.WechatTemplateEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.StoreGroupMappingMapper;
import com.cool.store.mapper.StoreMapper;
import com.cool.store.request.notice.*;
import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.service.MessageTemplateService;
import com.cool.store.service.StoreService;
import com.cool.store.service.wechat.WechatTemplateService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.notice.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @Author suzhuhong
 * @Date 2025/7/25 9:59
 * @Version 1.0
 */
@Service
@Slf4j
public class MessageTemplateServiceImpl implements MessageTemplateService {


    @Resource
    MessageTemplateDAO messageTemplateDAO;
    @Resource
    StoreMapper storeMapper;
    @Resource
    RegionDao RegionDao;
    @Resource
    StoreGroupMappingMapper storeGroupMappingMapper;
    @Resource
    StoreService storeService;
    @Resource
    StoreMessageDAO storeMessageDAO;
    @Resource
    EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    MatterConfigDAO matterConfigDAO;
    @Resource
    WechatTemplateService wechatTemplateService;
    @Resource
    RedisUtilPool redisUtilPool;
    @Resource
    TaskExecutor noticeThreadPool;
    @Resource
    HyPartnerUserInfoDAO hyPartnerUserInfoDAO;
    @Resource
    MessageIssueService messageIssueService;



    @Override
    public Boolean addMessageTemplate(MessageTemplateAddRequest request, LoginUserInfo user) {
        MessageTemplateDO messageTemplateDO = new MessageTemplateDO();
        BeanUtils.copyProperties(request, messageTemplateDO);
        messageTemplateDO.setMessageCode(getMessageTemplateCode());
        messageTemplateDO.setMatterType(MatterTypeEnum.NOTICE.getCode());
        messageTemplateDO.setCreateUserId(user.getUserId());
        messageTemplateDO.setSystemSource("CRM");
        messageTemplateDAO.insert(messageTemplateDO);
        return Boolean.TRUE;
    }

    public String getMessageTemplateCode() {
        //当前日期
        String today = CoolDateUtils.getTodayMillis();
        return "16" + today + String.format("%04d", ThreadLocalRandom.current().nextInt(100));
    }

    @Override
    public Boolean editMessageTemplate(MessageTemplateAddRequest request, LoginUserInfo user) {
        if (request.getId()==null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR);
        }
        MessageTemplateDO messageTemplateDO = messageTemplateDAO.getById(request.getId());
        //只有待发布状态能编辑
        if (messageTemplateDO.getPublishStatus()!=0){
            throw new ServiceException(ErrorCodeEnum.MESSAGE_TEMPLATE_NOT_SUPPORT_EDIT);
        }
        BeanUtils.copyProperties(request, messageTemplateDO);
        messageTemplateDO.setUpdaterUserId(user.getUserId());
        messageTemplateDAO.update(messageTemplateDO);
        return Boolean.TRUE;
    }

    @Override
    public MessageTemplateDetailVO getMessageTemplateDetail(Long id) {
        MessageTemplateDetailVO messageTemplateDetailVO = new MessageTemplateDetailVO();
        MessageTemplateDO messageTemplateDO = messageTemplateDAO.getById(id);
        if(messageTemplateDO==null){
            return messageTemplateDetailVO;
        }
        BeanUtils.copyProperties(messageTemplateDO, messageTemplateDetailVO);
        messageTemplateDetailVO.setUserInfoList(JSONObject.parseArray(messageTemplateDO.getHandlePersonInfo(), CommonDTO.class));
        messageTemplateDetailVO.setStoreInfoList(JSONObject.parseArray(messageTemplateDO.getStoreInfo(), CommonDTO.class));
        List<MessageTemplateCountDTO> messageTemplateCountList = storeMessageDAO.getMessageTemplateCountList(Arrays.asList(messageTemplateDO.getId()));

        if (CollectionUtils.isNotEmpty(messageTemplateCountList)){
            messageTemplateDetailVO.setTotalNum(messageTemplateCountList.get(0).getTotalStoreCount());
            messageTemplateDetailVO.setHandleNum(messageTemplateCountList.get(0).getProcessedStoreCount());
        }
        return messageTemplateDetailVO;
    }

    @Override
    public Boolean batchDeleteMessageTemplate(BatchDeletedRequest request, LoginUserInfo user) {
        List<MessageTemplateDO> list = messageTemplateDAO.getByIds(request.getIds());
        //校验是否都是未发布状态
        if (list.stream().anyMatch(x -> x.getPublishStatus()!= PublishStatusEnum.UNPUBLISHED.getCode())){
            throw new ServiceException(ErrorCodeEnum.MESSAGE_TEMPLATE_NOT_SUPPORT_DELETED);
        }
        messageTemplateDAO.updateDeleteStatusBatch(request.getIds(),user.getUserId());
        return Boolean.TRUE;
    }



    @Override
    public Boolean batchPublishMessageTemplate(BatchPublishRequest request, String userId) {
        log.info("batchPublishMessageTemplate:{}",JSONObject.toJSONString(request));
        if (CollectionUtils.isEmpty(request.getIds())||CollectionUtils.isEmpty(request.getStoreInfoList())||CollectionUtils.isEmpty(request.getUserInfoList())){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        List<MessageTemplateDO> list = messageTemplateDAO.getByIds(request.getIds());
        //过滤 只保留未发布的
        list = list.stream().filter(x -> PublishStatusEnum.UNPUBLISHED.getCode().equals(x.getPublishStatus())).collect(Collectors.toList());

        if (CollUtil.isEmpty(list)){
            log.info("未找到待发布消息模板");
            return Boolean.TRUE;
        }

        List<String> lockKeys = list.stream()
                .map(x -> "msg_template_publish:" + x.getId())
                .collect(Collectors.toList());

        boolean allLocksAcquired = tryAcquireLocks(lockKeys);
        if (!allLocksAcquired) {
            log.warn("存在正在发布的模板，本次操作取消。模板IDs: {}", JSONObject.toJSONString(lockKeys));
            throw new ServiceException(ErrorCodeEnum.MESSAGE_PUBLISH);
        }
        List<MessageTemplateDO> finalList = list;
        noticeThreadPool.execute(() -> {
            syncPublish(request, userId, finalList, lockKeys);
        });
        return Boolean.TRUE;
    }

    public Boolean syncPublish(BatchPublishRequest request, String userId, List<MessageTemplateDO> list,List<String> lockKeys){
        try {
            List<StoreAreaDTO> storeAreaDTOS = getStoreRange(request.getStoreInfoList());
            List<String> storeIds = storeAreaDTOS.stream().map(StoreAreaDTO::getStoreId).collect(Collectors.toList());
            Map<String, List<String>> authUser = getAuthUser(request.getUserInfoList(), storeIds);
            List<StoreMessageDO> realtimeMessageList = new ArrayList<>();
            list.stream().forEach(x -> {
                List<StoreMessageDO> result = new ArrayList<>();
                storeAreaDTOS.forEach(y->{
                    if (CollectionUtils.isEmpty(authUser.get(y.getStoreId()))){
                        log.info("当前门店没有人员 门店名称：{}",y.getStoreName());
                        return;
                    }
                    StoreMessageDO storeMessageDO = new StoreMessageDO();
                    storeMessageDO.setStoreId(y.getStoreId());
                    storeMessageDO.setStoreName(y.getStoreName());
                    storeMessageDO.setStoreCode(y.getStoreCode());
                    storeMessageDO.setMessageTemplateId(x.getId());
                    storeMessageDO.setReadStatus(ReadStatusEnum.UNREAD.getCode());
                    storeMessageDO.setReadTime(new Date());
                    storeMessageDO.setProcessStatus(ProcessStatusEnum.UNTREATED.getCode());
                    storeMessageDO.setProcessTime(new Date());
                    String userIdStr = authUser.get(y.getStoreId()).stream().collect(Collectors.joining(","));
                    storeMessageDO.setOperatorList(userIdStr);
                    result.add(storeMessageDO);
                });
                storeMessageDAO.batchInsert(result);
                if (MatterTypeEnum.REALTIME.getCode().equals(request.getMatterType())) {
                    realtimeMessageList.addAll(result);
                }
            });

            //存在第一个成功 第二个失败 会有问题 todo
            List<Long> updateIds = list.stream().map(MessageTemplateDO::getId).collect(Collectors.toList());
            messageTemplateDAO.batchUpdateStoreInfoAndUserInfo(updateIds,
                    JSONObject.toJSONString(request.getStoreInfoList()),
                    JSONObject.toJSONString(request.getUserInfoList()),
                    userId);

            //发送通知
            Set<String> userIds = authUser.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());

            //分批 查询用户信息
            List<String> openIdList = new ArrayList<>();
            Lists.partition(new ArrayList<>(userIds), 100).forEach(x->{
                List<EnterpriseUserDO> userInfoByUserIds = enterpriseUserDAO.getUserInfoByUserIds(x);
                //取出用户的手机号，过滤掉空的手机号
                List<String> mobileList = userInfoByUserIds.stream().filter(user -> StringUtils.isNotBlank(user.getMobile())).map(EnterpriseUserDO::getMobile).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(mobileList)){
                    List<ServiceAccountOpenIdDTO> serviceAccountOpenIdDTOS = hyPartnerUserInfoDAO.selectLastBindRecord(mobileList);
                    if (CollectionUtils.isNotEmpty(serviceAccountOpenIdDTOS)){
                        //服务号ID
                        openIdList.addAll(serviceAccountOpenIdDTOS.stream().map(ServiceAccountOpenIdDTO::getServiceAccountOpenId).collect(Collectors.toList()));
                    }

                }
            });

            MessageTemplateDO messageTemplateDO = list.get(0);
            Map<String, Object> data = new HashMap<>();
            data.put(WechatTemplateDetailEnum.THING6.getCode(), messageTemplateDO.getMessageTitle());
            data.put(WechatTemplateDetailEnum.TIME33.getCode(), DateUtils.parseDateToStr(DateUtils.SPECIAL_DATE_START, new Date()));
            data.put(WechatTemplateDetailEnum.CHARACTER_STRING14.getCode(), messageTemplateDO.getMessageCode());
            openIdList.forEach(x->{
                wechatTemplateService.sendMiniAppTemplate(x, WechatTemplateEnum.NEW_QUESTION_NOTICE,data,"pages/notification/index");
            });
            // 即时消息下发
            messageIssueService.issueMessage(realtimeMessageList);
        } catch (Exception e) {
            log.info("发布流程异常 e:{}",e.getMessage());
        } finally {
            releaseLocks(lockKeys);
            log.info("发布流程结束，已释放Redis锁");
        }
        return Boolean.TRUE;
    }




    /**
     * 尝试获取所有Redis锁
     */
    private boolean tryAcquireLocks(List<String> lockKeys) {
        boolean allSuccess = true;
        List<String> acquiredLocks = new ArrayList<>();

        for (String lockKey : lockKeys) {
            try {
                // 设置锁，过期时间设为5分钟，防止死锁
                Boolean  success = redisUtilPool.setNxExpire(lockKey, "locking",1000*60*5);
                if (success != null && success) {
                    acquiredLocks.add(lockKey);
                } else {
                    log.warn("获取Redis锁失败: {}", lockKey);
                    allSuccess = false;
                    break;
                }
            } catch (Exception e) {
                log.error("获取Redis锁异常: {}", lockKey, e);
                allSuccess = false;
                break;
            }
        }

        // 如果任何一个锁获取失败，释放之前已经获取的锁
        if (!allSuccess) {
            releaseLocks(acquiredLocks);
        }

        return allSuccess;
    }

    /**
     * 释放Redis锁
     */
    private void releaseLocks(List<String> lockKeys) {
        if (CollUtil.isEmpty(lockKeys)) {
            return;
        }
        for (String lockKey : lockKeys) {
            try {
                redisUtilPool.delKey(lockKey);
                log.debug("释放Redis锁成功: {}", lockKey);
            } catch (Exception e) {
                log.error("释放Redis锁异常: {}", lockKey, e);
            }
        }
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Boolean> thirdMatterHandle(ThirdMatterRequest thirdMatterRequest) {
        log.info("thirdMatterHandle request：{}", JSONObject.toJSONString(thirdMatterRequest));
        //第三方事项处理
        MatterConfigDO matterConfig = matterConfigDAO.getById(thirdMatterRequest.getMatterConfigId());
        if (matterConfig==null||matterConfig.getStatus()==0){
            return ApiResponse.error(ErrorCodeEnum.CONFIG_NOT_EXIST);
        }
        //封装事项模版
        MessageTemplateDO messageTemplateDO = new MessageTemplateDO();
        messageTemplateDO.setMessageCode(getMessageTemplateCode());
        messageTemplateDO.setModuleCode(matterConfig.getModuleCode());
        messageTemplateDO.setMatterType(matterConfig.getMatterType());
        messageTemplateDO.setMessageTitle(thirdMatterRequest.getMatterTitle());
        messageTemplateDO.setSystemSource(matterConfig.getSystemSource());
        messageTemplateDO.setProcessType(thirdMatterRequest.getProcessType());
        messageTemplateDO.setRemindType(thirdMatterRequest.getRemindType());
        if (RemindTypeEnum.STAGE_REMINDER.getCode().equals(thirdMatterRequest.getRemindType())){
            messageTemplateDO.setRemindStartTime(thirdMatterRequest.getRemindStartTime());
            messageTemplateDO.setRemindEndTime(thirdMatterRequest.getRemindEndTime());
        }
        messageTemplateDO.setDeadline(thirdMatterRequest.getDeadline());
        messageTemplateDO.setTodayTask(thirdMatterRequest.getTodayTask());
        messageTemplateDO.setMessageImage(thirdMatterRequest.getMessageImage());
        messageTemplateDO.setPublishStatus(PublishStatusEnum.UNPUBLISHED.getCode());
        messageTemplateDO.setJumpType(matterConfig.getJumpType());
        messageTemplateDO.setJumpUrl(matterConfig.getJumpUrl());
        messageTemplateDO.setHandleKeyword(thirdMatterRequest.getHandleKeyword());

        if (MatterTypeEnum.LOGISTICS.getCode().equals(matterConfig.getMatterType())){
            SceneEnum scene = SceneEnum.getByCode(thirdMatterRequest.getSceneCode());
            messageTemplateDO.setMessageImage(scene.getScenePicture());
            //物流直接使用传过来的地址
            messageTemplateDO.setJumpUrl(thirdMatterRequest.getJumpUrl());
        }
        //如果是盘点 截止日期去当天
        if (MatterTypeEnum.INVENTORY.getCode().equals(matterConfig.getMatterType())){
            messageTemplateDO.setDeadline(new Date());
        }
        String storeInfo = matterConfig.getDefaultStoreInfo();
        String userInfo = matterConfig.getDefaultHandlePersonInfo();
        //门店
        if (CollectionUtils.isNotEmpty(thirdMatterRequest.getShopCodeList())){
            log.info("shopCodeList:{}",JSONObject.toJSONString(thirdMatterRequest.getShopCodeList()));
            List<StoreDO> storeNumByStoreCodes = storeMapper.getStoreNumByStoreCodes(thirdMatterRequest.getShopCodeList());
            if (CollectionUtils.isNotEmpty(storeNumByStoreCodes)){
                //组装成门店信息
                List<CommonDTO> storeList = new ArrayList<>();
                storeNumByStoreCodes.forEach(x -> {
                    CommonDTO store = new CommonDTO("store", x.getStoreId(), x.getStoreName());
                    storeList.add(store);
                });
                storeInfo = JSONObject.toJSONString(storeList);
            }
        }
        //人员
        List<EnterpriseUserDO> userInfoByUserMobileList = enterpriseUserDAO.getUserInfoByUserMobileList(thirdMatterRequest.getMobileList());
        if (CollectionUtils.isNotEmpty(userInfoByUserMobileList)){
            //组装人员信息
            List<CommonDTO> userList = new ArrayList<>();
            userInfoByUserMobileList.forEach(x -> {
                CommonDTO user = new CommonDTO("person", x.getUserId(), x.getName());
                userList.add(user);
            });
            userInfo = JSONObject.toJSONString(userList);
        }
        Boolean publishFlag = Boolean.TRUE;
        //校验是否发布
        if (StringUtils.isEmpty(userInfo)|| StringUtils.isEmpty(storeInfo)){
            publishFlag = Boolean.FALSE;
        }
        messageTemplateDO.setCreateUserId("system");
        if (!publishFlag){
            //如果不发布 保存门店人员信息
            messageTemplateDO.setStoreInfo(storeInfo);
            messageTemplateDO.setHandlePersonInfo(userInfo);
        }
        messageTemplateDAO.insert(messageTemplateDO);
        //调用发布
        if (publishFlag){
            //开始计算人员门店
            BatchPublishRequest batchPublishRequest = new BatchPublishRequest();
            batchPublishRequest.setIds(Arrays.asList(messageTemplateDO.getId()));
            batchPublishRequest.setStoreInfoList(JSONObject.parseArray(storeInfo, CommonDTO.class));
            batchPublishRequest.setUserInfoList(JSONObject.parseArray(userInfo, CommonDTO.class));
            batchPublishRequest.setMatterType(matterConfig.getMatterType());
            try {
                batchPublishMessageTemplate(batchPublishRequest,"");
            } catch (ServiceException e) {
                return new ApiResponse(e.getErrorCode(), e.getErrorMessage(), null);
            }
            return ApiResponse.success(Boolean.TRUE);
        }
        return ApiResponse.success(Boolean.TRUE);
    }


    @Override
    public PageInfo<NoticeDTO> getMessageTemplateList(MessageTemplateQueryRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<NoticeDTO> list = messageTemplateDAO.getMessageTemplateList(request);
        if (CollectionUtils.isEmpty(list)){
            return new PageInfo<>(list);
        }
        //将列表中的创建人id与发布人id 放到同一个list 去重
        Set<String> userIdSet = new HashSet<>();
        list.forEach(notice -> {
            if (notice.getCreateUserId() != null) {
                userIdSet.add(String.valueOf(notice.getCreateUserId()));
            }
            if (notice.getPublishUserId() != null) {
                userIdSet.add(String.valueOf(notice.getPublishUserId()));
            }
        });

        List<String> uniqueUserIds = new ArrayList<>(userIdSet);
        List<EnterpriseUserDO> userInfoByUserIds = enterpriseUserDAO.getUserInfoByUserIds(uniqueUserIds);
        Map<String, String> userMap = userInfoByUserIds.stream().collect(Collectors.toMap(EnterpriseUserDO::getUserId, EnterpriseUserDO::getName));


        List<Long>  templateIds = list.stream().map(NoticeDTO::getId).collect(Collectors.toList());
        List<MessageTemplateCountDTO> messageTemplateCountList = storeMessageDAO.getMessageTemplateCountList(templateIds);
        //根据模板id查询 转为map
        Map<Long, MessageTemplateCountDTO> messageTemplateCountMap = messageTemplateCountList.stream().collect(Collectors.toMap(MessageTemplateCountDTO::getTemplateId, x -> x));
        list.forEach(x -> {
            x.setCreateUserName(userMap.get(x.getCreateUserId()));
            x.setPublishUserName(userMap.get(x.getPublishUserId()));
            MessageTemplateCountDTO count = messageTemplateCountMap.getOrDefault(x.getId(), new MessageTemplateCountDTO());
            x.setHandleNum(count.getProcessedStoreCount());
            x.setTotalNum(count.getTotalStoreCount());
        });
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<StoreMessageDetailVO> getStoreMessageListByTemplateId(StoreMessageRequest request) {
        PageHelper.startPage(request.getPageNum(),request.getPageSize());
        List<StoreMessageDO> list = storeMessageDAO.getStoreMessageList(request);
        if (CollectionUtils.isEmpty(list)){
            return new PageInfo<>();
        }

        List<StoreMessageDetailVO> result = new ArrayList<>();
        list.forEach(x->{
            StoreMessageDetailVO storeMessageDetailVO = new StoreMessageDetailVO();
            BeanUtils.copyProperties(x,storeMessageDetailVO);
            result.add(storeMessageDetailVO);
        });
        PageInfo storeMessageDOPageInfo = new PageInfo<>(list);
        storeMessageDOPageInfo.setList(result);
        return storeMessageDOPageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchRevokeNotice(BatchRevokeRequest request, LoginUserInfo user) {
        log.info("batchRevokeNotice request:{}", JSONObject.toJSONString(request));
        List<Long> ids = request.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        //将消息置为撤销状态
        messageTemplateDAO.batchUpdatePublishStatus(ids);
        //将门店未处理的消息置为撤销状态 已处理和撤销的保持不变
        storeMessageDAO.batchRevoke(ids, user.getUserId(), user.getName());
        return Boolean.TRUE;
    }

    @Override
    public Boolean revokeById(Long id, LoginUserInfo user) {
        //查询门店消息
        StoreMessageDO storeMessage = storeMessageDAO.getById(id);
        if (storeMessage == null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        if (RevokeStatusEnum.REVOKE.getCode().equals(storeMessage.getRevokeStatus())){
            throw new ServiceException(ErrorCodeEnum.STORE_MESSAGE_REVOKE);
        }
        if (ProcessStatusEnum.PROCESSED.getCode().equals(storeMessage.getProcessStatus())){
            throw new ServiceException(ErrorCodeEnum.STORE_MESSAGE_HANDLED);
        }
        storeMessageDAO.revokeById(id,user.getUserId(),user.getName());
        return Boolean.TRUE;
    }

    @Override
    public List<ModuleAndMatterVO> getModuleList(String storeId,String mobile) {
        List<ModuleAndMatterVO> moduleAndMatterList = ModuleAndMatterVO.getModuleAndMatterList();
        EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(mobile);
        if (enterpriseUserDO == null){
            enterpriseUserDO = new EnterpriseUserDO();
        }
        List<ModuleAndMatterVO> list= new ArrayList<>();
        EnterpriseUserDO finalEnterpriseUserDO = enterpriseUserDO;
        moduleAndMatterList.forEach(x->{
            Integer integer = storeMessageDAO.queryStoreModuleCount(storeId, finalEnterpriseUserDO.getUserId(), x.getModuleCode());
            if (integer > 0){
                list.add(x);
            }
        });
        return list;
    }

    @Override
    public PageInfo<StoreMessageVO> getStorePendingList(StoreMessagePendingRequest request) {
        if(request.getMobile()==null||StringUtils.isEmpty(request.getStoreId())){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(request.getMobile());
        if (enterpriseUserDO == null){
            return new PageInfo<>();
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<StoreMessageVO> storeMessageListByCondition = storeMessageDAO.getStoreMessageListByCondition(request.getStoreId(), request.getModuleCode(),
                request.getTodayTask(), request.getPendingFlag(), enterpriseUserDO.getUserId());
        return new PageInfo<>(storeMessageListByCondition);
    }

    @Override
    public MessageDetailVO getMessageDetail(Long id) {
        MessageDetailVO messageDetailVO = storeMessageDAO.getMessageDetail(id);
        if (messageDetailVO!=null&&messageDetailVO.getPublishUserId()!=null){
            EnterpriseUserDO userInfoById = enterpriseUserDAO.getUserInfoById(messageDetailVO.getPublishUserId());
            if (userInfoById != null){
                messageDetailVO.setPublishUserName(userInfoById.getName());
            }
        }
        return messageDetailVO;
    }

    @Override
    public Boolean readMessage(Long id, String mobile) {
        StoreMessageDO message = storeMessageDAO.getById(id);
        if (ProcessStatusEnum.PROCESSED.getCode().equals(message.getProcessStatus())){
            log.info("当前消息已读已处理：{}",JSONObject.toJSONString( message));
            return Boolean.TRUE;
        }
        message.setReadStatus(ProcessStatusEnum.PROCESSED.getCode());
        message.setReadTime(new Date());
        MessageTemplateDO template = messageTemplateDAO.getById(message.getMessageTemplateId());
        if (ProcessTypeEnum.READ.getCode().equals(template.getProcessType())){
            message.setProcessStatus(ProcessStatusEnum.PROCESSED.getCode());
            message.setProcessTime(new Date());
            EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(mobile);
            if (enterpriseUserDO != null){
                message.setActualOperatorId(enterpriseUserDO.getId());
                message.setActualOperatorName(enterpriseUserDO.getName());
            }
        }
        storeMessageDAO.update( message);
        return Boolean.TRUE;
    }

    @Override
    public Boolean handleMessage(Long id, String userName,String mobile) {
        log.info("handleMessage request:{}，处理人：{}", JSONObject.toJSONString(id), userName);
        StoreMessageDO message = storeMessageDAO.getById(id);
        if (message==null){
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        message.setProcessStatus(ProcessStatusEnum.PROCESSED.getCode());
        message.setProcessTime(new Date());
        EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(mobile);
        if (enterpriseUserDO != null){
            message.setActualOperatorId(enterpriseUserDO.getId());
            message.setActualOperatorName(enterpriseUserDO.getName());
        }
        storeMessageDAO.update( message);
        return Boolean.TRUE;
    }

    @Override
    public ApiResponse<Boolean> thirdHandleMessage(ThirdHandleMessageRequest request) {
        log.info("thirdHandleMessage request:{}", JSONObject.toJSONString(request));
        MessageTemplateDO message = messageTemplateDAO.getByKeyword(request.getHandleKeyword());
        if (message==null){
            return ApiResponse.error(ErrorCodeEnum.MESSAGE_NOT_EXIST);
        }
        if (!ProcessTypeEnum.HANDLE.getCode().equals(message.getProcessType())){
            return ApiResponse.error(ErrorCodeEnum.MESSAGE_NOT_HANDLED);
        }
        storeMessageDAO.batchUpdateHandle(message.getId(), request.getShopCodeList());
        return ApiResponse.success(Boolean.TRUE);
    }


    public Map<String, List<String>> getAuthUser(List<CommonDTO> personInfo, List<String> storeIds){
        if (CollectionUtils.isEmpty(personInfo)){
            return new HashMap<>();
        }
        List<String> personIds = personInfo.stream().filter(x -> TypeEnum.PERSON.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());
        List<String> positionIds = personInfo.stream().filter(x -> TypeEnum.POSITION.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());
        List<String> groupIdList = personInfo.stream().filter(x -> TypeEnum.USER_GROUP.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());
        List<String> regionIdList = personInfo.stream().filter(x -> TypeEnum.ORGANIZATION.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());
        //权限
        List<AuthStoreUserDTO> authStoreUserList = storeService.getStorePositionUserList(storeIds, positionIds, personIds, groupIdList, regionIdList);
        Map<String, List<String>> storeUserMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(authStoreUserList)) {
            storeUserMap = authStoreUserList.stream().collect(Collectors.toMap(AuthStoreUserDTO::getStoreId,
                    AuthStoreUserDTO::getUserIdList, (a, b) -> a));
        }
        return storeUserMap;
    }

    /**
     * 获取门店范围
     * @param commonDTOS
     * @return
     */
    private List<StoreAreaDTO> getStoreRange( List<CommonDTO> commonDTOS){
        List<String> regionIds = commonDTOS.stream().filter(x -> TypeEnum.REGION.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());

        List<RegionDO> regionDOsByRegionIds = new ArrayList<>();
        Set<String> storeIdSet = new HashSet<>();
        if (CollectionUtils.isNotEmpty(regionIds)){
            regionDOsByRegionIds = RegionDao.getRegionByRegionIds(regionIds);
            //区域全路径地址集合 ["/1/37139128281/","/1/37139128283/"]
            List<String> regionFullRegionPathList = regionDOsByRegionIds.stream().map(RegionDO::getFullRegionPath).collect(Collectors.toList());
            //根据regionFullRegionPathList查询区域下所有的门店(包括子区域门店)
            List<StoreAreaDTO> storeAreaDTOS = storeMapper.listStoreByRegionPathList(regionFullRegionPathList);
            storeIdSet = storeAreaDTOS.stream().map(StoreAreaDTO::getStoreId).collect(Collectors.toSet());
        }
        List<String> storeIdList = commonDTOS.stream().filter(x -> TypeEnum.STORE.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(storeIdList)){
            //将寻找的门店添加到set中
            storeIdSet.addAll(storeIdList);
        }
        List<String> groupList = commonDTOS.stream().filter(x -> TypeEnum.GROUP.getType().equals(x.getType()))
                .map(CommonDTO::getValue).collect(Collectors.toList());
        //分组
        if (CollectionUtils.isNotEmpty(groupList)) {
            List<StoreGroupMappingDO> groupStoreList = storeGroupMappingMapper.getStoreGroupMappingByGroupIDs(groupList);
            if (CollectionUtils.isNotEmpty(groupStoreList)) {
                Set<String> groupStoreSet = groupStoreList.stream().map(StoreGroupMappingDO::getStoreId).collect(Collectors.toSet());
                if(CollectionUtils.isNotEmpty(groupStoreSet)){
                    //将寻找的门店添加到set中
                    storeIdSet.addAll(groupStoreSet);
                }
            }
        }
        if(CollectionUtils.isEmpty(storeIdSet)){
            return new ArrayList<>();
        }
        List<StoreAreaDTO> storeDTOList = storeMapper.getStoreAreaList(new ArrayList<>(storeIdSet));
        if(CollectionUtils.isNotEmpty(storeDTOList)){
            storeDTOList = storeDTOList.stream().filter(o -> "open".equals(o.getStoreStatus())).collect(Collectors.toList());
        }
        return storeDTOList;
    }



}
