package com.gic.haoban.manage.service.service.moment.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.clerk.api.service.PowerService;
import com.gic.commons.util.*;
import com.gic.enterprise.api.dto.EnterpriseSettingDTO;
import com.gic.enterprise.api.dto.StoreSearchDTO;
import com.gic.enterprise.api.service.EnterpriseService;
import com.gic.enterprise.api.service.StoreService;
import com.gic.enterprise.api.service.StoreWidgetService;
import com.gic.haoban.manage.api.dto.CommonMQDTO;
import com.gic.haoban.manage.api.dto.ContentMaterialDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanAttendDTO;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanDTO;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanWxaDTO;
import com.gic.haoban.manage.api.enums.NoticeMessageTypeEnum;
import com.gic.haoban.manage.api.enums.PendingTaskTypeEnum;
import com.gic.haoban.manage.api.qdto.moment.PlanListWxaQDTO;
import com.gic.haoban.manage.api.qdto.moment.QwMomentPlanQDTO;
import com.gic.haoban.manage.api.qdto.moment.TaskNumQDTO;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.api.service.StaffClerkRelationApiService;
import com.gic.haoban.manage.api.util.notify.NoticeMessageUtil;
import com.gic.haoban.manage.service.dao.mapper.StaffMapper;
import com.gic.haoban.manage.service.dao.mapper.moment.QwMomentPlanAttendMapper;
import com.gic.haoban.manage.service.dao.mapper.moment.QwMomentPlanMapper;
import com.gic.haoban.manage.service.entity.TabHaobanClerkMainStoreRelated;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.moment.TabQwMomentPlan;
import com.gic.haoban.manage.service.entity.moment.TabQwMomentPlanAttend;
import com.gic.haoban.manage.service.pojo.ClerkStaffBO;
import com.gic.haoban.manage.service.pojo.bo.PendingTaskBO;
import com.gic.haoban.manage.service.pojo.bo.moment.CountBO;
import com.gic.haoban.manage.service.service.ClerkMainStoreRelatedService;
import com.gic.haoban.manage.service.service.QywxSendService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.moment.QwMomentPlanAttendService;
import com.gic.haoban.manage.service.service.moment.QwMomentPlanDataService;
import com.gic.haoban.manage.service.service.moment.QwMomentPlanService;
import com.gic.haoban.manage.service.service.notify.PendingTaskService;
import com.gic.mq.sdk.GicMQClient;
import com.gic.quartz.api.dto.QuartzTaskDTO;
import com.gic.quartz.api.service.QuartzService;
import com.gic.wechat.api.dto.qywx.chat.GroupChatListDTO;
import com.gic.wechat.api.dto.qywx.chat.GroupChatListItemDTO;
import com.gic.wechat.api.dto.qywx.moment.MomentPublishDTO;
import com.gic.wechat.api.dto.qywx.moment.MomentResultDTO;
import com.gic.wechat.api.dto.qywx.moment.MomentUserDTO;
import com.gic.wechat.api.service.qywx.QywxExternalUserService;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service("qwMomentPlanService")
public class QwMomentPlanServiceImpl implements QwMomentPlanService {

    private final Logger logger = LogManager.getLogger(this.getClass());
    @Autowired
    private QwMomentPlanMapper qwMomentPlanMapper ;
    @Autowired
    private QwMomentPlanAttendService qwMomentPlanAttendService ;
    @Autowired
    private QwMomentPlanAttendMapper qwMomentPlanAttendMapper ;
    @Autowired
    private QuartzService quartzService;
    @Autowired
    private ClerkService clerkService ;
    @Autowired
    private EnterpriseService enterpriseService ;
    @Autowired
    private StoreService storeService ;
    @Autowired
    private StaffClerkRelationApiService staffClerkRelationApiService;
    @Autowired
    private PowerService powerService ;
    @Autowired
    private StoreWidgetService storeWidgetService ;
    @Autowired
    private QywxSendService qywxSendService ;
    @Autowired
    private QywxExternalUserService qywxExternalUserService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService ;
    @Autowired
    private StaffMapper staffMapper ;
    @Autowired
    private QwMomentPlanDataService qwMomentPlanDataService ;
    @Autowired
    private HaobanCommonMQApiService haobanCommonMQApiService ;
    @Autowired
    private PendingTaskService pendingTaskService ;
    @Autowired
    private ClerkMainStoreRelatedService clerkMainStoreRelatedService ;

    private static GicMQClient mqClient = GICMQClientUtil.getClientInstance();

    @Override
    public ServiceResponse<Page<QwMomentPlanDTO>> planList(QwMomentPlanQDTO qdto) {
        PageHelper.startPage(qdto);
        if(StringUtils.isNotEmpty(qdto.getNameParams())) {
            qdto.setNameParamsLike("%"+qdto.getNameParams()+"%");
        }
        if(StringUtils.isBlank(qdto.getSortColumn())) {
            qdto.setSortColumn("create_time");
        }
        if(StringUtils.isBlank(qdto.getSortType())) {
            qdto.setSortType("desc");
        }
        List<TabQwMomentPlan> list = this.qwMomentPlanMapper.list(qdto);
        Page<QwMomentPlanDTO> retPage = PageHelperUtils.changePageHelperToCurrentPage(list, QwMomentPlanDTO.class);
        return ServiceResponse.success(retPage);
    }

    @Override
    public ServiceResponse<Page<QwMomentPlanWxaDTO>> planListWxa(PlanListWxaQDTO qdto) {
        PageHelper.startPage(qdto);
        if(StringUtils.isNotEmpty(qdto.getName())) {
            qdto.setNameLike("%"+qdto.getName()+"%");
        }
        List<QwMomentPlanWxaDTO> list = this.qwMomentPlanMapper.planListWxa(qdto);
        Page<QwMomentPlanWxaDTO> retPage = PageHelperUtils.changePageHelperToCurrentPage(list, QwMomentPlanWxaDTO.class);
        return ServiceResponse.success(retPage);
    }

    @Override
    public ServiceResponse<QwMomentPlanDTO> save(QwMomentPlanDTO dto) {
        logger.info("保存朋友圈活动={}", JSONObject.toJSONString(dto));
        String enterpriseId = dto.getEnterpriseId() ;
        String wxEnterpriseId = dto.getWxEnterpriseId() ;
        Long planId = dto.getPlanId() ;
        boolean publishNow = dto.getPublishType()==1 ;
        TabQwMomentPlan plan = EntityUtil.changeEntity(TabQwMomentPlan.class,dto) ;
        Date now = new Date() ;
        plan.setUpdateTime(now);
        // 1立即发布2定时发布
        if(publishNow) {
            plan.setPublishTime(now);
        }
        boolean createFlag = false ;
        plan.setBeginDate(plan.getPublishTime());
        Date endTime = DateUtil.getEndTimeOfDay(DateUtil.addDay(plan.getBeginDate(), plan.getExpireDays()));
        plan.setEndDate(endTime);
        if(null == planId) {
            createFlag = true ;
            planId = UniqueIdUtils.uniqueLong();
            dto.setPlanId(planId);
            plan.setPlanId(planId);
            plan.setCreateTime(now);
            plan.setStatusFlag(1);
            this.qwMomentPlanMapper.insert(plan);
        }else {
            this.qwMomentPlanMapper.update(plan);
        }
        // 参与导购
        if(dto.getPlanClerkType()==1) {
            if (createFlag) {
                List<StaffClerkRelationDTO> list = this.staffClerkRelationApiService.listByClerkIdsWxEnterpriseId(dto.getSelectClerkIdList(),plan.getWxEnterpriseId()) ;
                List<ClerkStaffBO> clerkStaffList = list.stream().map(o->{
                    ClerkStaffBO bo = new ClerkStaffBO() ;
                    bo.setClerkId(o.getClerkId());
                    bo.setStaffId(o.getStaffId());
                    return bo ;
                }).collect(Collectors.toList()) ;
                int statusFlag = 0 ;
                if(publishNow) {
                    // 校验是不是主门店
                    statusFlag = 0  ;
                }
                this.qwMomentPlanAttendService.saveClerk(wxEnterpriseId,enterpriseId, planId, clerkStaffList , statusFlag);
            } else {
                List<String> oldList = this.qwMomentPlanAttendMapper.listClerk(planId , null).stream().map(o -> o.getClerkId()).collect(Collectors.toList());
                List<String> newList = dto.getSelectClerkIdList();
                List<String> addList = newList.stream().filter(o -> !oldList.contains(o)).distinct().collect(Collectors.toList());
                List<String> delList = oldList.stream().filter(o -> !newList.contains(o)).distinct().collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(addList)) {
                    List<StaffClerkRelationDTO> list = this.staffClerkRelationApiService.listByClerkIdsWxEnterpriseId(addList,plan.getWxEnterpriseId()) ;
                    List<ClerkStaffBO> clerkStaffList = list.stream().map(o->{
                        ClerkStaffBO bo = new ClerkStaffBO() ;
                        bo.setClerkId(o.getClerkId());
                        bo.setStaffId(o.getStaffId());
                        return bo ;
                    }).collect(Collectors.toList()) ;
                    this.qwMomentPlanAttendService.saveClerk(wxEnterpriseId,enterpriseId, planId , clerkStaffList , 0);
                }
                if (CollectionUtils.isNotEmpty(delList)) {
                    this.qwMomentPlanAttendMapper.delClerks(planId, delList);
                }
            }
        }
        if(!publishNow) {
            this.addOrDelTimer(planId, plan.getPublishTime(), 1);
        }else {
            this.addOrDelTimer(planId, new Date(), 0);
            JSONObject jsonObject = new JSONObject() ;
            jsonObject.put("planId",planId) ;
            try {
                // initTaskClerk
                logger.info("立即开始执行={}",planId);
                mqClient.sendMessage("qwMomentInitClerkMQ", jsonObject.toJSONString(),10);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return ServiceResponse.success(dto);
    }

    private void sendTaskToClerk(String clerkId, TabQwMomentPlan plan) {
        String enterpriseId = plan.getEnterpriseId() ;
        Long planId = plan.getPlanId() ;
        String planName = plan.getTitle() ;
        String invalidTime = DateUtil.dateToStr(plan.getEndDate(),"yyyy-MM-dd HH:mm:ss") ;
        logger.info("发送任务通知,clerkId={}",clerkId);
        Map<String, String> map = new HashMap<>();
        map.put("taskName",planName) ;
        map.put("invalidTime",invalidTime) ;
        int messageType =  NoticeMessageTypeEnum.hbapp_canvas_friend_circle_task.getType();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("planId",planId) ;
        jsonObject.put("clerkId",clerkId) ;
        ClerkDTO clerk = this.clerkService.getclerkById(clerkId) ;
        if(null != clerk) {
            jsonObject.put("storeId", clerk.getStoreId());
        }
        NoticeMessageUtil.sendNoticeMessage(enterpriseId,clerkId,messageType,null,map,jsonObject);
    }


    @Override
    public ServiceResponse<Void> del(Long planId) {
        this.qwMomentPlanMapper.del(planId);
        this.addOrDelTimer(planId, new Date(), 0);
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> stop(Long planId) {
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        this.qwMomentPlanMapper.stop(planId);
        // 删除定时
        this.addOrDelTimer(planId, new Date(), 0);
        if(plan.getExecType()==0 && StringUtils.isNotBlank(plan.getMomentId())) {
            String wxEnterpriseId = plan.getWxEnterpriseId() ;
            WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
            logger.info("取消发送={},{}",planId,plan.getMomentId());
            this.qywxExternalUserService.cancelMomentTask(qwDTO.getThirdCorpid(),
                    qwDTO.getSelf3thSecret(), plan.getMomentId() ,qwDTO.isSelf(),qwDTO.getUrlHost()) ;
        }
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<QwMomentPlanDTO> detail(Long planId) {
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId);
        if(null == plan) {
            return ServiceResponse.failure("9999", "活动不存在或已删除");
        }
        QwMomentPlanDTO dto = EntityUtil.changeEntityByJSON(QwMomentPlanDTO.class,plan) ;
        // 获取参与导购
        if(dto.getPlanClerkType()==1) {
            List<QwMomentPlanAttendDTO> clerkList = this.qwMomentPlanAttendMapper.listClerk(planId,null) ;
            dto.setClerkList(clerkList);
        }
        return ServiceResponse.success(dto);
    }

    private void addOrDelTimer(Long planId, Date sendTime, int status) {
        logger.info("添加1/删除0定时,{},{}", status, planId);
        QuartzTaskDTO quartzTask = new QuartzTaskDTO();
        quartzTask.setTaskStatus(status);
        String taskTimeInfo = this.getTaskTime(sendTime);
        quartzTask.setTaskTimeInfo(taskTimeInfo);
        quartzTask.setTaskService("com.gic.haoban.manage.api.service.moment.QwMomentApiService");
        quartzTask.setTaskMethod("sendPlanNoticeTimer");
        quartzTask.setTaskParam(planId + "");
        quartzTask.setReferId(planId + "");
        try {
            quartzService.addOrUpdateQuartzTask(quartzTask);
        } catch (Exception e) {
            logger.warn("提交定时任务异常", e);
        }
    }

    private String getTaskTime(Date date) {
        String timeInfo = DateUtil.dateToStr(date, "yyyyMMddHHmmss");
        String year = timeInfo.substring(0, 4);
        int month = Integer.parseInt(timeInfo.substring(4, 6));
        int day = Integer.parseInt(timeInfo.substring(6, 8));
        int hour = Integer.parseInt(timeInfo.substring(8, 10));
        int minute = Integer.parseInt(timeInfo.substring(10, 12));
        int second = Integer.parseInt(timeInfo.substring(12, 14));
        String time = new StringBuilder().append(second).append(" ").append(minute).append(" ").append(hour).append(" ")
                .append(day).append(" ").append(month).append(" ").append(year).toString();
        return time;
    }


    private void saveAttendClerkForTask(TabQwMomentPlan plan) {
        Long planId = plan.getPlanId() ;
        String creatorId = plan.getCreatorId() ;
        String enterpriseId = plan.getEnterpriseId() ;
        ClerkDTO clerkDTO = this.clerkService.getclerkById(creatorId) ;
        EnterpriseSettingDTO enterpriseSetting = enterpriseService.getEnterpriseSettingByEnterpriseId(enterpriseId);
        List<String> storeIdList = null ;
        if(clerkDTO.getClerkType()==3 || !(enterpriseSetting.getEnableAccessControl() != null && enterpriseSetting.getEnableAccessControl() == 1)) {
            logger.info("超管");
            StoreSearchDTO searchDTO = new StoreSearchDTO() ;
            searchDTO.setEnterpriseId(plan.getEnterpriseId());
            searchDTO.setStatus("2");
            storeIdList = this.storeService.listStoreIds(searchDTO) ;
        }else {
            storeIdList = this.getStoreIdList(clerkDTO) ;
        }
        List<StaffClerkRelationDTO> list = this.staffClerkRelationApiService.listByStoreIds(plan.getWxEnterpriseId() , storeIdList) ;
        List<ClerkStaffBO> clerkIdList = list.stream().filter(o->{
            TabHaobanClerkMainStoreRelated tab = this.clerkMainStoreRelatedService.getMainStoreByStaffId(o.getStaffId(),plan.getWxEnterpriseId()) ;
            return tab != null && tab.getStoreId().equals(o.getStoreId()) ;
        }).map(o->{
            ClerkStaffBO bo = new ClerkStaffBO() ;
            bo.setClerkId(o.getClerkId());
            bo.setStaffId(o.getStaffId());
            return bo ;
        }).collect(Collectors.toList()) ;
        Page<ClerkDTO> userPage = this.clerkService.pageUserBySearchName(plan.getEnterpriseId(),null,1,10000) ;
        List<String> userIdList = userPage.getResult().stream().map(o->o.getClerkId()).collect(Collectors.toList());
        logger.info("管理员列表={}",userIdList);
        clerkIdList.stream().filter(o->!userIdList.contains(o)).collect(Collectors.toList()) ;
        logger.info("导购数量={}",clerkIdList.size());

        this.qwMomentPlanAttendService.saveClerk(plan.getWxEnterpriseId(),plan.getEnterpriseId(),planId, clerkIdList , 1);
        this.qwMomentPlanMapper.updateClerkNum(planId,clerkIdList.size(),-1,-1);
    }

    private List<String> getStoreIdList(ClerkDTO clerkDTO) {
        String clerkId = clerkDTO.getClerkId();
        String enterpriseId = clerkDTO.getEnterpriseId();
        String storeWidgetId = this.powerService.getStoreWidgetId(null, clerkId);
        // 门店id列表
        List<String> storeIdList = storeWidgetService.getStoreWidgetStore(storeWidgetId, enterpriseId, null, null, 2);
        logger.info("组件id={},上线数量:{}", storeWidgetId,storeIdList.size());
        if (CollectionUtils.isEmpty(storeIdList)) {
            return Collections.emptyList();
        }
        return storeIdList;
    }

    @Override
    public void initTaskClerk(String params) {
        logger.info("创建立即执行朋友圈={}",params);
        JSONObject json = JSONObject.parseObject(params) ;
        Long planId = json.getLong("planId") ;
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        this.send(plan);
    }

    @Override
    public void sendPlanNoticeTimer(String params) {
        logger.info("定时发布任务发送通知={}",params);
        Long planId = Long.valueOf(params) ;
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        if(null == plan) {
            logger.info("null");
            return;
        }
        this.send(plan);
    }

    private void send(TabQwMomentPlan plan) {
        if(plan.getDeleteFlag()==1 || plan.getStatusFlag()!=1 || plan.getEndDate().getTime()<=System.currentTimeMillis()) {
            logger.info("计划已停止={}",plan.getPlanId());
            return;
        }
        // 0全部导购 1部分导购
        if(plan.getPlanClerkType()==0) {
            this.saveAttendClerkForTask(plan) ;
        }else {
            // 下发失败
            this.qwMomentPlanAttendService.updateStatusFlag(plan);
        }
        this.sendPlanNotice(plan);
    }

    // 发送活动通知
    private void sendPlanNotice(TabQwMomentPlan plan) {
        if(plan.getPublishType()==1 || plan.getPublishTime().getTime() <= System.currentTimeMillis()) {
            long planId = plan.getPlanId();
            // 好办小程序
            if(plan.getExecType()==1) {
                List<QwMomentPlanAttendDTO> list = this.qwMomentPlanAttendMapper.listClerk(planId , 1);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (QwMomentPlanAttendDTO dto : list) {
                        this.sendTaskToClerk(dto.getClerkId(),plan);
                        this.addPendingTask(plan,dto.getStoreId(),dto.getClerkId(),dto.getAttendId()) ;
                    }
                }
            }else {
                // 企微下发任务
                this.sendToQiwei(plan);
            }
        }
    }

    @Override
    public void sendToQiwei(TabQwMomentPlan plan) {
        List<ContentMaterialDTO> imageList = new ArrayList<>() ;
        String json = plan.getMediaInfo() ;
        JSONArray arr = JSONArray.parseArray(json) ;
        String msg = null ;
        for(int i=0;i<arr.size();i++) {
            JSONObject obj  = arr.getJSONObject(i) ;
            ContentMaterialDTO vo = new ContentMaterialDTO();
            vo.setMaterialType(obj.getInteger("materialType"));
            if(vo.getMaterialType()==4) {
                vo.setVideoImgUrl(obj.getString("imgUrl"));
                vo.setImgUrl(obj.getString("videoUrl"));
            }
            if(vo.getMaterialType()==3) {
                vo.setLink(obj.getString("link"));
                vo.setImgUrl(obj.getString("imgUrl"));
            }
            if(vo.getMaterialType()==2) {
                vo.setImgUrl(obj.getString("imgUrl"));
            }
            vo.setMaterialTitle(obj.getString("title"));
            if(vo.getMaterialType()==1) {
                msg = obj.getString("contentText") ;
                continue;
            }
            vo.setMaterialDesc(obj.getString("contentText"));
            imageList.add(vo);
        }
        List<QwMomentPlanAttendDTO> clerkList = this.qwMomentPlanAttendMapper.listClerk(plan.getPlanId(),1) ;
        List<String> clerkIdList = clerkList.stream().map(o->o.getClerkId()).collect(Collectors.toList());
        ServiceResponse<String> resp = this.qywxSendService.share(plan.getWxEnterpriseId(),clerkIdList,msg,imageList) ;
        logger.info("发企微朋友={}",JSONObject.toJSONString(resp));
        String jobId = resp.getResult() ;
        if(StringUtils.isBlank(jobId)) {
            logger.info("朋友圈调用企微失败={}",plan.getPlanId());
            // api concurrent out of limit
            if("45033".equals(resp.getCode())) {
                CommonMQDTO mq = new CommonMQDTO() ;
                mq.setType(8) ;
                Map<String,String> map = new HashMap<>() ;
                map.put("planId",plan.getPlanId()+"") ;
                mq.setParams(map);
                this.haobanCommonMQApiService.putCommonDelayMessage(mq, 300);
                return;
            }
            return;
        }
        for (QwMomentPlanAttendDTO dto : clerkList) {
            this.addPendingTask(plan,dto.getStoreId(),dto.getClerkId(),dto.getAttendId()) ;
        }
        this.qwMomentPlanMapper.updateJobid(plan.getPlanId(),jobId) ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(plan.getWxEnterpriseId());
        ServiceResponse<Object> resp2 = this.qywxExternalUserService.getMomentTaskResult(qwDTO.getThirdCorpid(),
                qwDTO.getSelf3thSecret(), jobId, qwDTO.isSelf(),qwDTO.getUrlHost()) ;
        logger.info("获取moment_id={}",JSONObject.toJSONString(resp2));
        if(null != resp2.getResult()) {
            String moment_id = resp2.getResult().toString() ;
            this.qwMomentPlanMapper.updateMomentId(plan.getPlanId(),moment_id);
        }else {
            CommonMQDTO mq = new CommonMQDTO() ;
            mq.setType(6) ;
            Map<String,String> map = new HashMap<>() ;
            map.put("planId",plan.getPlanId()+"") ;
            mq.setParams(map);
            this.haobanCommonMQApiService.putCommonDelayMessage(mq, 60);
        }
    }

    @Override
    public void getMomentId(Long planId) {
        TabQwMomentPlan plan =  this.qwMomentPlanMapper.getById(planId) ;
        if(null == plan) {
            logger.info("计划已删除");
            return;
        }
        String wxEnterpriseId =plan.getWxEnterpriseId() ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
        ServiceResponse<Object> resp2 = this.qywxExternalUserService.getMomentTaskResult(qwDTO.getThirdCorpid(),
                qwDTO.getSelf3thSecret(), plan.getQwJobid(), qwDTO.isSelf(),qwDTO.getUrlHost()) ;
        logger.info("获取moment_id={}",JSONObject.toJSONString(resp2));
        if(null != resp2.getResult()) {
            String moment_id = resp2.getResult().toString() ;
            this.qwMomentPlanMapper.updateMomentId(plan.getPlanId(),moment_id);
        }else {
            CommonMQDTO mq = new CommonMQDTO() ;
            mq.setType(6) ;
            Map<String,String> map = new HashMap<>() ;
            map.put("planId",plan.getPlanId()+"") ;
            mq.setParams(map);
            this.haobanCommonMQApiService.putCommonDelayMessage(mq, 60);
        }
    }

    @Override
    public ServiceResponse<Integer> getTaskNum(TaskNumQDTO qdto) {
        int count = this.qwMomentPlanMapper.getTaskNum(qdto);
        return ServiceResponse.success(count);
    }

    @Override
    public void getQwData(Long planId) {
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        List< TabQwMomentPlanAttend> list = this.qwMomentPlanAttendMapper.listForData(planId) ;
        for(TabQwMomentPlanAttend item : list) {
            try {
                this.getQwData(item, 0, plan.getMomentId());
            }catch (Exception e) {
                logger.info("异常",e);
            }
        }
        CountBO bo = this.qwMomentPlanAttendMapper.getQwCount(planId) ;
        if (null != bo && (null != bo.getLikeCount() || null != bo.getCommentCount())) {
            int like = 0 ;
            int comment = 0 ;
            if(bo.getLikeCount() != null) {
                like = bo.getLikeCount() ;
            }
            if(bo.getCommentCount() != null) {
                comment = bo.getCommentCount() ;
            }
            this.qwMomentPlanMapper.updateQwData(planId , like , comment) ;
        }
    }

    @Override
    public void getQwData(TabQwMomentPlanAttend task , int type ,String planMomentId) {
        logger.info("获取企微的统计={},{},{}",JSONObject.toJSONString(task),type,planMomentId);
        if(StringUtils.isNotBlank(planMomentId)) {
            task.setMomentId(planMomentId);
        }
        if(StringUtils.isBlank(task.getMomentId())) {
            return;
        }
        MomentResultDTO dto = this.getQwData(task.getStaffId(),task.getMomentId(),task.getWxEnterpriseId()) ;
        if(null != dto) {
            this.qwMomentPlanDataService.save(task, dto);
            if(type==1) {
                CountBO bo = this.qwMomentPlanAttendMapper.getQwCount(task.getPlanId()) ;
                if (null != bo && (null != bo.getLikeCount() || null != bo.getCommentCount())) {
                    int like = 0 ;
                    int comment = 0 ;
                    if(bo.getLikeCount() != null) {
                        like = bo.getLikeCount() ;
                    }
                    if(bo.getCommentCount() != null) {
                        comment = bo.getCommentCount() ;
                    }
                    this.qwMomentPlanMapper.updateQwData(task.getPlanId() , like , comment) ;
                }
            }
        }
    }

    private MomentResultDTO getQwData(String staffId , String momentId ,  String wxEnterpriseId) {
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        return this.getData(staffId,momentId,qwDTO);
    }

    private MomentResultDTO getData(String staffId , String momentId , WxEnterpriseQwDTO qwDTO) {
        TabHaobanStaff staff =  this.staffMapper.selectByPrimaryKey(staffId) ;
        if(null == staff) {
            logger.info("无员工={}",staffId);
            return null ;
        }
        String wxUserId = staff.getWxUserId() ;
        if(qwDTO.needOpenUserId3th()) {
            wxUserId = staff.getWxOpenUseId() ;
        }
        ServiceResponse<MomentResultDTO> resp = this.qywxExternalUserService.getMomentComments(qwDTO.getThirdCorpid(),
                qwDTO.getSelf3thSecret(), momentId,wxUserId,qwDTO.isSelf(),qwDTO.getUrlHost()) ;
        logger.info("企微统计返回={},{}",JSONObject.toJSONString(resp),staffId);
        MomentResultDTO dto  = resp.getResult() ;
        return dto ;
    }

    private void addPendingTask(TabQwMomentPlan plan , String storeId , String clerkId , Long attendId) {
        PendingTaskBO bo = new PendingTaskBO();
        bo.setRelationId(attendId+"");
        bo.setBusinessId(plan.getPlanId()+"");
        bo.setTaskType(PendingTaskTypeEnum.QYWX_MOMENT.getType());
        bo.setTitle(plan.getTitle());
        bo.setDescription(plan.getRemark());
        bo.setStoreId(storeId);
        bo.setInvalidTime(plan.getEndDate());
        bo.setClerkId(clerkId);
        bo.setEnterpriseId(plan.getEnterpriseId());
        bo.setOverdueTime(plan.getEndDate());
        this.pendingTaskService.addOrUpdatePendingTask(bo);
    }

    @Override
    public void getQwPublishData(Long planId, String cursor) {
        if(null == cursor) {
            logger.info("获取企微朋友执行情况={}", planId);
        }
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        String momentId = plan.getMomentId() ;
        if(StringUtils.isBlank(momentId)) {
            return;
        }
        String wxEnterpriseId = plan.getWxEnterpriseId() ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        ServiceResponse<MomentPublishDTO>  resp = this.qywxExternalUserService.getPublishList(qwDTO.getThirdCorpid(),
                qwDTO.getSelf3thSecret(), momentId,null,qwDTO.isSelf(),qwDTO.getUrlHost()) ;
        if(!resp.isSuccess()) {
            logger.info("拉取列表异常={}", JSON.toJSON(resp));
            return;
        }
        MomentPublishDTO dto = resp.getResult();
        cursor = dto.getNext_cursor();
        List<MomentUserDTO> list = dto.getTask_list() ;
        for (MomentUserDTO item : list) {
            try {
                String userid = item.getUserid() ;
                int chatStatus = item.getPublish_status() ;
                if(chatStatus==1) {
                    TabHaobanStaff staff = this.staffMapper.selectByUserIdAndEnterpriseId(userid, wxEnterpriseId);
                    if(null != staff) {
                        String staffId = staff.getStaffId();
                        List<TabQwMomentPlanAttend> tabList = this.qwMomentPlanAttendMapper.getByStaff(planId, staffId);
                        if(CollectionUtils.isNotEmpty(tabList)) {
                            for(TabQwMomentPlanAttend attend :tabList) {
                                if(attend.getTaskStatus()==1) {
                                    this.qwMomentPlanAttendService.finishTaskUpdateData(attend.getAttendId(),attend.getPlanId(),new Date(),null) ;
                                }
                            }
                        }
                    }
                }
            }catch (Exception e) {
                logger.info("异常",e);
            }
        }
        // 从企微拉取下一批数据
        if (org.apache.commons.lang.StringUtils.isNotBlank(cursor)) {
            this.getQwPublishData(planId,cursor);
        }
    }


    @Override
    public void qwDataTimer(String params) {
        logger.info("朋友圈-定时-{}",params);
        // 是否完成
        if(params.equals("1")) {
            List<Long> planIdList = this.qwMomentPlanMapper.listForData(1) ;
            logger.info("朋友圈-定时1-{}",planIdList);
            if(CollectionUtils.isNotEmpty(planIdList)) {
                for(Long planId : planIdList) {
                    try{
                        CommonMQDTO mq = new CommonMQDTO() ;
                        mq.setType(9) ;
                        Map<String,String> map = new HashMap<>() ;
                        map.put("planId",planId+"") ;
                        mq.setParams(map);
                        this.haobanCommonMQApiService.putCommonDelayMessage(mq, 10);
                    }catch (Exception e) {
                        logger.info("异常",e);
                    }
                }
            }
        }

        // 评论数据
        if(params.equals("2")) {
            List<Long> planIdList = this.qwMomentPlanMapper.listForData(2) ;
            logger.info("朋友圈-定时2-{}",planIdList);
            if(CollectionUtils.isNotEmpty(planIdList)) {
                for(Long planId : planIdList) {
                    try {
                        try{
                            CommonMQDTO mq = new CommonMQDTO() ;
                            mq.setType(10) ;
                            Map<String,String> map = new HashMap<>() ;
                            map.put("planId",planId+"") ;
                            mq.setParams(map);
                            this.haobanCommonMQApiService.putCommonDelayMessage(mq, 10);
                        }catch (Exception e) {
                            logger.info("异常",e);
                        }
                    }catch (Exception e) {
                        logger.info("异常",e);
                    }
                }
            }
        }

        // 到期停止
        if(params.equals("3")) {
            Date end = DateUtil.addDay(new Date(),-1) ;
            end = DateUtil.getEndTimeOfDay(end) ;
            List<TabQwMomentPlan> planList = this.qwMomentPlanMapper.listForStop(end) ;
            if(CollectionUtils.isNotEmpty(planList)) {
                for(TabQwMomentPlan plan : planList) {
                    String wxEnterpriseId = plan.getWxEnterpriseId() ;
                    WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
                    logger.info("取消发送={},{}",plan.getPlanId(),plan.getMomentId());
                    if(StringUtils.isNotBlank(plan.getMomentId())) {
                        this.qywxExternalUserService.cancelMomentTask(qwDTO.getThirdCorpid(),
                                qwDTO.getSelf3thSecret(), plan.getMomentId(), qwDTO.isSelf(), qwDTO.getUrlHost());
                    }
                }
            }
        }
    }

    @Override
    public void sendRetry(Long qwPlanId) {
        logger.info("朋友圈重试={}",qwPlanId);
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(qwPlanId) ;
        this.sendToQiwei(plan);
    }
}
