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

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.commons.util.ToolUtil;
import com.gic.haoban.app.customer.enums.QywxTaskStatusEnum;
import com.gic.haoban.app.customer.service.api.service.QywxTagSyncApiService;
import com.gic.haoban.base.api.common.ServiceResponse;
import com.gic.haoban.common.utils.EntityUtil;
import com.gic.haoban.manage.api.dto.*;
import com.gic.haoban.manage.api.enums.QywxTagRelationSyncFlagEnum;
import com.gic.haoban.manage.api.enums.QywxTagRelationTypeEnum;
import com.gic.haoban.manage.api.service.QywxTagApiService;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.QywxTagRelationMapper;
import com.gic.haoban.manage.service.entity.*;
import com.gic.haoban.manage.service.pojo.QywxSyncTagFormatPojo;
import com.gic.haoban.manage.service.service.ExternalClerkRelatedService;
import com.gic.haoban.manage.service.service.QywxTagService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.util.DingUtils;
import com.gic.member.api.dto.MemberTagDTO;
import com.gic.member.api.service.MemberTagService;
import com.gic.member.tag.api.dto.MemberTagItemDTO;
import com.gic.member.tag.api.service.MemberTagApiService;
import com.gic.member.tag.api.service.MemberTagItemApiService;
import com.gic.mq.sdk.GicMQClient;
import com.gic.redis.data.util.RedisUtil;
import com.gic.wechat.api.dto.qywx.QywxTagDTO;
import com.gic.wechat.api.dto.qywx.QywxTagGroupDTO;
import com.gic.wechat.api.dto.qywx.response.QywxGetCorpTagListDTO;
import com.gic.wechat.api.dto.qywx.response.QywxResponseDTO;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Created 2021/6/21.
 *
 * @author hua
 */
@Service
public class QywxTagApiServiceImpl implements QywxTagApiService {
    private static final Logger logger = getLogger(QywxTagApiServiceImpl.class);
    /**
     * 限制次数
     */
    private static final Integer MAX_TIMES = 3;
    @Autowired
    private QywxSuiteApiService qywxSuiteApiService;

    @Autowired
    private Config config;

    @Autowired
    private WxEnterpriseService wxEnterpriseService;

    @Autowired
    private QywxTagService qywxTagService;

    @Autowired
    private QywxUserApiService qywxUserApiService;

    @Autowired
    private ExternalClerkRelatedService externalClerkRelatedService;

    @Autowired
    private MemberTagService memberTagService;

    @Autowired
    private QywxTagSyncApiService qywxTagSyncApiService;

    @Autowired
    private MemberTagItemApiService memberTagItemApiService;
    @Autowired
    private QywxTagRelationMapper qywxTagRelationMapper;
    @Autowired
    private MemberTagApiService memberTagApiService;

    @Override
    public void pullQywxTag(String wxEnterpriseId) {
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        if (null == qwDTO) {
            logger.info("企业标签所在企业不存在");
            return;
        }
        QywxGetCorpTagListDTO corpTagListResp = qywxSuiteApiService.getCorpTagList(qwDTO.getThirdCorpid(),  qwDTO.getSelf3thSecret(), null, -1 , qwDTO.isSelf(),qwDTO.getUrlHost());
        if (corpTagListResp.getErrcode() != 0) {
            logger.info("企业微信标签有问题:{}", wxEnterpriseId);
            return;
        }
        //拉取保存所有标签
        List<QywxTagGroupDTO> tagGroup = corpTagListResp.getTagGroup();
        for (QywxTagGroupDTO groupDTO : tagGroup) {
            qywxTagService.saveQywxTagByQywxGroupKey(wxEnterpriseId, groupDTO);
        }
    }

    @Override
    public  com.gic.api.base.commons.ServiceResponse syncTagToQywx(String enterpriseId, String memberTagId) {
        logger.info("更新企微标签,memberTagId={}",memberTagId);
        List<TabQywxTagRelation> relationList = this.qywxTagRelationMapper.listByMemberTagId(null,memberTagId) ;
        if(CollectionUtils.isEmpty(relationList)) {
            logger.info("标签未同步过企微");
            return com.gic.api.base.commons.ServiceResponse.success() ;
        }
        String  wxEnterpriseId  = relationList.get(0).getWxEnterpriseId() ;
        com.gic.member.tag.api.dto.MemberTagDTO memberTagDTO = memberTagApiService.getMemberTagById(memberTagId);
        List<MemberTagItemDTO> tagItems = memberTagApiService.queryMemberTagItem(memberTagId);
        QywxTagInfoDTO qywxTagInfoDTO = new QywxTagInfoDTO();
        qywxTagInfoDTO.setWxEnterpriseId(wxEnterpriseId);
        qywxTagInfoDTO.setMemberTagId(memberTagDTO.getTagId());
        qywxTagInfoDTO.setQywxGroupName(memberTagDTO.getTagName());
        List<QywxTagItemDTO> items = tagItems.stream().map(item -> {
            QywxTagItemDTO mid = new QywxTagItemDTO();
            mid.setMemberTagItemId(item.getTagItemId());
            mid.setQywxTagKey(item.getTagItemId());
            mid.setQywxTagName(item.getTagItemName());
            return mid;
        }).collect(Collectors.toList());
        //保存同步
        this.syncTagToQywx(wxEnterpriseId,enterpriseId,qywxTagInfoDTO,items);
        return com.gic.api.base.commons.ServiceResponse.success() ;
    }

    @Override
    public ServiceResponse syncTagToQywx(String wxEnterpriseId, String enterpriseId, QywxTagInfoDTO infoDTO, List<QywxTagItemDTO> items) {
        String memberTagId = infoDTO.getMemberTagId() ;
        logger.info("标签同步到企业微信,wxEnterpriseId={},memberTagId={}",wxEnterpriseId,memberTagId);
        List<MemberTagItemDTO> tagItems = memberTagApiService.queryMemberTagItem(memberTagId);
        items = tagItems.stream().map(item -> {
            QywxTagItemDTO mid = new QywxTagItemDTO();
            mid.setMemberTagItemId(item.getTagItemId());
            mid.setQywxTagKey(item.getTagItemId());
            mid.setQywxTagName(item.getTagItemName());
            return mid;
        }).collect(Collectors.toList());
        ServiceResponse ret = new ServiceResponse();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        // 判断更新
        List<String> needDelList = new ArrayList<>() ;
        List<QywxTagItemDTO> needAddList = new ArrayList<>() ;
        List<String> memberTagItemIdList = items.stream().map(o->o.getMemberTagItemId()).collect(Collectors.toList()); ;
        List<TabQywxTagRelation> relationList = this.qywxTagRelationMapper.listByMemberTagId(wxEnterpriseId,memberTagId) ;
        if(CollectionUtils.isNotEmpty(relationList)) {
            String hbTagId = relationList.get(0).getQywxTagId() ;
            TabQywxTag tag = this.qywxTagService.getQywxTagByQywxTagId(wxEnterpriseId,hbTagId) ;
            String qwGroupKey = tag.getQywxGroupKey() ;
            logger.info("已经存在企微标签,进行更新处理={}",qwGroupKey);
            QywxGetCorpTagListDTO tagListDTO = this.qywxSuiteApiService.getCorpTagList(qwDTO.getThirdCorpid(),qwDTO.getSelf3thSecret(),Arrays.asList(qwGroupKey),0,qwDTO.isSelf(),qwDTO.getUrlHost()) ;
            logger.info("企微侧标签={}",JSONObject.toJSONString(tagListDTO));
            List<TabQywxTagItem> tagItemList = this.qywxTagService.listByQywxTagId(wxEnterpriseId,hbTagId) ;
            Map<String,TabQywxTagItem> tagItemMap = tagItemList.stream().collect(Collectors.toMap(TabQywxTagItem::getQywxTagItemId,o->o,(k1,k2)->k1)) ;
            // 更新赋值
            infoDTO.setQywxGroupKey(qwGroupKey);
            // 需要删除的标签值
            for(TabQywxTagRelation relation : relationList) {
                String memberItemTagId = relation.getTagItemId() ;
                if(!memberTagItemIdList.contains(memberItemTagId)) {
                    this.qywxTagRelationMapper.deleteByPrimaryKey(relation.getQywxTagRelationId()) ;
                    String hbTagItemId = relation.getQywxTagItemId() ;
                    this.qywxTagService.delQywxTagItemById(wxEnterpriseId,hbTagItemId) ;
                    TabQywxTagItem tagItem = tagItemMap.get(hbTagItemId) ;
                    if(null != tagItem) {
                        needDelList.add(tagItem.getQywxTagKey()) ;
                    }
                }
            }
            if(CollectionUtils.isNotEmpty(needDelList)) {
                this.qywxSuiteApiService.delCorpTag(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), needDelList, 1, qwDTO.isSelf(),qwDTO.getUrlHost());
            }
            // 需要添加的标签值
            List<String> existMemberTagIdList = relationList.stream().map(o->o.getTagItemId()).collect(Collectors.toList());
            for(QywxTagItemDTO memberTag : items) {
                if(!existMemberTagIdList.contains(memberTag.getMemberTagItemId())) {
                    needAddList.add(memberTag) ;
                }
            }
            items = needAddList ;
            logger.info("更新标签,删除={},新增={}",needDelList,needAddList);
        }
        if(CollectionUtils.isEmpty(items)) {
            logger.info("没有需要处理的标签");
            return ret ;
        }
        //调用企业微信接口保存
        QywxGetCorpTagListDTO resp = this.saveQywxTag(qwDTO.getThirdCorpid(), infoDTO, items,qwDTO);
        if (resp.getErrcode() != 0 && CollectionUtils.isEmpty(resp.getTagGroup())) {
            logger.info("同步失败：{}", JSONObject.toJSONString(resp));
            ret.setCode(resp.getErrcode());
            ret.setMessage(resp.getErrmsg());
            return ret;
        }
        //拉取保存所有标签
        List<QywxTagGroupDTO> tagGroup = resp.getTagGroup();
        QywxTagGroupDTO groupDTO = tagGroup.get(0);
        //保存企业微信标签信息
        Pair<TabQywxTag, List<TabQywxTagItem>> savePair = qywxTagService.saveQywxTagByQywxGroupKey(wxEnterpriseId, groupDTO);
        if (null == savePair) {
            logger.info("保存失败：{}", JSONObject.toJSONString(groupDTO));
            ret.setCode(1);
            ret.setMessage("保存企业微信标签失败");
            return ret;
        }
        //保存关联关系
        this.saveRelation(wxEnterpriseId, enterpriseId, infoDTO, items, savePair);
        return ret;
    }

    /**
     * 保存标签的关联关系
     *
     * @param wxEnterpriseId
     * @param enterpriseId
     * @param infoDTO
     */
    private void saveRelation(String wxEnterpriseId, String enterpriseId, QywxTagInfoDTO infoDTO, List<QywxTagItemDTO> items, Pair<TabQywxTag, List<TabQywxTagItem>> localQywxTagPair) {
        Map<String, QywxTagItemDTO> orgMap = items.stream().collect(Collectors.toMap(item -> item.getQywxTagName(), dto -> dto,(k1,k2)->k1));
        //设置关联关系
        TabQywxTag groupKey = localQywxTagPair.getKey();
        List<TabQywxTagItem> tabQywxTagItems = localQywxTagPair.getRight();

        List<TabQywxTagRelation> saveRelationList = new ArrayList<>();
        //如果存在qywxGroupKey 说明已经创建过了
        if (StringUtils.isBlank(infoDTO.getQywxGroupKey())) {
            TabQywxTagRelation groupRelation = new TabQywxTagRelation();
            groupRelation.setEnterpriseId(enterpriseId);
            groupRelation.setMemberTagId(infoDTO.getMemberTagId());
            groupRelation.setQywxTagId(groupKey.getQywxTagId());
            groupRelation.setRelationType(QywxTagRelationTypeEnum.TAG_GROUP.getType());
            groupRelation.setStatusFlag(1);
            groupRelation.setSyncFlag(QywxTagRelationSyncFlagEnum.PRE.getType());
            groupRelation.setQywxTagRelationId(ToolUtil.randomUUID());
            groupRelation.setWxEnterpriseId(wxEnterpriseId);
            saveRelationList.add(groupRelation);
        }
        List<TabQywxTagRelation> itemList = tabQywxTagItems.stream().map(tab -> {
            QywxTagItemDTO orgItem = orgMap.get(tab.getQywxTagName());
            TabQywxTagRelation itemRelation = new TabQywxTagRelation();
            itemRelation.setWxEnterpriseId(wxEnterpriseId);
            itemRelation.setQywxTagRelationId(ToolUtil.randomUUID());
            itemRelation.setSyncFlag(QywxTagRelationSyncFlagEnum.PRE.getType());
            itemRelation.setStatusFlag(1);
            itemRelation.setRelationType(QywxTagRelationTypeEnum.TAG_ITEM.getType());
            itemRelation.setQywxTagId(groupKey.getQywxTagId());
            itemRelation.setMemberTagId(infoDTO.getMemberTagId());
            itemRelation.setEnterpriseId(enterpriseId);
            itemRelation.setQywxTagItemId(tab.getQywxTagItemId());
            itemRelation.setTagItemId(orgItem.getMemberTagItemId());
            return itemRelation;
        }).collect(Collectors.toList());
        saveRelationList.addAll(itemList);
        qywxTagService.saveQywxRelation(saveRelationList);
    }

    /**
     * 调用企业微信接口 保存标签
     * @param infoDTO
     * @param items
     * @return
     */
    private QywxGetCorpTagListDTO saveQywxTag(String corpid, QywxTagInfoDTO infoDTO, List<QywxTagItemDTO> items , WxEnterpriseQwDTO qwDTO) {
        QywxTagGroupDTO qywxTagGroupDTO = new QywxTagGroupDTO();
        qywxTagGroupDTO.setGroupName("GIC" + infoDTO.getQywxGroupName());
        qywxTagGroupDTO.setOrder(infoDTO.getOrder());
        qywxTagGroupDTO.setGroupId(infoDTO.getQywxGroupKey());

        List<QywxTagDTO> tagItems = items.stream().map(item -> {
            QywxTagDTO qywxTagDTO = new QywxTagDTO();
            qywxTagDTO.setName(item.getQywxTagName());
            qywxTagDTO.setOrder(item.getOrder());
            return qywxTagDTO;
        }).collect(Collectors.toList());
        qywxTagGroupDTO.setTag(tagItems);
        String secret = config.getWxSuiteid() ;
        if(qwDTO.isSelf()) {
            secret = qwDTO.getSelfSecret() ;
        }
        return qywxSuiteApiService.saveCorpTag(corpid, secret, qywxTagGroupDTO , qwDTO.isSelf(),qwDTO.getUrlHost());
    }

    @Override
    public ServiceResponse closeSync(String wxEnterpriseId, String memberTagId) {
        ServiceResponse resp = new ServiceResponse();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        List<TabQywxTagRelation> tagRelations = qywxTagService.listQywxTagRelationByMemberTagId(wxEnterpriseId, memberTagId);
        if (CollectionUtils.isEmpty(tagRelations)) {
            return resp;
        }
        TabQywxTag tabQywxTag = qywxTagService.getQywxTagByQywxTagId(wxEnterpriseId, tagRelations.get(0).getQywxTagId());
        //关闭同步
        qywxTagService.closeSync(wxEnterpriseId, memberTagId);
        List<String> delIds = new ArrayList<>();
        delIds.add(tabQywxTag.getQywxGroupKey());
        QywxResponseDTO responseDTO = qywxSuiteApiService.delCorpTag(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), delIds, 0,qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("关闭同步：{}", JSONObject.toJSONString(responseDTO));
        if (responseDTO.getErrcode() != 0) {
            resp.setMessage(responseDTO.getErrmsg());
            resp.setCode(responseDTO.getErrcode());
            return resp;
        }
        qywxTagService.delQywxTag(tabQywxTag.getQywxGroupKey(), wxEnterpriseId);
        return resp;
    }

    @Override
    public ServiceResponse delGicTagItem(String wxEnterpriseId, String tagItemId) {
        ServiceResponse resp = new ServiceResponse();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        TabQywxTagRelation qywxTagRelation = qywxTagService.getQywxTagRelationByTagItemId(wxEnterpriseId, tagItemId);
        if (null == qywxTagRelation) {
            resp.setMessage("没有同步，无需删除");
            return resp;
        }
        TabQywxTagItem qywxTagItem = qywxTagService.getQywxTagItemById(wxEnterpriseId, qywxTagRelation.getQywxTagItemId());

        List<String> delIds = new ArrayList<>();
        delIds.add(qywxTagItem.getQywxTagKey());
        String secret = config.getWxSuiteid() ;
        if(qwDTO.isSelf()) {
          secret = qwDTO.getSelfSecret() ;
        }
        QywxResponseDTO responseDTO = qywxSuiteApiService.delCorpTag(qwDTO.getThirdCorpid(), secret, delIds, 1,qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("删除标签项：{}", JSONObject.toJSONString(responseDTO));
        if (responseDTO.getErrcode() != 0) {
            resp.setMessage(responseDTO.getErrmsg());
            resp.setCode(responseDTO.getErrcode());
            return resp;
        }

        //删除标签项 以及同步关系
        qywxTagService.delQywxTagItemById(wxEnterpriseId, qywxTagItem.getQywxTagItemId());
        qywxTagService.changeTagRelationStatus(qywxTagRelation.getQywxTagRelationId(), 0);
        return resp;
    }

    @Override
    public List<QywxTagRelationDTO> listAllByWxEnterpriseId(String wxEnterpriseId) {
        List<TabQywxTagRelation> ret = qywxTagService.listAllQywxRelation(wxEnterpriseId);
        return EntityUtil.changeEntityListByJSON(QywxTagRelationDTO.class, ret);
    }

    @Override
    public void addQywxTag(QywxTagCallbackDTO callbackDTO) {
        logger.info("企业微信新增标签回调：{}", JSONObject.toJSONString(callbackDTO));
        if (!config.getWxSuiteid().equals(callbackDTO.getSuiteId())) {
            logger.info("非第三方回调");
            return;
        }
        TabHaobanWxEnterprise wxEnterpriseDto = wxEnterpriseService.getEnterpriseBycorpId(callbackDTO.getAuthCorpId());
        if (null == wxEnterpriseDto) {
            logger.info("企业不存在：{}", callbackDTO.getAuthCorpId());
            return;
        }
        QywxTagRelationTypeEnum relationTypeEnum = QywxTagRelationTypeEnum.getByTagType(callbackDTO.getTagType());
        if (relationTypeEnum == null) {
            logger.error("未找到对应关系，{}", callbackDTO.getTagType());
            return;
        }
        String wxEnterpriseId = wxEnterpriseDto.getWxEnterpriseId() ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        //标签组
        if (Objects.equals(relationTypeEnum.getTagType(), QywxTagRelationTypeEnum.TAG_GROUP.getTagType())) {
            logger.info("新增标签组无需操作：{}", callbackDTO.getTagId());
            List<String> ids = new ArrayList<>();
            ids.add(callbackDTO.getTagId());
            QywxGetCorpTagListDTO tagDetail = qywxSuiteApiService.getCorpTagList(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), ids, QywxTagRelationTypeEnum.TAG_GROUP.getType() , qwDTO.isSelf(),qwDTO.getUrlHost());
            if (tagDetail.getErrcode() != 0) {
                logger.info("没有关联，无需操作：{}", JSONObject.toJSONString(tagDetail));
                return;
            }
            QywxTagGroupDTO qywxTagGroupDTO = tagDetail.getTagGroup().get(0);
            //保存标签项
            qywxTagService.saveQywxTagByQywxGroupKey(wxEnterpriseDto.getWxEnterpriseId(), qywxTagGroupDTO);
            //标签项
        } else if (Objects.equals(relationTypeEnum.getTagType(), QywxTagRelationTypeEnum.TAG_ITEM.getTagType())) {
            //查找对应的标签组  如果标签组关联了
            List<String> ids = new ArrayList<>();
            ids.add(callbackDTO.getTagId());
            QywxGetCorpTagListDTO tagDetail = qywxSuiteApiService.getCorpTagList(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), ids, QywxTagRelationTypeEnum.TAG_ITEM.getType() , qwDTO.isSelf(),qwDTO.getUrlHost());
            if (tagDetail.getErrcode() != 0) {
                logger.info("查询失败，无需操作：{}", JSONObject.toJSONString(tagDetail));
                return;
            }
            if (CollectionUtils.isEmpty(tagDetail.getTagGroup())) {
                logger.info("标签组不存在：{}", JSONObject.toJSONString(tagDetail));
                return;
            }
            QywxTagGroupDTO qywxTagGroupDTO = tagDetail.getTagGroup().get(0);
            //保存标签项
            qywxTagService.saveQywxTagByQywxGroupKey(wxEnterpriseDto.getWxEnterpriseId(), qywxTagGroupDTO);
        }
    }

    @Override
    public void delQywxTag(QywxTagCallbackDTO callbackDTO) {
        logger.info("企业微信删除标签回调：{}", JSONObject.toJSONString(callbackDTO));
        if (!config.getWxSuiteid().equals(callbackDTO.getSuiteId())) {
            logger.info("非第三方回调");
            return;
        }
        TabHaobanWxEnterprise wxEnterpriseDto = wxEnterpriseService.getEnterpriseBycorpId(callbackDTO.getAuthCorpId());
        if (null == wxEnterpriseDto) {
            logger.info("企业不存在：{}", callbackDTO.getAuthCorpId());
            return;
        }
        QywxTagRelationTypeEnum relationTypeEnum = QywxTagRelationTypeEnum.getByTagType(callbackDTO.getTagType());
        if (relationTypeEnum == null) {
            logger.error("未找到对应关系，{}", callbackDTO.getTagType());
            return;
        }
        //标签组
        if (Objects.equals(relationTypeEnum.getTagType(), QywxTagRelationTypeEnum.TAG_GROUP.getTagType())) {
            TabQywxTag qywxGroupKey = qywxTagService.getQywxTagByQywxGroupKey(wxEnterpriseDto.getWxEnterpriseId(), callbackDTO.getTagId());
            if (null == qywxGroupKey) {
                logger.info("原型不存在，不需要处理");
                return;
            }
            List<TabQywxTagRelation> relations = qywxTagService.listQywxTagRelationByQywxTagId(wxEnterpriseDto.getWxEnterpriseId(), qywxGroupKey.getQywxTagId());
            //没有同步的关系 删除保存企业微信标签
            if (CollectionUtils.isEmpty(relations)) {
                logger.info("删除保存的企业微信标签");
                qywxTagService.delQywxTag(callbackDTO.getTagId(), wxEnterpriseDto.getWxEnterpriseId());
                return;
            }
            TabQywxTagRelation relation = relations.stream().findFirst().get();
            logger.info("删除标签组 关闭同步：{}", relation.getMemberTagId());
            //删除同步 关闭同步
            qywxTagService.closeSync(wxEnterpriseDto.getWxEnterpriseId(), relation.getMemberTagId());
            qywxTagService.delQywxTag(callbackDTO.getTagId(), wxEnterpriseDto.getWxEnterpriseId());
            saveCloseTask(qywxGroupKey.getQywxGroupName().substring(3), "-1", relation.getWxEnterpriseId(), relation.getEnterpriseId());
            //标签项
        } else if (Objects.equals(relationTypeEnum.getTagType(), QywxTagRelationTypeEnum.TAG_ITEM.getTagType())) {
            TabQywxTagRelation qywxTagRelation = qywxTagService.getQywxTagRelationByQywxKey(wxEnterpriseDto.getWxEnterpriseId(), callbackDTO.getTagId(), QywxTagRelationTypeEnum.TAG_ITEM.getType());
            if (null == qywxTagRelation) {
                logger.info("没有关联，无需操作");
                qywxTagService.delQywxTagItemById(wxEnterpriseDto.getWxEnterpriseId(), qywxTagRelation.getQywxTagItemId());
                return;
            }
            logger.info("删除标签 关闭同步：{}", qywxTagRelation.getMemberTagId());
            //删除同步 关闭同步
            this.closeSync(wxEnterpriseDto.getWxEnterpriseId(), qywxTagRelation.getMemberTagId());
            TabQywxTag tabQywxTag = qywxTagService.getQywxTagByQywxTagId(qywxTagRelation.getWxEnterpriseId(), qywxTagRelation.getQywxTagId());
            saveCloseTask(tabQywxTag.getQywxGroupName(), "-1", qywxTagRelation.getWxEnterpriseId(), qywxTagRelation.getEnterpriseId());
        }

    }

    private void saveCloseTask(String tagName, String staffId, String wxEnterpriseId, String enterpriseId) {
        String content = tagName + "-关闭标签同步成功";
        qywxTagSyncApiService.saveCloseTask(staffId, wxEnterpriseId, enterpriseId, content, QywxTaskStatusEnum.ALL_SUCCESS.getType());
    }

    @Override
    public void editQywxTag(QywxTagCallbackDTO callbackDTO) {
        logger.info("企业微信修改标签回调：{}", JSONObject.toJSONString(callbackDTO));
        if (!config.getWxSuiteid().equals(callbackDTO.getSuiteId())) {
            logger.info("非第三方回调");
            return;
        }
        TabHaobanWxEnterprise wxEnterpriseDto = wxEnterpriseService.getEnterpriseBycorpId(callbackDTO.getAuthCorpId());
        if (null == wxEnterpriseDto) {
            logger.info("企业不存在：{}", callbackDTO.getAuthCorpId());
            return;
        }
        QywxTagRelationTypeEnum relationTypeEnum = QywxTagRelationTypeEnum.getByTagType(callbackDTO.getTagType());
        if (relationTypeEnum == null) {
            logger.error("未找到对应关系，{}", callbackDTO.getTagType());
            return;
        }
        String wxEnterpriseId = wxEnterpriseDto.getWxEnterpriseId() ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        //标签组
        if (Objects.equals(relationTypeEnum.getTagType(), QywxTagRelationTypeEnum.TAG_GROUP.getTagType())) {
            //判断是否存在关联 存在需要同步回去
            TabQywxTagRelation relaton = qywxTagService.getQywxTagRelationByQywxKey(wxEnterpriseDto.getWxEnterpriseId(), callbackDTO.getTagId(), QywxTagRelationTypeEnum.TAG_GROUP.getType());
            if (null == relaton) {
                logger.info("原型不存在，不需要处理");
                return;
            }
            //名称同步回去
            TabQywxTag qywxGroupKey = qywxTagService.getQywxTagByQywxGroupKey(wxEnterpriseDto.getWxEnterpriseId(), callbackDTO.getTagId());
            QywxTagDTO qywxTagDTO = new QywxTagDTO();
            qywxTagDTO.setId(callbackDTO.getTagId());
            qywxTagDTO.setName(qywxGroupKey.getQywxGroupName());
            qywxTagDTO.setOrder(qywxGroupKey.getOrder());
            qywxSuiteApiService.editCorpTagNameOrOrder(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), qywxTagDTO , qwDTO.isSelf(),qwDTO.getUrlHost());

            //标签项
        } else if (Objects.equals(relationTypeEnum.getTagType(), QywxTagRelationTypeEnum.TAG_ITEM.getTagType())) {
            TabQywxTagItem qywxTagItem = qywxTagService.getQywxTagItemByQywxItemKey(wxEnterpriseDto.getWxEnterpriseId(), callbackDTO.getTagId());
            if (null == qywxTagItem) {
                logger.info("没有关联，无需操作");
                return;
            }
            List<TabQywxTagRelation> relations = qywxTagService.listQywxTagRelationByQywxTagId(wxEnterpriseDto.getWxEnterpriseId(), qywxTagItem.getQywxTagId());
            if (CollectionUtils.isEmpty(relations)) {
                logger.info("直接删除标签项");
                qywxTagService.delQywxTagItemById(wxEnterpriseDto.getWxEnterpriseId(), qywxTagItem.getQywxTagItemId());
                return;
            }
            //名称同步回去
            QywxTagDTO qywxTagDTO = new QywxTagDTO();
            qywxTagDTO.setId(callbackDTO.getTagId());
            qywxTagDTO.setName(qywxTagItem.getQywxTagName());
            qywxTagDTO.setOrder(qywxTagItem.getOrder());
            qywxSuiteApiService.editCorpTagNameOrOrder(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), qywxTagDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        }
    }

    @Override
    public ServiceResponse syncFriendTagToQywxByExternalUserId(String wxEnterpriseId, String enterpriseId, String externalUserId, List<String> tagItemIds) {
        logger.info("同步好友标签到企业微信：externalUserId={},{}", externalUserId, JSONObject.toJSONString(tagItemIds));
        ServiceResponse resp = new ServiceResponse();
        //获取需要同步的标签
        QywxSyncTagFormatPojo syncTagFormat = listSyncTagItems(wxEnterpriseId);
        if (syncTagFormat == null) {
            logger.info("没有需要同步的标签");
            resp.setCode(2);
            resp.setMessage("没有要同步的标签");
            return resp;
        }
        //该会员要同步的打的企业微信标签 该商户下
        Set<String> entQywxTagKeys = tagItemIds.stream().filter(tagItemId -> syncTagFormat.getGicToQywxTagItemIdMap().containsKey(tagItemId))
                .map(tagItemId -> syncTagFormat.getGicToQywxTagItemIdMap().get(tagItemId)).collect(Collectors.toSet());

        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        //查询外部联系人
        String wxSuiteid = config.getWxSuiteid();
        String externalUseridInfo =  null ;
        if(qwDTO.isSelf()) {
            externalUseridInfo = this.qywxUserApiService.getCorpSelfExternalUseridInfo(qwDTO.getDkCorpid(), qwDTO.getSelfSecret(), externalUserId,qwDTO.getUrlHost()) ;
        }else {
            externalUseridInfo = this.qywxUserApiService.getExternalUseridInfo(qwDTO.getThirdCorpid(), wxSuiteid, externalUserId);
        }
        if (StringUtils.isBlank(externalUseridInfo)) {
            logger.info("好友不存在");
            resp.setCode(3);
            resp.setMessage("好友不存在");
            return resp;
        } else if (externalUseridInfo.equals("1")) {
            logger.info("限制次数");
            resp.setCode(45033);
            resp.setMessage("getExternalUseridInfo接口次数限制");
            return resp;
        }
        Map<String, Set<String>> externalTagMap = getExternalTagMap(externalUseridInfo, wxEnterpriseId);
        if (null == externalTagMap) {
            logger.info("没有好友需要同步");
            resp.setCode(5);
            resp.setMessage("没有好友需要同步");
            return resp;
        }

        //商户下设置同步的企业微信标签keys
        Set<String> entQywxTagSyncKeys = syncTagFormat.getEntQywxTagKeysMap().get(enterpriseId);
        if (CollectionUtils.isEmpty(entQywxTagSyncKeys)) {
            logger.info("该商户下没有标签");
            resp.setCode(6);
            resp.setMessage("该商户下没有标签");
            return resp;
        }
        //同步好友
        externalTagMap.forEach((wxUserId, haveTagKes) -> {
            //该用户在该商户下打的标签
            Sets.SetView<String> entHasSetQywxTagKeys = Sets.intersection(haveTagKes, entQywxTagSyncKeys);
            //获取需要打的标签
            Sets.SetView<String> needSetTags = Sets.difference(entQywxTagKeys, entHasSetQywxTagKeys);
            //需要删除的标签
            Sets.SetView<String> needDelTags = Sets.difference(entHasSetQywxTagKeys, entQywxTagKeys);
            logger.info("该用户打标签：{}",wxUserId);
            if (CollectionUtils.isEmpty(needDelTags) && CollectionUtils.isEmpty(needSetTags)) {
                logger.info("不需要操作：{},{}", wxUserId, externalUserId);
                return;
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("corpid", qwDTO.getThirdCorpid());
            jsonObject.put("suiteId", wxSuiteid);
            jsonObject.put("wxUserId", wxUserId);
            jsonObject.put("externalUserId", externalUserId);
            if (CollectionUtils.isNotEmpty(needSetTags)) {
                jsonObject.put("needSetTags", StringUtils.join(needSetTags, ","));
            }
            if (CollectionUtils.isNotEmpty(needDelTags)) {
                jsonObject.put("needDelTags", StringUtils.join(needDelTags, ","));
            }
            GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
            try {
                logger.info("qywxMarkTagMq 该用户打标签：{}",jsonObject.toJSONString());
                clientInstance.sendMessage("qywxMarkTagMq", jsonObject.toJSONString());
            } catch (Exception e) {
                logger.info("企微标签同步qywxMarkTagMq发送失败：{}", e.getMessage(), e);
            }
        });
        return resp;
    }

    /**
     * 获取以及同步的标签序列表
     */
    private QywxSyncTagFormatPojo listSyncTagItems(String wxEnterpriseId) {
        QywxSyncTagFormatPojo pojo = new QywxSyncTagFormatPojo();
        List<TabQywxTagRelation> relations = qywxTagService.listAllQywxRelation(wxEnterpriseId);
        if (CollectionUtils.isEmpty(relations)) {
            return null;
        }
        //企业微信标签key 关联对应的 gic标签关系
        Map<String, TabQywxTagRelation> relationMap = relations.stream().filter(dto -> dto.getRelationType() == QywxTagRelationTypeEnum.TAG_ITEM.getType()).collect(Collectors.toMap(dto -> dto.getQywxTagItemId(), dto -> dto));
        if (MapUtils.isEmpty(relationMap)) {
            return null;
        }
        List<String> syncTagItemsIds = relationMap.keySet().stream().collect(Collectors.toList());

        //同步的标签项
        List<TabQywxTagItem> tagItems = qywxTagService.listQywxTagItemByIds(wxEnterpriseId, syncTagItemsIds);
        //企业微信标签id 对应的标签
        Map<String, TabQywxTagItem> qywxTagItemMap = tagItems.stream().collect(Collectors.toMap(dto -> dto.getQywxTagItemId(), dto -> dto));

        //企业微信标签与gic标签id的对应关系
        Map<String, String> qywxToGicTagItemIdMap = syncTagItemsIds.stream().collect(Collectors.toMap(qywxTagId -> qywxTagItemMap.get(qywxTagId).getQywxTagKey(), qywxTagId -> relationMap.get(qywxTagId).getTagItemId()));
        //gic标签与企业微信标签id的对应关系
        Map<String, String> gicToQywxTagItemIdMap = syncTagItemsIds.stream().collect(Collectors.toMap(qywxTagId -> relationMap.get(qywxTagId).getTagItemId(), qywxTagId -> qywxTagItemMap.get(qywxTagId).getQywxTagKey()));
        //gic商户对应的已经同步的gic标签项列表
        Map<String, Set<String>> entGicTagItemIdMap = relations.stream().filter(dto -> dto.getRelationType() == QywxTagRelationTypeEnum.TAG_ITEM.getType())
                .collect(Collectors.groupingBy(dto -> dto.getEnterpriseId(), Collectors.mapping(dto -> dto.getTagItemId(), Collectors.toSet())));
        //gic商户对应的已经同步的企业微信表亲列表
        Map<String, Set<String>> entQywxTagKeysMap = relations.stream().filter(dto -> dto.getRelationType() == QywxTagRelationTypeEnum.TAG_ITEM.getType())
                .collect(Collectors.groupingBy(dto -> dto.getEnterpriseId(), Collectors.mapping(dto -> gicToQywxTagItemIdMap.get(dto.getTagItemId()), Collectors.toSet())));

        pojo.setEntGicTagItemIdMap(entGicTagItemIdMap);
        pojo.setEntQywxTagKeysMap(entQywxTagKeysMap);
        pojo.setGicToQywxTagItemIdMap(gicToQywxTagItemIdMap);
        pojo.setQywxToGicTagItemIdMap(qywxToGicTagItemIdMap);
        return pojo;
    }


    @Override
    public ServiceResponse syncQywxTagToGicByExternalUserId(String wxEnterpriseId, String externalUserId, String wxUserId) {
        //刷新标签的时候不允许同步
        ServiceResponse resp = new ServiceResponse();
        //所有以及关联同步的标签
        QywxSyncTagFormatPojo syncTagFormatPojo = listSyncTagItems(wxEnterpriseId);
        if (syncTagFormatPojo == null) {
            logger.info("没有需要同步的标签,wxUserId:{},externalUserId:{},wxId:{}", wxUserId, externalUserId, wxEnterpriseId);
            resp.setMessage("没有需要同步的标签");
            return resp;
        }
        //企业微信同步的标签key
        Set<String> qywxTagKeys = syncTagFormatPojo.getQywxToGicTagItemIdMap().keySet();

        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        //查询外部联系人
        String externalUseridInfo = null ;
        if(qwDTO.isSelf()) {
            externalUseridInfo = this.qywxUserApiService.getCorpSelfExternalUseridInfo(qwDTO.getDkCorpid(), qwDTO.getSelfSecret(), externalUserId,qwDTO.getUrlHost()) ;
        }else {
            externalUseridInfo = this.qywxUserApiService.getExternalUseridInfo(qwDTO.getThirdCorpid(), config.getWxSuiteid(), externalUserId);
        }
        if (StringUtils.isBlank(externalUseridInfo)) {
            logger.info("好友不存在");
            resp.setCode(2);
            resp.setMessage("好友不存在");
            return resp;
        } else if (externalUseridInfo.equals("1")) {
            logger.info("限制次数");
            resp.setCode(45033);
            resp.setMessage("限制次数");
            return resp;
        }
        Map<String, Set<String>> externalTagMap = getExternalTagMap(externalUseridInfo, wxEnterpriseId);
        if (MapUtils.isEmpty(externalTagMap)) {
            logger.info("该用户没有不存在好友关系，获取不到关联导购打的标签，：externalUseridInfo:{}", externalUseridInfo);
            resp.setMessage("该用户没有不存在好友关系，获取不到关联导购打的标签");
            return resp;
        }
        //当前操作用户企业打的标签
        Set<String> staffChangeTagKeys = externalTagMap.get(wxUserId);
        if (CollectionUtils.isEmpty(staffChangeTagKeys)) {
            logger.info("该用户没有不存在好友关系，获取不到关联导购打的标签,wxUserId:{}", wxUserId);
            resp.setMessage("该用户没有不存在好友关系，获取不到关联导购打的标签");
            return resp;
        }
        Sets.SetView<String> staffHasSetTagKeys = Sets.intersection(staffChangeTagKeys, qywxTagKeys);

        //获取该外部联系人的所有会员
        List<TabHaobanExternalClerkRelated> clerkRelateds = externalClerkRelatedService.listExternalByExternalUserid(wxEnterpriseId, externalUserId);
        if (CollectionUtils.isEmpty(clerkRelateds)) {
            logger.info("该用户没关联对应的好友：{}", externalUserId);
            resp.setMessage("该用户没关联对应的好友");
            return resp;
        }
        //企业下的企业微信标签对应关系
        Map<String, Set<String>> entQywxTagKeysMap = syncTagFormatPojo.getEntQywxTagKeysMap();
        Map<String, Set<String>> entGicTagItemIdMap = syncTagFormatPojo.getEntGicTagItemIdMap();

        List<String> hasSaveMemberId = new ArrayList<>();
        for (TabHaobanExternalClerkRelated clerkRelated : clerkRelateds) {
            logger.info("需要处理的好友：{}", JSONObject.toJSONString(clerkRelated));
            //该会员在该企业已经同步 无需同步
            if (hasSaveMemberId.contains(clerkRelated.getMemberId())) {
                continue;
            }
            hasSaveMemberId.add(clerkRelated.getMemberId());

            //该会员所在企业下 配置的同步的标签列表
            Set<String> entQywxSyncTagKeys = entQywxTagKeysMap.get(clerkRelated.getEnterpriseId());
            Set<String> entQywxSyncTagItemIds = entGicTagItemIdMap.get(clerkRelated.getEnterpriseId());
            if (CollectionUtils.isEmpty(entQywxSyncTagKeys)) {
                logger.info("该企业下没有配置需要同步的：{},{}", externalUserId, clerkRelated.getEnterpriseId());
                continue;
            }
            String memberId = externalClerkRelatedService.checkAndUpdateMemberByUnonId(clerkRelated.getEnterpriseId(), clerkRelated.getMemberId(), clerkRelated.getUnionid());
            if (null == memberId) {
                logger.info("会员不存在:{}", externalUserId);
                continue;
            }
            //该会员打的标签
            List<MemberTagDTO> gicItems = memberTagService.listMemberTag(clerkRelated.getEnterpriseId(), memberId);
            Set<String> noSyncTagItemIds = new HashSet<>();
            if (!CollectionUtils.isEmpty(gicItems)) {
                noSyncTagItemIds = gicItems.stream().filter(item -> !entQywxSyncTagItemIds.contains(item.getTagsId())).map(dto -> dto.getTagsId()).collect(Collectors.toSet());
                logger.info("没有同步的标签：{}", JSONObject.toJSONString(noSyncTagItemIds));
            }
            //该企业下会员需要设置的标签
            Sets.SetView<String> entMemberNeedSetQywxKeys = Sets.intersection(staffHasSetTagKeys, entQywxSyncTagKeys);
            Set<String> saveTagIds = entMemberNeedSetQywxKeys.stream().map(qywxKey -> syncTagFormatPojo.getQywxToGicTagItemIdMap().get(qywxKey)).collect(Collectors.toSet());
            saveTagIds.addAll(noSyncTagItemIds);
            logger.info("该企业会员需要打的标签：{}", JSONObject.toJSONString(entMemberNeedSetQywxKeys));
            //更新标签 会自动同步
            if (CollectionUtils.isEmpty(saveTagIds)) {
                saveMemberTags(new HashSet<>(), clerkRelated.getEnterpriseId(), memberId, clerkRelated.getClerkId());
            } else {
                saveMemberTags(saveTagIds, clerkRelated.getEnterpriseId(), memberId, clerkRelated.getClerkId());
            }
        }
        return resp;
    }

    private void saveMemberTags(Set<String> tagItemIds, String enterpriseId, String memberId, String clerkId) {
        List<MemberTagDTO> list = tagItemIds.stream().map(tagId -> {
            MemberTagDTO memberTagDTO = new MemberTagDTO();
            memberTagDTO.setTagsId(tagId);
            memberTagDTO.setEnterpriseId(enterpriseId);
            memberTagDTO.setMemberId(memberId);
            memberTagDTO.setClerkId(clerkId);
            return memberTagDTO;
        }).collect(Collectors.toList());

        logger.info("会员打标签：{}", JSONObject.toJSONString(list));
        if (CollectionUtils.isEmpty(list)) {
            logger.info("会员打标签list为空");
            return;
        }
        memberTagService.saveOrUpdateMemberTagHB(enterpriseId, list, memberId);
    }


    /**
     * 获取企业微信的外部联系人的所有联系关系
     *
     * @param externalUseridInfo
     * @return
     */
    private Map<String, Set<String>> getExternalTagMap(String externalUseridInfo, String wxEnterpriseId) {
        logger.info("externalUseridInfo:{}", externalUseridInfo);
        Map<String, Set<String>> ret = new HashMap<>();
        JSONObject jsonObject = JSONObject.parseObject(externalUseridInfo);

        if (!jsonObject.containsKey("follow_user")) {
            logger.info("没有相关的好友");
            return null;
        }

        JSONArray followUser = jsonObject.getJSONArray("follow_user");
        for (int i = 0; i < followUser.size(); i++) {
            JSONObject midUser = followUser.getJSONObject(i);
            String wxUserId = midUser.getString("userid");
            Set<String> midTagIds = new HashSet<>();
            if (!midUser.containsKey("tags")) {
                ret.put(wxUserId, midTagIds);
                continue;
            }
            JSONArray tags = midUser.getJSONArray("tags");
            for (int n = 0; n < tags.size(); n++) {
                JSONObject tagMid = tags.getJSONObject(n);
                String tagId = tagMid.getString("tag_id");
                String tagType = tagMid.getString("type");
                if (tagType.equals("1")) {
                    midTagIds.add(tagId);
                }
            }
            ret.put(wxUserId, midTagIds);
        }
        return ret;
    }

    @Override
    public void changeQywxTagStatus(String memberTagId, String wxEnterpriseId, int status) {
        qywxTagService.changeRelationSyncFlagByMemberTagId(wxEnterpriseId, memberTagId, status);
    }

    @Override
    public boolean saveRelation(String wxEnterpriseId, String enterpriseId, List<String> memberTagIds) {
        if (CollectionUtils.isEmpty(memberTagIds)) {
            return false;
        }
        return false;
    }

    @Override
    public ServiceResponse renameQywxTag(String wxEnterpriseId, String id, String name, Integer type) {
        ServiceResponse resp = new ServiceResponse();
        String renameQywxKey = null;
        Long order = null;
        String relationId = null;
        //标签组
        if (type == QywxTagRelationTypeEnum.TAG_GROUP.getType()) {

            TabQywxTag tabQywxTag = qywxTagService.getQywxTagByQywxTagId(wxEnterpriseId, id);
            if (null == tabQywxTag) {
                resp.setMessage("没有关联无需处理");
                return resp;
            }
            renameQywxKey = tabQywxTag.getQywxGroupKey();
            order = tabQywxTag.getOrder();
            name = "GIC" + name;
            relationId = tabQywxTag.getQywxTagId();
        } else if (type == QywxTagRelationTypeEnum.TAG_ITEM.getType()) {
            TabQywxTagItem qywxTagItem = qywxTagService.getQywxTagItemById(wxEnterpriseId, id);
            if (null == qywxTagItem) {
                resp.setMessage("没有关联无需处理");
                return resp;
            }
            renameQywxKey = qywxTagItem.getQywxTagKey();
            order = qywxTagItem.getOrder();
            relationId = qywxTagItem.getQywxTagItemId();
        }
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        //名称同步回去
        QywxTagDTO qywxTagDTO = new QywxTagDTO();
        qywxTagDTO.setId(renameQywxKey);
        qywxTagDTO.setName(name);
        qywxTagDTO.setOrder(order);
        QywxResponseDTO responseDTO = qywxSuiteApiService.editCorpTagNameOrOrder(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), qywxTagDTO , qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("同步名称：{}", JSONObject.toJSONString(responseDTO));
        if (responseDTO.getErrcode() != 0) {
            resp.setMessage(responseDTO.getErrmsg());
            resp.setCode(responseDTO.getErrcode());
        }
        qywxTagService.saveQywxTagOrTagItemName(relationId, name, type);
        return resp;
    }

    @Override
    public List<QywxTagRelationDTO> listQywxTagRelationByMemberTagId(String wxEnterpriseId, String memberTagId) {
        List<TabQywxTagRelation> tagRelations = qywxTagService.listQywxTagRelationByMemberTagId(wxEnterpriseId, memberTagId);
        return EntityUtil.changeEntityListByJSON(QywxTagRelationDTO.class, tagRelations);
    }

//    @Override
//    public QywxTagRelationDTO getQywxTagRelationByRelationId(String relationId) {
//        TabQywxTagRelation tagRelation = qywxTagService.getQywxTagRelationById(relationId);
//        return EntityUtil.changeEntityByJSON(QywxTagRelationDTO.class, tagRelation);
//    }

    @Override
    public QywxTagInfoDTO getQywxTagByQywxTagId(String qywxTagId) {
        TabQywxTag tabQywxTag = qywxTagService.getQywxTagByQywxTagId(null, qywxTagId);
        return EntityUtil.changeEntityByJSON(QywxTagInfoDTO.class, tabQywxTag);
    }


    @Override
    public void updateQywxTagRelationSyncStatusByTagItemId(String wxEnterpriseId, String tagItemId) {
        qywxTagService.changeRelationSyncFlagByTagItemId(wxEnterpriseId, tagItemId, 2);
    }

    @Override
    public void checkQywxSync(String params) {
        List<TabHaobanWxEnterprise> wxEnterprises = wxEnterpriseService.listAll();
        wxEnterprises.forEach(wxEnterprise -> {
            logger.info("企业：{}", wxEnterprise.getWxEnterpriseId());
            try {
                List<TabQywxTagRelation> tagRelations = qywxTagService.listAllQywxRelation(wxEnterprise.getWxEnterpriseId());
                if (CollectionUtils.isEmpty(tagRelations)) {
                    logger.info("无需校验: 没有要同步的企业");
                    return;
                }
                QywxSyncTagFormatPojo pojo = this.listSyncTagItems(wxEnterprise.getWxEnterpriseId());

                List<TabQywxTagRelation> qywxTagRelations = tagRelations.stream().filter(dto -> dto.getRelationType() == QywxTagRelationTypeEnum.TAG_GROUP.getType()).collect(Collectors.toList());
                for (TabQywxTagRelation qywxTagRelation : qywxTagRelations) {
                    Map<String, Object> map = checkQywxSyncByQywxTag(qywxTagRelation, wxEnterprise, pojo);
                    if (MapUtils.isNotEmpty(map)) {
                        logger.error("企微与好办同步标签不相同:{}", JSON.toJSONString(map));
                    }
                }
            } catch (Exception e) {
                logger.info("校验异常：{}", e);
            }
        });


    }

    /**
     * 校验
     *
     * @param relation
     * @param wxEnterprise
     */
    private LinkedHashMap<String, Object> checkQywxSyncByQywxTag(TabQywxTagRelation relation, TabHaobanWxEnterprise wxEnterprise, QywxSyncTagFormatPojo pojo) {
        LinkedHashMap<String, Object> ret = new LinkedHashMap<>();
        boolean flag = false;
        ret.put("hb标签id", relation.getQywxTagId());

        TabQywxTag tabQywxTag = qywxTagService.getQywxTagByQywxTagId(relation.getWxEnterpriseId(), relation.getQywxTagId());
        if (null == tabQywxTag) {
            logger.info("数据库不存在该企业微信标签：{}", relation.getQywxTagId());
            ret.put("描述", "标签数据库不存在:" + relation.getTagItemId());
            return ret;
        }
        ret.put("名称(标签)", tabQywxTag.getQywxGroupName());
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(relation.getWxEnterpriseId()) ;
        List<String> ids = new ArrayList<>();
        ids.add(tabQywxTag.getQywxGroupKey());
        QywxGetCorpTagListDTO tagDetail = qywxSuiteApiService.getCorpTagList(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), ids, QywxTagRelationTypeEnum.TAG_GROUP.getType() , qwDTO.isSelf(),qwDTO.getUrlHost());
        if (tagDetail.getErrcode() != 0) {
            logger.info("查询失败，无需操作：{}", JSONObject.toJSONString(tagDetail));
            ret.put("描述", "查询失败:" + tagDetail.getErrmsg());
            return ret;
        }
        if (CollectionUtils.isEmpty(tagDetail.getTagGroup())) {
            logger.info("标签组不存在：{}", JSONObject.toJSONString(tagDetail));
            ret.put("描述", "标签组不存在:" + tabQywxTag.getQywxGroupName());
            return ret;
        }


        //获取该标签已经绑定的标签项key
        Map<String, String> qywxToGicTagItemIdMap = pojo.getQywxToGicTagItemIdMap();

        List<TabQywxTagItem> gicQywxSyncTagItems = qywxTagService.listByQywxTagId(wxEnterprise.getWxEnterpriseId(), relation.getQywxTagId());
        Map<String, String> gicQywxTagNameMap = gicQywxSyncTagItems.stream().filter(tab -> qywxToGicTagItemIdMap.containsKey(tab.getQywxTagKey())).collect(Collectors.toMap(mid -> mid.getQywxTagKey(), mid -> mid.getQywxTagName()));
        if (CollectionUtils.isEmpty(gicQywxSyncTagItems)) {
            logger.info("gic同步企业微信标签异常");
            ret.put("描述", "gic同步企业微信标签异常:" + tabQywxTag.getQywxGroupName());
            return ret;
        }
        Set<String> gicQywxKeysSet = gicQywxTagNameMap.keySet();

        //获取企业微信的标签项key
        QywxTagGroupDTO qywxTagGroupDTO = tagDetail.getTagGroup().get(0);
        List<QywxTagDTO> tagItems = qywxTagGroupDTO.getTag();
        if (CollectionUtils.isEmpty(tagItems)) {
            ret.put("描述", "企业微信标签项空:" + tabQywxTag.getQywxGroupName());
            return ret;
        }
        Map<String, QywxTagDTO> qywxTagDTOMap = tagItems.stream().collect(Collectors.toMap(dto -> dto.getId(), dto -> dto));
        Set<String> qywxKeysSet = qywxTagDTOMap.keySet();

        //gic没有同步的标签项
        Map<String, String> gicToQywxTagItemIdMap = pojo.getGicToQywxTagItemIdMap();
        List<MemberTagItemDTO> gicTagItems = memberTagItemApiService.getItemListByTagId(relation.getMemberTagId());
        Set<MemberTagItemDTO> noSyncTags = gicTagItems.stream().filter(dto -> !gicToQywxTagItemIdMap.containsKey(dto.getTagItemId())).collect(Collectors.toSet());

        //在gic存在 企业微信不存在
        Sets.SetView<String> qywxUnHaves = Sets.difference(gicQywxKeysSet, qywxKeysSet);
        //企业微信存在 gic不存在
        Sets.SetView<String> gicUnHaves = Sets.difference(qywxKeysSet, gicQywxKeysSet);

        ret.put("现企微标签项", tagItems.stream().map(dto -> dto.getName()).collect(Collectors.joining("],[", "[", "]")));
        ret.put("现gic标签项", gicTagItems.stream().map(dto -> dto.getTagItemName()).collect(Collectors.joining("],[", "[", "]")));

        //企业微信缺少
        if (!CollectionUtils.isEmpty(qywxUnHaves)) {
            flag = true;
            ret.put("标签项缺少(企微)", qywxUnHaves.stream().map(mid -> gicQywxTagNameMap.get(mid)).collect(Collectors.joining("],[", "[", "]")));
        }

        //未同步标签项
        if (!CollectionUtils.isEmpty(noSyncTags)) {
            flag = true;
            ret.put("标签项未同步", noSyncTags.stream().map(mid -> mid.getTagItemName()).collect(Collectors.joining("],[", "[", "]")));
        }

        //gic缺少
        if (!CollectionUtils.isEmpty(gicUnHaves)) {
            flag = true;
            ret.put("标签项缺少(gic)", gicUnHaves.stream().map(id -> qywxTagDTOMap.get(id).getName()).collect(Collectors.joining("],[", "[", "]")));
        }

        if (flag) {
            return ret;
        }
        return null;

    }

    @Override
    public void qywxMarkTag(String param) {
        if (StringUtils.isBlank(param)) {
            logger.info("标签数据为空");
            return;
        }
        logger.info("企微标签同步：{}",param);
        JSONObject jsonObject = JSON.parseObject(param);
        String corpid = jsonObject.getString("corpid");
        String suiteId = jsonObject.getString("suiteId");
        String wxUserId = jsonObject.getString("wxUserId");
        String externalUserId = jsonObject.getString("externalUserId");
        String needSetTags = jsonObject.getString("needSetTags");
        String needDelTags = jsonObject.getString("needDelTags");
        String key = "HAOBAN:QYWX:TAG:" + wxUserId + externalUserId;
        Integer currentTimes = Convert.toInt(RedisUtil.getCache(key), 0);
        if (currentTimes > MAX_TIMES) {
            logger.error("企微打标签超过最大次数，key：{}", key);
            return;
        }
        List<String> needSetTagList = new ArrayList<>();
        List<String> needDelTagList = new ArrayList<>();
        if (StringUtils.isNotBlank(needSetTags)) {
            needSetTagList = Arrays.asList(needSetTags.split(","));
        }
        if (StringUtils.isNotBlank(needDelTags)) {
            needDelTagList = Arrays.asList(needDelTags.split(","));
        }
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpid) ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterprise.getWxEnterpriseId()) ;
        QywxResponseDTO responseDTO = qywxUserApiService.markTag(corpid, qwDTO.getSelf3thSecret(), wxUserId, externalUserId, needSetTagList, needDelTagList , qwDTO.isSelf() ,qwDTO.getUrlHost());
        logger.info("操作返回：{}", JSONObject.toJSONString(responseDTO));
        if (responseDTO.getErrcode() != 0) {
            logger.info("权限不对，重试三次:{},{}", wxUserId, externalUserId);
            GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
            try {
                clientInstance.sendMessage("qywxMarkTagMq", jsonObject.toJSONString(), 30);
            } catch (Exception e) {
                logger.info("企微标签同步qywxMarkTagMq发送失败：{}", e.getMessage(), e);
            }
            RedisUtil.setCache(key, currentTimes + 1, 2L, TimeUnit.HOURS);
        }
    }
}
