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

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.haoban.manage.api.dto.CommonMQDTO;
import com.gic.haoban.manage.api.dto.HaobanTaskNoticeDTO;
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.enums.NoticeMessageTypeEnum;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.api.service.HaobanTaskNoticeApiService;
import com.gic.haoban.manage.service.dao.mapper.HaobanTaskNoticeMapper;
import com.gic.haoban.manage.service.dao.mapper.StaffMapper;
import com.gic.haoban.manage.service.dao.mapper.chat.GroupChatPlanMapper;
import com.gic.haoban.manage.service.dao.mapper.chat.GroupChatPlanOwnerLogMapper;
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.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.TabHaobanTaskNotice;
import com.gic.haoban.manage.service.entity.chat.TabGroupChatPlan;
import com.gic.haoban.manage.service.entity.chat.TabGroupChatPlanOwnerLog;
import com.gic.haoban.manage.service.entity.moment.TabQwMomentPlan;
import com.gic.haoban.manage.service.service.StaffClerkRelationService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.redis.data.util.RedisUtil;
import com.gic.wechat.api.dto.qywx.ItemDTO;
import com.gic.wechat.api.dto.qywx.QywxXcxSendMessageDTO;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service("haobanTaskNoticeApiService")
public class HaobanTaskNoticeApiServiceImpl implements HaobanTaskNoticeApiService {

    // 每次成员数
    private int pageSize = 1000;
    @Autowired
    private HaobanTaskNoticeMapper haobanTaskNoticeMapper;
    @Autowired
    private QywxSuiteApiService qywxSuiteApiService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private QwMomentPlanMapper qwMomentPlanMapper ;
    @Autowired
    private QwMomentPlanAttendMapper qwMomentPlanAttendMapper ;
    @Autowired
    private StaffClerkRelationService staffClerkRelationService ;
    @Autowired
    private StaffMapper staffMapper;
    @Autowired
    private ClerkService clerkService ;
    @Autowired
    private GroupChatPlanMapper groupChatPlanMapper ;
    @Autowired
    private GroupChatPlanOwnerLogMapper groupChatPlanOwnerLogMapper ;
    @Autowired
    private HaobanCommonMQApiService haobanCommonMQApiService ;

    int maxNum = 10 ;
    @Override
    public ServiceResponse<Void> save(HaobanTaskNoticeDTO notice) {
        Date start = DateUtil.getStartTimeOfDay() ;
        Date end = DateUtil.getEndTimeOfDay() ;
        int num = this.haobanTaskNoticeMapper.listByPlanId(notice.getPlanId(), start, end) ;
        if(num >= maxNum) {
            return ServiceResponse.failure("00001", "执行次数超过最大限制");
        }
        String key ="hbNotice"+ notice.getPlanId() ;
        RedisUtil.lock(key, 3L);
        try {
            if(num + 1 >= maxNum) {
                return ServiceResponse.failure("00001", "执行次数超过最大限制");
            }
            TabHaobanTaskNotice entity = EntityUtil.changeEntityByJSON(TabHaobanTaskNotice.class, notice) ;
            entity.setId(UniqueIdUtils.uniqueLong());
            this.haobanTaskNoticeMapper.save(entity) ;
        }finally {
            RedisUtil.unlock(key);
        }
        return ServiceResponse.success();
    }

    @Override
    public HaobanTaskNoticeDTO getById(Long id) {
        TabHaobanTaskNotice notice = this.haobanTaskNoticeMapper.getById(id) ;
        if(null != notice) {
            return EntityUtil.changeEntityByJSON(HaobanTaskNoticeDTO.class, notice) ;
        }
        return null;
    }

    @Override
    public ServiceResponse<Void> sendTimer(String params) {
        List<TabHaobanTaskNotice> noticeList =  this.haobanTaskNoticeMapper.listForTimer() ;
        Set<String> planIdSet = new HashSet<>() ;
        if(CollectionUtils.isNotEmpty(noticeList)) {
            this.haobanTaskNoticeMapper.updateStatus(noticeList.stream().map(o->o.getId()).collect(Collectors.toList())) ;
            for(TabHaobanTaskNotice notice :noticeList) {
                if(planIdSet.contains(notice.getPlanId())) {
                    continue;
                }
                planIdSet.add(notice.getPlanId()) ;
                if(notice.getPlanType()==1) {
                    CommonMQDTO dto = new CommonMQDTO();
                    dto.setType(20);
                    Map<String,String> map = new HashMap<>() ;
                    map.put("id", notice.getId()+"") ;
                    dto.setParams(map);
                    this.haobanCommonMQApiService.putCommonMessage(dto);
                }else if(notice.getPlanType()==2) {
                    CommonMQDTO dto = new CommonMQDTO();
                    dto.setType(21);
                    Map<String,String> map = new HashMap<>() ;
                    map.put("id", notice.getId()+"") ;
                    dto.setParams(map);
                    this.haobanCommonMQApiService.putCommonMessage(dto);
                }else if(notice.getPlanType()==3) {
                    this.chatSend(notice);
                }else if(notice.getPlanType()==4) {
                    this.momentSend(notice);
                }
            }
        }
        return null;
    }


    private void chatSend(TabHaobanTaskNotice notice) {
        Long planId = Long.parseLong(notice.getPlanId()) ;
        TabGroupChatPlan plan = this.groupChatPlanMapper.selectById(planId) ;
        int pageNum = 0;
        List<TabGroupChatPlanOwnerLog> ownerList = null;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(plan.getWxEnterpriseId()) ;
        while (true) {
            ownerList = this.groupChatPlanOwnerLogMapper.listForDoPlan(planId, pageNum * pageSize, pageSize);
            if (CollectionUtils.isEmpty(ownerList)) {
                break;
            }
            pageNum++;
            for (TabGroupChatPlanOwnerLog ownerLog : ownerList) {
                String clerkId = ownerLog.getClerkId() ;
                String staffId = ownerLog.getStaffId() ;
                String wxUserId = this.getQwUserId(qwDTO, staffId ,clerkId) ;
                if(StringUtils.isBlank(wxUserId)) {
                    continue;
                }
                String appUrl = NoticeMessageTypeEnum.GROUP_CHAT_PLAN.getPageUrl() + NoticeMessageTypeEnum.GROUP_CHAT_PLAN.getPageType();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("planId",planId) ;
                jsonObject.put("ownerLogId",ownerLog.getOwnerLogId()) ;
                ClerkDTO clerk = this.clerkService.getclerkById(clerkId) ;
                if(null != clerk) {
                    jsonObject.put("storeId", clerk.getStoreId());
                }
                appUrl += "&data=" + jsonObject.toJSONString();
                this.send(qwDTO, wxUserId, appUrl , plan.getName() ,notice);
            }
        }
    }
    private void momentSend(TabHaobanTaskNotice notice) {
        Long planId = Long.parseLong(notice.getPlanId()) ;
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        // 判断计划
        List<QwMomentPlanAttendDTO> list = this.qwMomentPlanAttendMapper.listClerk(planId , 1);
        if (CollectionUtils.isNotEmpty(list)) {
            WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(plan.getWxEnterpriseId()) ;
            for (QwMomentPlanAttendDTO dto : list) {
                if(dto.getTaskStatus()==1) {
                    String  clerkId = dto.getClerkId() ;
                    String wxUserId = this.getQwUserId(qwDTO, dto.getStaffId() ,clerkId) ;
                    if(StringUtils.isBlank(wxUserId)) {
                        continue;
                    }
                    String appUrl = NoticeMessageTypeEnum.hbapp_canvas_friend_circle_task.getPageUrl() + NoticeMessageTypeEnum.hbapp_canvas_friend_circle_task.getPageType();
                    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());
                    }
                    appUrl += "&data=" + jsonObject.toJSONString();
                    this.send(qwDTO, wxUserId, appUrl , plan.getTitle() ,notice);
                }
            }
        }
    }


    private void send(WxEnterpriseQwDTO qwDTO , String wxUserId , String appUrl , String title , TabHaobanTaskNotice notice) {
        QywxXcxSendMessageDTO xcx = new QywxXcxSendMessageDTO() ;
        xcx.setTitle("任务执行提醒");
        xcx.setAppid(qwDTO.getHbWxaAppid());
        xcx.setUserIds(Arrays.asList(wxUserId));
        xcx.setPage(appUrl);
        xcx.setItems(this.getItems(notice,title));
        boolean sendFlag = qywxSuiteApiService.sendMessage(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), xcx, qwDTO.isSelf(), qwDTO.getUrlHost());
    }


    private List<ItemDTO> getItems(TabHaobanTaskNotice notice , String title) {
        List<ItemDTO> items = new ArrayList<>() ;
        ItemDTO paramItem1 = new ItemDTO();
        paramItem1.setKey("任务类型");
        if(notice.getPlanType()==3) {
            paramItem1.setValue("社群群发");
        }
        if(notice.getPlanType()==4) {
            paramItem1.setValue("企微朋友圈");
        }
        items.add(paramItem1) ;

        ItemDTO paramItem2 = new ItemDTO();
        paramItem2.setKey("任务名称");
        paramItem2.setValue(title);
        items.add(paramItem2) ;

        if(StringUtils.isNotBlank(notice.getRemark())) {
            ItemDTO paramItem3 = new ItemDTO();
            paramItem3.setKey("执行说明");
            paramItem3.setValue(notice.getRemark());
            items.add(paramItem3);
        }
        return items;
    }


    private String getQwUserId(WxEnterpriseQwDTO qwDTO ,String staffId , String clerkId) {
        if(StringUtils.isBlank(staffId) && StringUtils.isBlank(clerkId)) {
            return null ;
        }
        if(StringUtils.isBlank(staffId)) {
            StaffClerkRelationDTO clerkRelationDTO = staffClerkRelationService.getByClerkId(clerkId);
            if(clerkRelationDTO == null) {
                return null ;
            }
            staffId = clerkRelationDTO.getStaffId() ;
        }
        TabHaobanStaff staff = this.staffMapper.selectByPrimaryKey(staffId) ;
        if(null == staff) {
            return null ;
        }
         String wxUserId = staff.getWxUserId();
        if (qwDTO.needOpenUserId3th()) {
            wxUserId = staff.getWxOpenUseId();
        }
        return wxUserId ;
    }

}
