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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
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.clerk.api.service.RightService;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.base.api.common.errCode.HaoBanErrCodeCommon;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.hm.HmClerkDTO;
import com.gic.haoban.manage.api.dto.hm.HmQrcodeDTO;
import com.gic.haoban.manage.api.dto.hm.HmQrcodeStoreDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmClerkRelationQDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmQrcodeListQDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmQrcodeQDTO;
import com.gic.haoban.manage.api.enums.ChannelCodeEnum;
import com.gic.haoban.manage.api.enums.WelcomeRelationStatusEnum;
import com.gic.haoban.manage.api.enums.hm.HmWelcomeReferType;
import com.gic.haoban.manage.api.service.hm.HmQrcodeApiService;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.pojo.bo.hm.HmClerkRelationBO;
import com.gic.haoban.manage.service.pojo.bo.hm.HmGroupSettingBO;
import com.gic.haoban.manage.service.pojo.bo.hm.HmQrcodeBO;
import com.gic.haoban.manage.service.pojo.bo.hm.HmQrcodeClerkBO;
import com.gic.haoban.manage.service.pojo.bo.hm.HmWelcomeRelationBO;
import com.gic.haoban.manage.service.pojo.bo.welcome.WelcomeDetailBO;
import com.gic.haoban.manage.service.service.StaffClerkRelationService;
import com.gic.haoban.manage.service.service.StaffService;
import com.gic.haoban.manage.service.service.WelcomeService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.hm.HmClerkRelationService;
import com.gic.haoban.manage.service.service.hm.HmGroupService;
import com.gic.haoban.manage.service.service.hm.HmQrcodeService;
import com.gic.haoban.manage.service.service.hm.WelcomeRelationService;
import com.gic.haoban.manage.service.service.impl.log.LogRecordAfterServiceImpl;
import com.gic.haoban.manage.service.util.QwFriendLimitCountUtil;
import com.gic.log.record.anno.GicLogRecord;
import com.gic.log.record.util.GicLogRecordCategoryEnum;
import com.gic.log.record.util.GicLogRecordEvaluationContext;
import com.gic.log.record.util.GicLogRecordOptTypeEnum;
import com.gic.member.tag.api.dto.MemberTagDTO;
import com.gic.member.tag.api.dto.MemberTagItemDTO;
import com.gic.member.tag.api.service.MemberTagApiService;
import com.gic.mq.sdk.GicMQClient;
import com.gic.redis.data.util.RedisUtil;
import com.gic.wechat.api.dto.qywx.response.QywxResponseDTO;
import com.gic.wechat.api.dto.qywx.welcome.QywxExternalcontactDTO;
import com.gic.wechat.api.dto.qywx.welcome.QywxExternalcontactResultDTO;
import com.gic.wechat.api.service.qywx.QywxUserApiService;

import cn.hutool.core.convert.Convert;

/**
 * @author mozhu
 * @date 2022/7/5 09:34
 */
@Service
public class HmQrcodeApiServiceImpl implements HmQrcodeApiService {

    private static Logger logger = LoggerFactory.getLogger(HmQrcodeApiServiceImpl.class);

    @Autowired
    private HmQrcodeService hmQrcodeService;
    @Autowired
    private QywxUserApiService qywxUserApiService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private Config config;
    @Autowired
    private StaffClerkRelationService staffClerkRelationService;
    @Autowired
    private HmClerkRelationService hmClerkRelationService;
    @Autowired
    private ClerkService clerkService;
    @Autowired
    private StoreService storeService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private WelcomeRelationService welcomeRelationService;
    @Autowired
    private HmGroupService hmGroupService;
    @Autowired
    private MemberTagApiService memberTagApiService;
    @Autowired
    private WelcomeService welcomeService;
    @Autowired
    private RightService rightService;

    @GicLogRecord(value = "新增员工活码-${#logContent}",
            category = GicLogRecordCategoryEnum.HUOMA,
            optType = GicLogRecordOptTypeEnum.HUOMA_ADD,
            optPage = "活码管理-新增员工活码",
            afterFunc = LogRecordAfterServiceImpl.class)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResponse add(HmQrcodeQDTO hmQrcodeQDTO) {
        String wxEnterpriseId = hmQrcodeQDTO.getWxEnterpriseId();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
        if (qwDTO == null) {
            logger.error("未查询到微信企业");
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "微信企业不存在");
        }
        hmQrcodeQDTO.setHmId(UniqueIdUtils.uniqueLong());
        Integer hmType = hmQrcodeQDTO.getHmType();
        Long hmId = hmQrcodeQDTO.getHmId();
        if (hmType == 1) {
            hmQrcodeQDTO.setHmCode("HM01" + hmId);
        } else {
            hmQrcodeQDTO.setHmCode("HM02" + hmId);
        }
        Long hmGroupId = hmQrcodeQDTO.getHmGroupId();
        if (hmGroupId == null) {
            hmQrcodeQDTO.setHmGroupId(0L);
        }

        List<String> clerkIdList = setStoreClerk(hmQrcodeQDTO, wxEnterpriseId, hmId, hmType, true);
        if (CollectionUtils.isEmpty(clerkIdList)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "该导购已经生成过活码或未关联过好办");
        }
        //生成活码
        QywxExternalcontactDTO qywxExternalcontactDTO = new QywxExternalcontactDTO();
        qywxExternalcontactDTO.setType(hmQrcodeQDTO.getHmType());
        qywxExternalcontactDTO.setScene(2);
        qywxExternalcontactDTO.setRemark(hmQrcodeQDTO.getName());
        qywxExternalcontactDTO.setSkipVerify(hmQrcodeQDTO.getPassFlag() == 1);
        qywxExternalcontactDTO.setState("HM" + hmId);
        List<String> userIds = staffClerkRelationService.listWxUserIdByClerkIds(clerkIdList, wxEnterpriseId);
        if (CollectionUtils.isEmpty(userIds)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "导购未关联好办");
        }
        qywxExternalcontactDTO.setUser(userIds);
        logger.info("新增活码参数：{}", JSON.toJSONString(qywxExternalcontactDTO));
        QywxExternalcontactResultDTO qywxExternalcontactResultDTO = qywxUserApiService.addContactWay(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), qywxExternalcontactDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        if (qywxExternalcontactResultDTO.getErrcode() != 0) {
            GicLogRecordEvaluationContext.noWriteLog();
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_0.getCode()), "创建企微活码失败,具体失败原因请参考企微报错http链接：" + qywxExternalcontactResultDTO.getErrmsg());
        }
        hmQrcodeQDTO.setWxQrcode(qywxExternalcontactResultDTO.getQr_code());
        hmQrcodeQDTO.setWxConfigId(qywxExternalcontactResultDTO.getConfig_id());

        //操作日志
        addLog(hmQrcodeQDTO);

        int saveResult = hmQrcodeService.insert(hmQrcodeQDTO);
        if (saveResult == 1) {
            // save welcome relation
            this.updateWelcomeRelation(hmQrcodeQDTO, null);
        }

        return ServiceResponse.success();
    }

    /**
     * 新增操作日志
     *
     * @param hmQrcodeQDTO
     */
    private void addLog(HmQrcodeQDTO hmQrcodeQDTO) {
        Integer invokingType = hmQrcodeQDTO.getInvokingType();
        if (invokingType == 0) {
            GicLogRecordEvaluationContext.noWriteLog();
        } else {
            //操作日志
            setLoggerContext(hmQrcodeQDTO.getEnterpriseId(), hmQrcodeQDTO.getWxEnterpriseId(), hmQrcodeQDTO.getWebLoginDTO());
            String logContent = "【" + hmQrcodeQDTO.getHmId() + "-" + hmQrcodeQDTO.getName() + "】";
            if (StringUtils.isBlank(logContent)) {
                GicLogRecordEvaluationContext.noWriteLog();
            } else {
                if (invokingType != 1) {
                    logContent = logContent + "——" + ChannelCodeEnum.getNameByCode(invokingType);
                }
                GicLogRecordEvaluationContext.putAttribute("logContent", logContent);
                logger.info("新增活码日志：logText:{}", logContent);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GicLogRecord(value = "批量新增员工活码-${#logContent}",
            category = GicLogRecordCategoryEnum.HUOMA,
            optType = GicLogRecordOptTypeEnum.HUOMA_ADD,
            optPage = "活码管理-新增员工活码",
            afterFunc = LogRecordAfterServiceImpl.class)
    public ServiceResponse addList(HmQrcodeQDTO hmQrcodeQDTO) {
        String wxEnterpriseId = hmQrcodeQDTO.getWxEnterpriseId();
        WxEnterpriseDTO wxEnterpriseDTO = wxEnterpriseService.selectById(wxEnterpriseId);
        if (wxEnterpriseDTO == null) {
            logger.error("未查询到微信企业");
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "微信企业不存在");
        }

        String lockKey = "qrCodeAdd" + wxEnterpriseId;
        if (RedisUtil.isLocked(lockKey)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_13.getCode()), "正在批量创建活码，请稍后再试");
        }
        RedisUtil.lock(lockKey, 10L);
        String enterpriseId = hmQrcodeQDTO.getEnterpriseId();
        List<String> clerkIdList = hmQrcodeQDTO.getClerkIdList();
        if (CollectionUtils.isEmpty(clerkIdList)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_5.getCode()), "导购不允许为空");
        }
        if (clerkIdList.contains("-1")) {
            List<HmQrcodeClerkBO> hmQrcodeClerkBOS = hmQrcodeService.listCanAddClerk(wxEnterpriseId, enterpriseId, hmQrcodeQDTO.getCreatorId());
            if (CollectionUtils.isEmpty(hmQrcodeClerkBOS)) {
                return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_5.getCode()), "无需要生成活码导购");
            }
            clerkIdList = hmQrcodeClerkBOS.stream().map(HmQrcodeClerkBO::getClerkId).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        }

        if (CollectionUtils.isEmpty(clerkIdList)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_5.getCode()), "无需要生成活码导购");
        }

        for (String clerkId : clerkIdList) {
            hmQrcodeQDTO.setClerkIdList(Collections.singletonList(clerkId));
            hmQrcodeQDTO.setName("");

            GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
            try {
                logger.info("发送消息到addHmQrcodeMq，{}", clerkId);
                clientInstance.sendMessage("addHmQrcodeMq", JSON.toJSONString(hmQrcodeQDTO));
            } catch (Exception e) {
                logger.info("发送消息到addHmQrcodeMq报错", e);
            }
        }

        setLoggerContext(enterpriseId, wxEnterpriseId, hmQrcodeQDTO.getWebLoginDTO());
        String logContent = "【" + "批量创建数量" + clerkIdList.size() + "】";
        if (StringUtils.isBlank(logContent)) {
            GicLogRecordEvaluationContext.noWriteLog();
        } else {
            GicLogRecordEvaluationContext.putAttribute("logContent", logContent);
            logger.info("批量新增活码日志：logText:{}", logContent);
        }
        return ServiceResponse.success();
    }

    @Override
    public void addHmQrcode(String param) {
        if (StringUtils.isBlank(param)) {
            logger.info("批量新增活码为空");
            return;
        }
        HmQrcodeQDTO hmQrcodeQDTO = JSON.toJavaObject(JSON.parseObject(param), HmQrcodeQDTO.class);
        add(hmQrcodeQDTO);
    }

    /**
     * 设置日志记录器上下文
     * 日志
     *
     * @param enterpriseId   企业标识
     * @param wxEnterpriseId wx企业标识
     * @param webLoginDTO    网络登录dto
     * @author mozhu
     * @date 2022-07-28 15:34:50
     */
    private void setLoggerContext(String enterpriseId, String wxEnterpriseId, WebLoginDTO webLoginDTO) {
        GicLogRecordEvaluationContext.putAttribute("enterpriseId", enterpriseId);
        GicLogRecordEvaluationContext.putAttribute("wxEnterpriseId", wxEnterpriseId);
        if (webLoginDTO != null) {
            GicLogRecordEvaluationContext.putAttribute("userId", webLoginDTO.getClerkId());
            GicLogRecordEvaluationContext.putAttribute("userName", webLoginDTO.getClerkFullName());
            GicLogRecordEvaluationContext.putAttribute("phoneNumber", webLoginDTO.getClerkPhone());
            GicLogRecordEvaluationContext.putAttribute("ywName", webLoginDTO.getOperationUserName());
        } else {
            GicLogRecordEvaluationContext.putAttribute("userId", "-1");
            GicLogRecordEvaluationContext.putAttribute("userName", "系统");
            GicLogRecordEvaluationContext.putAttribute("phoneNumber", "--");
            GicLogRecordEvaluationContext.putAttribute("ywName", "系统");
        }
    }


    @GicLogRecord(value = "修改员工活码-${#hmName}：${#logContent}",
            category = GicLogRecordCategoryEnum.HUOMA,
            optType = GicLogRecordOptTypeEnum.HUOMA_EDIT,
            optPage = "活码管理-修改员工活码",
            afterFunc = LogRecordAfterServiceImpl.class)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResponse update(HmQrcodeQDTO hmQrcodeQDTO) {
        String wxEnterpriseId = hmQrcodeQDTO.getWxEnterpriseId();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
        if (qwDTO == null) {
            logger.error("未查询到微信企业");
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "微信企业不存在");
        }

        Long hmId = hmQrcodeQDTO.getHmId();
        HmQrcodeBO hmQrcodeBO = hmQrcodeService.queryById(hmId);
        if (hmQrcodeBO == null) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "该活码不存在");
        }
        Integer hmType = hmQrcodeQDTO.getHmType();
        if (hmType == null) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "活码类型为空");
        }
        List<String> clerkIdList = setStoreClerk(hmQrcodeQDTO, wxEnterpriseId, hmId, hmType, false);
        if (CollectionUtils.isEmpty(clerkIdList)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "该导购已经生成过活码或未关联过好办");
        }
        //更新活码
        QywxExternalcontactDTO qywxExternalcontactDTO = new QywxExternalcontactDTO();
        qywxExternalcontactDTO.setType(hmQrcodeQDTO.getHmType());
        qywxExternalcontactDTO.setRemark(hmQrcodeQDTO.getName());
        qywxExternalcontactDTO.setSkipVerify(hmQrcodeQDTO.getPassFlag() == 1);
        qywxExternalcontactDTO.setState("HM" + hmId);
        qywxExternalcontactDTO.setConfigId(hmQrcodeBO.getWxConfigId());
        List<String> userIds = staffClerkRelationService.listWxUserIdByClerkIds(clerkIdList, wxEnterpriseId);
        if (CollectionUtils.isEmpty(userIds)) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "导购未关联好办");
        }
        qywxExternalcontactDTO.setUser(userIds);
        QywxResponseDTO qywxResponseDTO = qywxUserApiService.updateContactWay(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), qywxExternalcontactDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        if (qywxResponseDTO.getErrcode() != 0) {
            logger.error("更新企微活码失败");
            GicLogRecordEvaluationContext.noWriteLog();
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_0.getCode()), qywxResponseDTO.getErrmsg());
        }

        setLoggerContext(hmQrcodeQDTO.getEnterpriseId(), wxEnterpriseId, hmQrcodeQDTO.getWebLoginDTO());

        //操作日志
        updateSystemLog(hmQrcodeQDTO, hmId);
        String welcomeId = hmQrcodeQDTO.getWelcomeId();
        if (StringUtils.isBlank(welcomeId)) {
            hmQrcodeQDTO.setWelcomeId("");
        }
        String memberLabelId = hmQrcodeQDTO.getMemberLabelId();
        if (StringUtils.isBlank(memberLabelId)) {
            hmQrcodeQDTO.setMemberLabelId("");
        }
        int updateResult = hmQrcodeService.update(hmQrcodeQDTO);
        if (updateResult == 1) {
            // 更新欢迎语引用次数
            hmQrcodeQDTO.setHmCode(hmQrcodeBO.getHmCode());
            this.updateWelcomeRelation(hmQrcodeQDTO, null);
        }
        return ServiceResponse.success();
    }

    /**
     * 修改活码操作日志
     *
     * @param hmQrcodeQDTO
     * @param hmId
     */
    private void updateSystemLog(HmQrcodeQDTO hmQrcodeQDTO, Long hmId) {
        StringBuffer logContent = new StringBuffer();
        HmQrcodeBO hmOld = hmQrcodeService.queryById(hmId);
        //操作日志
        //名称
        String name = hmQrcodeQDTO.getName();
        Integer invokingType = hmQrcodeQDTO.getInvokingType();
        String nameOld = hmOld.getName();
        if (!name.equals(nameOld)) {
            logContent.append("活码名称「").append(nameOld).append("」").append("变更为「").append(name).append("」");
        }
        //分组
        Long hmGroupId = hmQrcodeQDTO.getHmGroupId();
        Long hmGroupIdOld = hmOld.getHmGroupId();
        if (!hmGroupId.equals(hmGroupIdOld)) {
            HmGroupSettingBO hmGroupSettingBOOld = hmGroupService.queryGroupSettingDetail(hmGroupIdOld);
            HmGroupSettingBO hmGroupSettingBO = hmGroupService.queryGroupSettingDetail(hmGroupId);
            logContent.append("活码分组「").append(hmGroupSettingBOOld.getGroupName()).append("」").append("变更为「").append(hmGroupSettingBO.getGroupName()).append("」");
        }
        //员工变更
        List<String> clerkIdList = hmQrcodeQDTO.getClerkIdList();
        List<HmClerkRelationBO> hmClerkRelationBOS = hmClerkRelationService.queryByHmIdNotInClerkIds(hmId, clerkIdList);
        if (CollectionUtils.isNotEmpty(hmClerkRelationBOS)) {
            //删除员工
            StringBuffer staffNameBuffer = new StringBuffer();
            for (HmClerkRelationBO hmClerkRelationBO : hmClerkRelationBOS) {
                staffNameBuffer.append(hmClerkRelationBO.getStaffName()).append(" ");
            }
            logContent.append("删除使用成员「").append(staffNameBuffer.toString()).append("」");
        }
        //新增员工
        String addStaffName = hmQrcodeQDTO.getAddStaffName();
        if (StringUtils.isNotBlank(addStaffName)) {
            logContent.append("新增使用成员「").append(addStaffName).append("」");
        }

        Integer passFlag = hmQrcodeQDTO.getPassFlag();
        Integer passFlagOld = hmOld.getPassFlag();
        if (!passFlag.equals(passFlagOld)) {
            if (passFlag == 1) {
                logContent.append("关闭自动通过好友").append("变更为开启自动通过好友");
            } else {
                logContent.append("开启自动通过好友").append("变更为关闭自动通过好友");
            }
        }
        //标签
        String memberLabelId = hmQrcodeQDTO.getMemberLabelId();
        String memberLabelIdOld = hmOld.getMemberLabelId();
        if (StringUtils.isBlank(memberLabelId) && StringUtils.isNotBlank(memberLabelIdOld)) {
            logContent.append("活码标签变更为空");
        }
        if (StringUtils.isNotBlank(memberLabelId) && StringUtils.isBlank(memberLabelIdOld)) {
            MemberTagItemDTO tagItem = memberTagApiService.findMemberTagItem(memberLabelId);
            String tagName = "";
            if (tagItem != null) {
                MemberTagDTO tag = this.memberTagApiService.getMemberTagById(tagItem.getTagId());
                tagName = tag.getTagName() + "-" + tagItem.getTagItemName();
            }
            logContent.append("活码标签变更为「").append(tagName).append("」");
        }
        if (StringUtils.isNotBlank(memberLabelId) && StringUtils.isNotBlank(memberLabelIdOld)) {
            if (!memberLabelId.equals(memberLabelIdOld)) {
                MemberTagItemDTO tagItem = memberTagApiService.findMemberTagItem(memberLabelId);
                MemberTagItemDTO tagItemOld = memberTagApiService.findMemberTagItem(memberLabelIdOld);
                String oldTagName = "";
                String tagName = "";
                if (tagItemOld != null) {
                    MemberTagDTO tag = this.memberTagApiService.getMemberTagById(tagItemOld.getTagId());
                    oldTagName = tag.getTagName() + "-" + tagItemOld.getTagItemName();
                }
                if (tagItem != null) {
                    MemberTagDTO tag = this.memberTagApiService.getMemberTagById(tagItem.getTagId());
                    tagName = tag.getTagName() + "-" + tagItem.getTagItemName();
                }
                logContent.append("活码标签「").append(oldTagName).append("」").append("变更为「").append(tagName).append("」");
            }
        }

        //欢迎语
        String welcomeId = hmQrcodeQDTO.getWelcomeId();
        String welcomeIdOld = hmOld.getWelcomeId();
        if (StringUtils.isBlank(welcomeId) && StringUtils.isNotBlank(welcomeIdOld)) {
            logContent.append("欢迎语变更为「 不发送欢迎语」");
        }
        if (StringUtils.isNotBlank(welcomeId) && StringUtils.isBlank(welcomeIdOld)) {
            WelcomeDetailBO welcome = welcomeService.getWelcome(welcomeId, hmQrcodeQDTO.getEnterpriseId());
            logContent.append("欢迎语变更为「").append(welcome.getTitle()).append("」");
        }
        if (StringUtils.isNotBlank(welcomeId) && StringUtils.isNotBlank(welcomeIdOld)) {
            if (!welcomeId.equals(welcomeIdOld)) {
                WelcomeDetailBO welcome = welcomeService.getWelcome(welcomeId, hmQrcodeQDTO.getEnterpriseId());
                WelcomeDetailBO welcomeOld = welcomeService.getWelcome(welcomeIdOld, hmQrcodeQDTO.getEnterpriseId());
                logContent.append("欢迎语「").append(welcomeOld.getTitle()).append("」").append("变更为「").append(welcome.getTitle()).append("」");
            }
        }

        String logText = logContent.toString();
        String hmName = "【" + hmId + "-" + hmQrcodeQDTO.getName() + "】";
        GicLogRecordEvaluationContext.putAttribute("hmName", hmName);
        if (invokingType != 1) {
            logText = logText + "——" + ChannelCodeEnum.getNameByCode(invokingType);
        }
        GicLogRecordEvaluationContext.putAttribute("logContent", logText);
        logger.info("更新活码日志：hmName:{},logText:{}", hmName, logText);
    }


    /**
     * 更新活码 欢迎语引用关系
     *
     * @param hmQrcodeQDTO
     */
    private void updateWelcomeRelation(HmQrcodeQDTO hmQrcodeQDTO, Integer status) {
        HmWelcomeRelationBO welcomeRelationBo = new HmWelcomeRelationBO();
        welcomeRelationBo.setEnterpriseId(hmQrcodeQDTO.getEnterpriseId());
        welcomeRelationBo.setWxEnterpriseId(hmQrcodeQDTO.getWxEnterpriseId());
        welcomeRelationBo.setWelcomeId(hmQrcodeQDTO.getWelcomeId());
        welcomeRelationBo.setReferId(hmQrcodeQDTO.getHmId() + "");
        welcomeRelationBo.setReferCode(hmQrcodeQDTO.getHmCode());
        welcomeRelationBo.setReferName(hmQrcodeQDTO.getName());
        welcomeRelationBo.setType(HmWelcomeReferType.HM.getCode());
        welcomeRelationBo.setStatus(status);
        welcomeRelationService.updateWelcomeRelation(welcomeRelationBo);
    }

    /**
     * 设置门店和导购
     *
     * @param hmQrcodeQDTO
     * @param wxEnterpriseId
     * @param hmId
     * @param hmType
     * @return
     */
    private List<String> setStoreClerk(HmQrcodeQDTO hmQrcodeQDTO, String wxEnterpriseId, Long hmId, Integer hmType, Boolean addFlag) {
        List<String> clerkIdList = hmQrcodeQDTO.getClerkIdList();
        if (CollectionUtils.isEmpty(clerkIdList)) {
            return null;
        }
        String enterpriseId = hmQrcodeQDTO.getEnterpriseId();

        String clerkId = clerkIdList.get(0);
        ClerkDTO clerkDTO = clerkService.getclerkById(clerkId);

        if (clerkDTO != null) {
            String name = hmQrcodeQDTO.getName();
            if (StringUtils.isBlank(name)) {
                hmQrcodeQDTO.setName(clerkDTO.getClerkName());
            }
        }

        if (hmType == 2) {
            //多人活码
            insertHmClerkRelation(hmQrcodeQDTO, enterpriseId, wxEnterpriseId, hmId, clerkIdList, addFlag);
        } else if (hmType == 1) {
            //单人活码
            HmQrcodeBO hmQrcodeBO = hmQrcodeService.queryByClerkId(clerkId, wxEnterpriseId);
            if (addFlag && hmQrcodeBO != null) {
                logger.error("已经生成过活码,clerkId：{}", clerkId);
                return null;
            }
            hmQrcodeQDTO.setClerkId(clerkId);
            if (clerkDTO != null) {
                hmQrcodeQDTO.setClerkName(clerkDTO.getClerkName());
                hmQrcodeQDTO.setClerkCode(clerkDTO.getClerkCode());
                String storeId = clerkDTO.getStoreId();
                hmQrcodeQDTO.setStoreId(storeId);
                StoreDTO storeDTO = storeService.getStore(storeId);
                if (storeDTO != null) {
                    hmQrcodeQDTO.setStoreCode(storeDTO.getStoreCode());
                    hmQrcodeQDTO.setStoreName(storeDTO.getStoreName());
                }
            }

            StaffClerkRelationDTO staffClerkRelationDTO = staffClerkRelationService.getByClerkId(clerkId);
            if (staffClerkRelationDTO != null) {
                hmQrcodeQDTO.setStaffId(staffClerkRelationDTO.getStaffId());
                TabHaobanStaff tabHaobanStaff = staffService.selectById(staffClerkRelationDTO.getStaffId());
                if (tabHaobanStaff != null) {
                    hmQrcodeQDTO.setStaffName(tabHaobanStaff.getStaffName());
                }
            }
        }
        return clerkIdList;
    }

    /**
     * 多人活码关联关系
     *
     * @param enterpriseId
     * @param wxEnterpriseId
     * @param hmId
     * @param clerkIdList
     * @param addFlag
     */
    private void insertHmClerkRelation(HmQrcodeQDTO hmQrcodeQDTO, String enterpriseId, String wxEnterpriseId, Long hmId, List<String> clerkIdList, Boolean addFlag) {
        Date now = new Date();
        if (!addFlag) {
            //修改，删除其余无效导购
            List<HmClerkRelationBO> hmClerkRelationBOS = hmClerkRelationService.queryByHmIdNotInClerkIds(hmId, clerkIdList);
            if (CollectionUtils.isNotEmpty(hmClerkRelationBOS)) {
                for (HmClerkRelationBO hmClerkRelationBO : hmClerkRelationBOS) {
                    hmClerkRelationService.updateStatusById(0, hmClerkRelationBO.getRelationId());
                }
            }
        }
        StringBuffer addStaffName = new StringBuffer();
        for (String clerkId : clerkIdList) {
            HmClerkRelationBO hmClerkRelationBO = hmClerkRelationService.queryByHmIdAndClerkId(hmId, clerkId);
            if (hmClerkRelationBO != null) {
                logger.error("该导购已经在该多人活码中,clerkId:{}", clerkId);
                continue;
            }
            HmClerkRelationQDTO hmClerkRelationQDTO = new HmClerkRelationQDTO();
            hmClerkRelationQDTO.setRelationId(UniqueIdUtils.uniqueLong());
            hmClerkRelationQDTO.setHmId(hmId);
            hmClerkRelationQDTO.setWxEnterpriseId(wxEnterpriseId);
            hmClerkRelationQDTO.setEnterpriseId(enterpriseId);
            hmClerkRelationQDTO.setClerkId(clerkId);
            ClerkDTO clerkDTO = clerkService.getclerkById(clerkId);
            if (clerkDTO != null) {
                String storeId = clerkDTO.getStoreId();
                hmClerkRelationQDTO.setStoreId(storeId);
                StoreDTO storeDTO = storeService.getStore(storeId);
                if (storeDTO != null) {
                    hmClerkRelationQDTO.setStoreCode(storeDTO.getStoreCode());
                    hmClerkRelationQDTO.setStoreName(storeDTO.getStoreName());
                }
                hmClerkRelationQDTO.setClerkName(clerkDTO.getClerkName());
                hmClerkRelationQDTO.setClerkCode(clerkDTO.getClerkCode());
            }

            StaffClerkRelationDTO staffClerkRelationDTO = staffClerkRelationService.getByClerkId(clerkId);
            if (staffClerkRelationDTO != null) {
                hmClerkRelationQDTO.setStaffId(staffClerkRelationDTO.getStaffId());
                TabHaobanStaff tabHaobanStaff = staffService.selectById(staffClerkRelationDTO.getStaffId());
                if (tabHaobanStaff != null) {
                    hmClerkRelationQDTO.setStaffName(tabHaobanStaff.getStaffName());
                    addStaffName.append(tabHaobanStaff.getStaffName()).append(" ");
                }
            }
            hmClerkRelationQDTO.setStatus(1);
            hmClerkRelationQDTO.setCreateTime(now);
            hmClerkRelationQDTO.setUpdateTime(now);
            hmClerkRelationQDTO.setOverFlag(0);
            hmClerkRelationQDTO.setAddNum(0);
            hmClerkRelationService.insert(hmClerkRelationQDTO);
        }
        if (addStaffName != null && addStaffName.length() > 0) {
            hmQrcodeQDTO.setAddStaffName(addStaffName.toString());
        }

    }


    @Override
    public HmQrcodeDTO getDetailById(Long hmId) {
        HmQrcodeBO hmQrcodeBO = hmQrcodeService.queryById(hmId);
        if (hmQrcodeBO != null) {
            HmGroupSettingBO hmGroupSettingBO = hmGroupService.queryGroupSettingDetail(hmQrcodeBO.getHmGroupId());
            if (hmGroupSettingBO != null) {
                hmQrcodeBO.setHmGroupName(hmGroupSettingBO.getGroupName());
            }
            MemberTagItemDTO tagItem = this.memberTagApiService.findMemberTagItem(hmQrcodeBO.getMemberLabelId());
            if (null != tagItem) {
                String tagId = tagItem.getTagId();
                MemberTagDTO tag = this.memberTagApiService.getMemberTagById(tagId);
                hmQrcodeBO.setMemberLabelName(tag.getTagName() + "-" + tagItem.getTagItemName());
                hmQrcodeBO.setMemberLabelStatus(tagItem.getStatus());
            }
            Integer hmType = hmQrcodeBO.getHmType();
            List<HmClerkDTO> clerkDTOList = new ArrayList<>();
            if (hmType == 1) {
                HmClerkDTO clerkDTO = new HmClerkDTO();
                clerkDTO.setClerkName(hmQrcodeBO.getClerkName());
                clerkDTO.setClerkId(hmQrcodeBO.getClerkId());
                clerkDTO.setClerkCode(hmQrcodeBO.getClerkCode());
                clerkDTOList.add(clerkDTO);
            } else if (hmType == 2) {
                List<HmClerkRelationBO> hmClerkRelationBOS = hmClerkRelationService.getHmClerkByHmId(hmId);
                if (CollectionUtils.isNotEmpty(hmClerkRelationBOS)) {
                    for (HmClerkRelationBO hmClerkRelationBO : hmClerkRelationBOS) {
                        HmClerkDTO clerkDTO = new HmClerkDTO();
                        clerkDTO.setClerkName(hmClerkRelationBO.getClerkName());
                        clerkDTO.setClerkId(hmClerkRelationBO.getClerkId());
                        clerkDTO.setClerkCode(hmClerkRelationBO.getClerkCode());
                        clerkDTOList.add(clerkDTO);
                    }
                }
            }
            hmQrcodeBO.setClerkList(clerkDTOList);
        }
        return EntityUtil.changeEntityNew(HmQrcodeDTO.class, hmQrcodeBO);
    }

    @Override
    public HmQrcodeDTO getSimpleById(Long hmId) {
        return EntityUtil.changeEntityNew(HmQrcodeDTO.class, hmQrcodeService.queryById(hmId));
    }

    @GicLogRecord(value = "废弃员工活码-${#logContent}",
            category = GicLogRecordCategoryEnum.HUOMA,
            optType = GicLogRecordOptTypeEnum.HUOMA_DEL,
            optPage = "活码管理-废弃员工活码",
            afterFunc = LogRecordAfterServiceImpl.class)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResponse delById(Long hmId, Integer invokingType, WebLoginDTO loginDTO) {
        HmQrcodeBO hmQrcodeBO = hmQrcodeService.queryById(hmId);
        if (hmQrcodeBO == null) {
            return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), "活码不存在");
        }

        String wxConfigId = hmQrcodeBO.getWxConfigId();
        if (StringUtils.isNotBlank(wxConfigId)) {
            WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(hmQrcodeBO.getWxEnterpriseId());
            QywxResponseDTO qywxResponseDTO = qywxUserApiService.delContactWay(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), wxConfigId,qwDTO.isSelf(),qwDTO.getUrlHost());
            int errcode = qywxResponseDTO.getErrcode();
            //https://open.work.weixin.qq.com/devtool/query?e=41044
            if (errcode != 0) {
                if (errcode == 41044) {
                    delQrcode(hmId, invokingType, loginDTO, hmQrcodeBO);
                    return ServiceResponse.success();
                }
                GicLogRecordEvaluationContext.noWriteLog();
                return ServiceResponse.failure(Convert.toStr(HaoBanErrCodeCommon.ERR_8.getCode()), qywxResponseDTO.getErrmsg());
            }
        }
        delQrcode(hmId, invokingType, loginDTO, hmQrcodeBO);
        return ServiceResponse.success();
    }

    /**
     * 删除活码
     *
     * @param hmId
     * @param invokingType
     * @param loginDTO
     * @param hmQrcodeBO
     */
    private void delQrcode(Long hmId, Integer invokingType, WebLoginDTO loginDTO, HmQrcodeBO hmQrcodeBO) {
        //操作日志
        setLoggerContext(hmQrcodeBO.getEnterpriseId(), hmQrcodeBO.getWxEnterpriseId(), loginDTO);
        String logContent = "【" + hmId + "-" + hmQrcodeBO.getName() + "】";
        if (invokingType != 1) {
            logContent = logContent + "——" + ChannelCodeEnum.getNameByCode(invokingType);
        }

        GicLogRecordEvaluationContext.putAttribute("logContent", logContent);
        hmQrcodeService.deleteById(hmId);
        HmQrcodeQDTO hmQrcodeQDTO = new HmQrcodeQDTO();
        hmQrcodeQDTO.setHmId(hmId);
        this.updateWelcomeRelation(hmQrcodeQDTO, WelcomeRelationStatusEnum.DEPRECATED.getCode());
    }


    @Override
    public int updateAddNumById(Long hmId, String clerkId) {
        StaffClerkRelationDTO staffClerkRelationDTO = staffClerkRelationService.getByClerkId(clerkId);
        if (staffClerkRelationDTO == null) {
            logger.error("未绑定好办：{}", clerkId);
            return 0;
        }
        HmQrcodeBO hmQrcodeBO = hmQrcodeService.queryById(hmId);
        if (hmQrcodeBO == null) {
            logger.error("无活码数据");
            return 0;
        }
        TabHaobanStaff tabHaobanStaff = staffService.selectById(staffClerkRelationDTO.getStaffId());
        Integer addNum = tabHaobanStaff.getAddNum();
        Integer hmType = hmQrcodeBO.getHmType();
        int limit = QwFriendLimitCountUtil.getLimit(true);
        if (hmType == 1) {
            //单人活码
            Integer overFlag = 0;
            if (addNum + 1 >= limit) {
                overFlag = 1;
            }
            return hmQrcodeService.updateAddNumById(hmId, overFlag);
        } else if (hmType == 2) {
            //多人活码
            HmClerkRelationBO hmClerkRelationBO = hmClerkRelationService.queryByHmIdAndClerkId(hmId, clerkId);
            if (hmClerkRelationBO == null) {
                logger.error("无多人活码导购数据,clerkId:{},hmId:{}", clerkId, hmId);
                return 0;
            }
            Integer overFlag = 0;
            if (addNum + 1 >= limit) {
                overFlag = 1;
            }
            Long relationId = hmClerkRelationBO.getRelationId();
            return hmClerkRelationService.updateAddNumById(relationId, overFlag);
        }
        return 0;
    }

    @Override
    public void resetAddNumAndOverFlag(String param) {
        logger.info("重置上限时间定时任务 start");
        hmQrcodeService.resetAddNumAndOverFlag();
        hmClerkRelationService.resetAddNumAndOverFlag();
        staffService.resetAddNum();
        logger.info("重置上限时间定时任务 end");
    }

    @Override
    public void checkStaffOpenContact(String param) {
        logger.info("检查员工是否开启联系我,定时任务，start");
        List<WxEnterpriseDTO> tabHaobanWxEnterprises = wxEnterpriseService.listAllEnterprise();
        for (WxEnterpriseDTO wxEnterpriseDTO : tabHaobanWxEnterprises) {
            String enterpriseId = wxEnterpriseDTO.getEnterpriseId();
            //查询出所有正常的导购
            String wxEnterpriseId = wxEnterpriseDTO.getWxEnterpriseId();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("wxEnterpriseId", wxEnterpriseId);
            jsonObject.put("enterpriseId", enterpriseId);
            GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
            try {
                clientInstance.sendMessage("checkStaffOpenContactByWxEnterpriseIdMq", jsonObject.toJSONString());
            } catch (Exception e) {
                logger.info("发送消息异常：{}", e.getMessage(),e);
            }

        }
        logger.info("检查员工是否开启联系我,定时任务，end");
    }

    @Override
    public void checkStaffOpenContactByWxEnterpriseId(String param) {
        JSONObject jsonObject = JSON.parseObject(param);
        String wxEnterpriseId = jsonObject.getString("wxEnterpriseId");
        String enterpriseId = jsonObject.getString("enterpriseId");
        logger.info("检查企业员工是否开启联系我：wxEnterpriseId:{},enterpriseId:{}", wxEnterpriseId, enterpriseId);
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
        //查询出所有正常的导购
        //企微已经开启联系我
        List<String> wxUserIdsList = null ;
        if(qwDTO.isSelf()) {
            wxUserIdsList = qywxUserApiService.listCorpExternalUserSelf(qwDTO.getDkCorpid(), qwDTO.getSelfSecret(),qwDTO.getUrlHost());
        }else {
            wxUserIdsList = qywxUserApiService.listCorpExternalUser(qwDTO.getThirdCorpid(), config.getWxSuiteid());
        }
        this.staffService.updateOpenConcatFlag(wxUserIdsList,qwDTO.needOpenUserId3th()?1:0) ;
        List<StaffClerkRelationDTO> staffClerkRelationDTOS = staffClerkRelationService.listIdsByWxUserIds(wxUserIdsList, wxEnterpriseId, enterpriseId);
        if (CollectionUtils.isEmpty(staffClerkRelationDTOS)) {
            logger.error("无导购关联数据");
            return;
        }
        for (StaffClerkRelationDTO staffClerkRelationDTO : staffClerkRelationDTOS) {
            //具有联系我功能的导购创建活码
            staffClerkRelationService.updateOpenConcatFlagById(1, staffClerkRelationDTO.getStaffClerkRelationId());
            //创建活码
            HmQrcodeQDTO hmQrcodeQDTO = new HmQrcodeQDTO();
            hmQrcodeQDTO.setHmType(1);
            hmQrcodeQDTO.setWxEnterpriseId(wxEnterpriseId);
            hmQrcodeQDTO.setEnterpriseId(staffClerkRelationDTO.getEnterpriseId());
            hmQrcodeQDTO.setName(staffClerkRelationDTO.getStaffName());
            hmQrcodeQDTO.setPassFlag(1);
            hmQrcodeQDTO.setStoreId(staffClerkRelationDTO.getStoreId());
            hmQrcodeQDTO.setClerkIdList(Collections.singletonList(staffClerkRelationDTO.getClerkId()));
            add(hmQrcodeQDTO);
        }

        List<StaffClerkRelationDTO> relationDTOS = staffClerkRelationService.listIdsByNotInWxUserIds(wxUserIdsList, wxEnterpriseId, enterpriseId);
        if (CollectionUtils.isEmpty(relationDTOS)) {
            logger.error("无导购不包含关联数据");
            return;
        }
        for (StaffClerkRelationDTO relationDTO : relationDTOS) {
            //有活码，但是企微联系我功能 被关闭
            String clerkId = relationDTO.getClerkId();
            HmQrcodeBO hmQrcodeBO = hmQrcodeService.queryByClerkId(clerkId, relationDTO.getWxEnterpriseId());
            if (hmQrcodeBO == null) {
                logger.info("导购无活码，无需处理：clerkId：{}", clerkId);
                continue;
            }
            staffClerkRelationService.updateOpenConcatFlagById(0, relationDTO.getStaffClerkRelationId());
            hmQrcodeService.updateStatusById(hmQrcodeBO.getHmId(), 3);
        }
    }

    @Override
    public List<HmQrcodeStoreDTO> getHmStoreByEnterpriseId(String wxEnterpriseId, String enterpriseId) {
        String key = "HM:STORE:" + enterpriseId + wxEnterpriseId;
        Object cache = RedisUtil.getCache(key);
        if (cache != null) {
            return (List<HmQrcodeStoreDTO>) cache;
        }
        List<HmQrcodeStoreDTO> hmQrcodeStoreDTOS = EntityUtil.changeEntityListNew(HmQrcodeStoreDTO.class, hmQrcodeService.getHmStoreByEnterpriseId(wxEnterpriseId, enterpriseId));
        RedisUtil.setCache(key, hmQrcodeStoreDTOS, 5L, TimeUnit.MINUTES);
        return hmQrcodeStoreDTOS;
    }

    @Override
    public List<String> getHmStoreForWxa(String wxEnterpriseId, String enterpriseId) {
        String key = "HM:STORE:WXA" + enterpriseId + wxEnterpriseId;
        Object cache = RedisUtil.getCache(key);
        if (cache != null) {
            return (List<String>) cache;
        }
        List<String> list = hmQrcodeService.getHmStoreForWxa(wxEnterpriseId, enterpriseId);
        RedisUtil.setCache(key, list, 5L, TimeUnit.MINUTES);
        return list;
    }

    /**
     * 批量修改活码分组
     *
     * @param hmIds
     * @param groupId
     * @return
     */
    @Override
    public ServiceResponse<Boolean> batchUpdateHmQrcodeGroup(List<Long> hmIds, Long groupId) {
        if (CollectionUtils.isEmpty(hmIds) || groupId == null) {
            return ServiceResponse.failure(HaoBanErrCodeCommon.ERR_2.getCode() + "", HaoBanErrCodeCommon.ERR_2.getMsg());
        }
        int updateCount = hmQrcodeService.batchUpdateQrcodeGroup(hmIds, groupId);
        return ServiceResponse.success(updateCount > 0);
    }

    @Override
    public ServiceResponse<List<String>> listHmIdForIndex(HmQrcodeListQDTO qdto) {
        return ServiceResponse.success(hmQrcodeService.listHmIdForIndex(qdto));
    }

    @Override
    public ServiceResponse<List<String>> listHasQrcodeClerk(String enterpriseId, List<String> clerkIdList) {
        return ServiceResponse.success(hmQrcodeService.listHasQrcodeClerk(enterpriseId, clerkIdList));
    }
    
    public com.gic.api.base.commons.ServiceResponse<String> getClerkQrcode(String enterpriseId, String clerkId) {
        return ServiceResponse.success(hmQrcodeService.getClerkQrcode(enterpriseId, clerkId));
    }
}
