package com.gic.haoban.manage.web.controller.hm;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.gic.api.base.commons.JSONResponse;
import com.gic.clerk.api.dto.AuthorizedUser;
import com.gic.qcloud.BucketNameEnum;
import com.gic.web.common.download.DownloadTask;
import com.gic.web.common.download.DownloadTaskUtil;
import com.gic.web.common.download.constants.TaskTypeEnum;
import com.gic.web.common.utils.DataApiUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.common.utils.AuthWebRequestUtil;
import com.gic.haoban.manage.api.constants.StatisticsApolloKeyConstant;
import com.gic.haoban.manage.api.dto.chat.GroupChatHmDTO;
import com.gic.haoban.manage.api.dto.hm.HmLinkChatDTO;
import com.gic.haoban.manage.api.dto.hm.HmLinkDTO;
import com.gic.haoban.manage.api.dto.hm.HmLinkStoreDTO;
import com.gic.haoban.manage.api.dto.hm.HmLinkStoreSettingDTO;
import com.gic.haoban.manage.api.dto.hm.HmPageDTO;
import com.gic.haoban.manage.api.dto.hm.WxUserAddLogDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmLinkSearchQDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.WxUserAddLogSearchQDTO;
import com.gic.haoban.manage.api.dto.statistics.StatisticsDTO;
import com.gic.haoban.manage.api.dto.welcome.dto.WelcomeDetailDTO;
import com.gic.haoban.manage.api.enums.hm.HmLinkTypeEnum;
import com.gic.haoban.manage.api.service.chat.GroupChatHmApiService;
import com.gic.haoban.manage.api.service.hm.HmLinkApiService;
import com.gic.haoban.manage.api.service.hm.HmPageApiService;
import com.gic.haoban.manage.api.service.hm.HmQrcodeApiService;
import com.gic.haoban.manage.api.service.hm.WxUserAddLogApiService;
import com.gic.haoban.manage.api.service.out.WelcomeApiService;
import com.gic.haoban.manage.web.log.LogRecordUserServiceImpl;
import com.gic.haoban.manage.web.qo.hm.data.HmLinkChartQO;
import com.gic.haoban.manage.web.qo.hm.data.HmLinkClerkListQO;
import com.gic.haoban.manage.web.utils.CreatorUtils;
import com.gic.haoban.manage.web.utils.statistics.DataStatisticsParamUtils;
import com.gic.haoban.manage.web.utils.statistics.DateUtils;
import com.gic.haoban.manage.web.vo.hm.HmLinkListVO;
import com.gic.haoban.manage.web.vo.hm.HmLinkVO;
import com.gic.haoban.manage.web.vo.hm.WxUserAddLogVO;
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;

/**
 * 
* @ClassName: HmLinkController
* @Description: 活码链接
* @author xugh
* @date 2022年7月1日 下午2:15:39
*
 */
@RestController
@RequestMapping("/hm/link")
@SuppressWarnings("unchecked")
public class HmLinkController {

    private static org.apache.logging.log4j.Logger logger = LogManager.getLogger(HmLinkController.class);
    @Autowired
    private HmLinkApiService hmLinkApiService;
    @Autowired
    private HmPageApiService hmPageApiService;
    @Autowired
    private WelcomeApiService welcomeApiService;
    @Autowired
    private MemberTagApiService memberTagApiService;
    @Autowired
    private WxUserAddLogApiService wxUserAddLogApiService;
    @Autowired
    private HmQrcodeApiService hmQrcodeApiService;
    @Autowired
    private GroupChatHmApiService groupChatHmApiService;
    @Autowired
    private LinkDataExcelHandler linkDataExcelHandler;

    @RequestMapping("add")
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.HUOMA, optType = GicLogRecordOptTypeEnum.HM_LINK_ADD, userFunc = LogRecordUserServiceImpl.class, optPage = "引流加人-新建链接")
    public RestResponse<Object> save(@RequestBody HmLinkDTO dto) {
        if (null == dto.getLinkType()) {
            GicLogRecordEvaluationContext.noWriteLog();
            return RestResponse.failure("9999", "请选择链接类型");
        }
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        RestResponse<Object> checkResp = this.saveCheck(dto);
        if (!"0".equals(checkResp.getCode())) {
            GicLogRecordEvaluationContext.noWriteLog();
            return checkResp;
        }
        dto.setCreatorId(loginUser.getClerkId());
        dto.setCreatorName(loginUser.getClerkName());
        dto.setModifierId(loginUser.getClerkId());
        dto.setModifierName(loginUser.getClerkName());
        dto.setWxEnterpriseId(loginUser.getWxEnterpriseId());
        dto.setEnterpriseId(loginUser.getEnterpriseId());
        ServiceResponse<String> saveResp = this.hmLinkApiService.save(dto);
        if (saveResp.isSuccess()) {
            if (dto.getLinkType() == HmLinkTypeEnum.CHAT_HM_LINK_TYPE.getLinkType()) {
                GicLogRecordEvaluationContext.setOptPage("引流入群-新建链接");
            }
            String logContent = "新增引流链接【" + saveResp.getResult() + "-" + dto.getName() + "】";
            logger.info(logContent);
            GicLogRecordEvaluationContext.putAttribute("logValue", logContent);
            GicLogRecordEvaluationContext.putOptTargetId(AuthWebRequestUtil.getLoginUser().getClerkId());
            return RestResponse.successResult();
        }
        return RestResponse.failure(saveResp.getCode(), saveResp.getResult());
    }

    @RequestMapping("update")
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.HUOMA, optType = GicLogRecordOptTypeEnum.HM_LINK_UPDATE, userFunc = LogRecordUserServiceImpl.class, optPage = "引流加人-编辑链接")
    public RestResponse<Object> update(@RequestBody HmLinkDTO dto) {
        Long linkId = dto.getLinkId();
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        RestResponse<Object> checkResp = this.saveCheck(dto);
        if (!"0".equals(checkResp.getCode())) {
            GicLogRecordEvaluationContext.noWriteLog();
            return checkResp;
        }
        ServiceResponse<HmLinkDTO> resp = this.hmLinkApiService.getByLinkId(loginUser.getWxEnterpriseId(),
                loginUser.getEnterpriseId(), linkId);
        if (!resp.isSuccess()) {
            GicLogRecordEvaluationContext.noWriteLog();
            return RestResponse.failure(resp.getCode(), resp.getMessage());
        }
        HmLinkDTO oldDTO = resp.getResult();
        dto.setModifierId(loginUser.getClerkId());
        dto.setModifierName(loginUser.getClerkName());
        ServiceResponse<String> saveResp = this.hmLinkApiService.save(dto);
        if (saveResp.isSuccess()) {
            if (dto.getLinkType() == HmLinkTypeEnum.CHAT_HM_LINK_TYPE.getLinkType()) {
                String logContent = this.getUpdateLogChat(oldDTO, dto);
                if (StringUtils.isNotBlank(logContent)) {
                    GicLogRecordEvaluationContext.setOptPage("引流入群-编辑链接");
                    GicLogRecordEvaluationContext.putAttribute("logValue", logContent);
                    GicLogRecordEvaluationContext.putOptTargetId(AuthWebRequestUtil.getLoginUser().getClerkId());
                }else {
                    GicLogRecordEvaluationContext.noWriteLog();
                }
                return RestResponse.successResult();
            } else {
                String logContent = this.getUpdateLog(oldDTO, dto);
                if (StringUtils.isBlank(logContent)) {
                    GicLogRecordEvaluationContext.noWriteLog();
                }
                logger.info(logContent);
                GicLogRecordEvaluationContext.putAttribute("logValue", logContent);
                GicLogRecordEvaluationContext.putOptTargetId(AuthWebRequestUtil.getLoginUser().getClerkId());
                return RestResponse.successResult();
            }
        }
        return RestResponse.failure(saveResp.getCode(), saveResp.getResult());
    }

    // 链接类型，名称，标签，分配规则，落地页模板
    private RestResponse<Object> saveCheck(HmLinkDTO dto) {
        if (StringUtils.isEmpty(dto.getName())) {
            return RestResponse.failure("9999", "链接名称不能为空");
        }
        if (null == dto.getPageId()) {
            return RestResponse.failure("9999", "请选择落地页模板");
        }
        if (dto.getLinkType() == HmLinkTypeEnum.CHAT_HM_LINK_TYPE.getLinkType()) {
            if (null == dto.getOtherChatHmId()) {
                return RestResponse.failure("9999", "其他可入群不能为空");
            }
            if (CollectionUtils.isNotEmpty(dto.getLinkChatList())) {
                for (HmLinkChatDTO chat : dto.getLinkChatList()) {
                    if (null == chat.getChatHmId()) {
                        return RestResponse.failure("9999", "请选择活码");
                    }
                }
            }
        } else {
            if (StringUtils.isEmpty(dto.getMemberLabelId())) {
                return RestResponse.failure("9999", "链接标签不能为空");
            }
            if (null == dto.getLinkType()) {
                return RestResponse.failure("9999", "请选择链接类型");
            }
            if (StringUtils.isEmpty(dto.getStoreRuleJson()) || StringUtils.isEmpty(dto.getCustomRuleJson())) {
                return RestResponse.failure("9999", "请选择分配规则");
            }
        }
        return RestResponse.successResult();
    }

    private String getUpdateLogChat(HmLinkDTO oldDTO, HmLinkDTO newDTO) {
        String wxEnterpriseId = newDTO.getWxEnterpriseId();
        String enterpriseId = newDTO.getEnterpriseId();
        StringBuilder content = new StringBuilder();
        String a = comp(wxEnterpriseId, enterpriseId, "链接名称", oldDTO.getName(), newDTO.getName(), 0);
        if (null != a) {
            content.append(a);
        }
        String b = comp(wxEnterpriseId, enterpriseId, "链接描述", oldDTO.getRemark(), newDTO.getRemark(), 0);
        if (null != b) {
            content.append(b);
        }
        String oldChatRule = oldDTO.getChatStoreRule();
        if(null == oldChatRule) {
            oldChatRule = "";
        }
        String newChatRule = newDTO.getChatStoreRule();
        if(null == newChatRule) {
            newChatRule = "";
        }
        String s = null ;
        logger.info("{},{}",oldChatRule,newChatRule);
        if(!oldChatRule.equals(newChatRule)) {
            String oldName = this.getChatRuleName(oldChatRule) ;
            String newName = this.getChatRuleName(newChatRule) ;
            s = String.format("定向入群设置从【%s】修改为【%s】", oldName, newName) ;
            content.append(s) ;
        }
        // 其他群活码
        String c = null;
        if (!oldDTO.getOtherChatHmId().equals(newDTO.getOtherChatHmId())) {
            ServiceResponse<GroupChatHmDTO> oldResp = this.groupChatHmApiService.detail(oldDTO.getOtherChatHmId());
            ServiceResponse<GroupChatHmDTO> newResp = this.groupChatHmApiService.detail(newDTO.getOtherChatHmId());
            String oldValue = "";
            String newValue = "";
            StringBuilder sb = new StringBuilder();
            if (oldResp.isSuccess()) {
                oldValue = oldResp.getResult().getChatHmCode() + "-" + oldResp.getResult().getName();
            }
            if (null != newResp) {
                newValue = newResp.getResult().getChatHmCode() + "-" + newResp.getResult().getName();
            }
            sb.append("其他可入群").append("「").append(oldValue).append("」变更为「").append(newValue).append("」");
            c = sb.toString();
            content.append(c);
        }
        // 落地页
        String d = null;
        if (!oldDTO.getPageId().equals(newDTO.getPageId())) {
            ServiceResponse<HmPageDTO> oldResp = this.hmPageApiService.queryPageDetail(oldDTO.getPageId());
            ServiceResponse<HmPageDTO> newResp = this.hmPageApiService.queryPageDetail(newDTO.getPageId());
            String oldValue = "";
            String newValue = "";
            StringBuilder sb = new StringBuilder();
            if (oldResp.isSuccess()) {
                oldValue = oldResp.getResult().getPageCode() + "-" + oldResp.getResult().getPageName();
            }
            if (null != newResp) {
                newValue = newResp.getResult().getPageCode() + "-" + newResp.getResult().getPageName();
            }
            sb.append("落地页模板").append("「").append(oldValue).append("」变更为「").append(newValue).append("」");
            d = sb.toString();
            content.append(d);
        }
        if (org.apache.commons.lang3.StringUtils.isAllBlank(a, b, c, d,s)) {
            return null;
        }
        StringBuilder sb = new StringBuilder("编辑引流链接").append("【").append(oldDTO.getLinkCode()).append("-")
                .append(oldDTO.getName()).append("】：");
        return sb.append(content).toString();
    }


    private String getChatRuleName(String chatRule) {
        if(org.apache.commons.lang3.StringUtils.isBlank(chatRule)) {
            return "--" ;
        }
        JSONArray arr = JSON.parseArray(chatRule) ;
        List<String> list = new ArrayList<>() ;
        for(int i=0;i<arr.size();i++) {
            JSONObject json = arr.getJSONObject(i) ;
            if(json.getIntValue("open")==1) {
                int type = json.getIntValue("type") ;
                if(type==1) {
                    list.add("服务门店");
                }else if(type==2) {
                    list.add("协管门店");
                }else if(type==3) {
                    list.add("LBS定位");
                }else if(type==4) {
                    list.add("指定人群");
                }
            }
        }
        if(CollectionUtils.isEmpty(list)) {
            return "--" ;
        }
        return list.stream().collect(Collectors.joining("、"));
    }

    private String getUpdateLog(HmLinkDTO oldDTO, HmLinkDTO newDTO) {
        String wxEnterpriseId = newDTO.getWxEnterpriseId();
        String enterpriseId = newDTO.getEnterpriseId();
        StringBuilder content = new StringBuilder();
        String a = comp(wxEnterpriseId, enterpriseId, "链接名称", oldDTO.getName(), newDTO.getName(), 0);
        if (null != a) {
            content.append(a);
        }
        String b = comp(wxEnterpriseId, enterpriseId, "链接描述", oldDTO.getRemark(), newDTO.getRemark(), 0);
        if (null != b) {
            content.append(b);
        }
        String c = comp(wxEnterpriseId, enterpriseId, "分配规则", oldDTO.getStoreRuleJson(), newDTO.getStoreRuleJson(), 3);
        if (null != c) {
            content.append(c);
        }
        String d = comp(wxEnterpriseId, enterpriseId, "分配规则", oldDTO.getCustomRuleJson(), newDTO.getCustomRuleJson(),
                oldDTO, newDTO);
        if (null != d) {
            content.append(d);
        }
        String e = comp(wxEnterpriseId, enterpriseId, "链接标签", oldDTO.getMemberLabelId(), newDTO.getMemberLabelId(), 1);
        if (null != e) {
            content.append(e);
        }
        String f = comp(wxEnterpriseId, enterpriseId, "欢迎语", oldDTO.getWelcomeId(), newDTO.getWelcomeId(), 2);
        if (null != f) {
            content.append(f);
        }
        if (org.apache.commons.lang3.StringUtils.isAllBlank(a, b, c, d, e, f)) {
            return null;
        }
        StringBuilder sb = new StringBuilder("编辑引流链接").append("【").append(oldDTO.getLinkCode()).append("-")
                .append(oldDTO.getName()).append("】：");
        return sb.append(content).toString();
    }

    public String comp(String wxEnterpriseId, String enterpriseId, String title, String oldValue, String newValue,
            HmLinkDTO oldDTO, HmLinkDTO newDTO) {
        // 其他门店
        JSONObject oldStoreRuleObj = JSONObject.parseObject(oldValue);
        JSONObject newStoreRuleObj = JSONObject.parseObject(newValue);
        logger.info("{},{}", oldStoreRuleObj, newStoreRuleObj);
        return otherStoreRuleLog(oldStoreRuleObj, newStoreRuleObj, oldDTO, newDTO);
    }

    // type 会员标签1 , 2 欢迎语
    public String comp(String wxEnterpriseId, String enterpriseId, String title, String oldValue, String newValue,
            int type) {
        StringBuilder sb = new StringBuilder();
        if (null == oldValue) {
            oldValue = "";
        }
        if (null == newValue) {
            newValue = "";
        }
        if (type == 0 && !oldValue.equals(newValue)) {
            sb.append(title).append("「").append(oldValue).append("」变更为「").append(newValue).append("」");
            return sb.toString();
        }
        // 会员标签
        if (type == 1 && !oldValue.equals(newValue)) {
            MemberTagItemDTO oldResp = this.memberTagApiService.findMemberTagItem(oldValue);
            MemberTagItemDTO newResp = this.memberTagApiService.findMemberTagItem(newValue);
            if (null != oldResp) {
                oldValue = oldResp.getTagName() + "-" + oldResp.getTagItemName();
            }
            if (null != newResp) {
                newValue = newResp.getTagName() + "-" + newResp.getTagItemName();
            }
            sb.append(title).append("「").append(oldValue).append("」变更为「").append(newValue).append("」");
            return sb.toString();
        }
        // 欢迎语
        if (type == 2 && !oldValue.equals(newValue)) {
            if (StringUtils.isEmpty(oldValue)) {
                ServiceResponse<WelcomeDetailDTO> resp = this.welcomeApiService.getWelcome(newValue, enterpriseId);
                if (null != resp && null != resp.getResult()) {
                    sb.append("欢迎语变更为").append("「").append(resp.getResult().getTitle()).append("」");
                    return sb.toString();
                }
            } else if (StringUtils.isEmpty(newValue)) {
                sb.append("欢迎语变更为").append("「").append("不发送欢迎语").append("」");
                return sb.toString();
            } else {
                ServiceResponse<WelcomeDetailDTO> oldResp = this.welcomeApiService.getWelcome(oldValue, enterpriseId);
                ServiceResponse<WelcomeDetailDTO> newResp = this.welcomeApiService.getWelcome(newValue, enterpriseId);
                if (null != oldResp && null != oldResp.getResult()) {
                    oldValue = oldResp.getResult().getTitle();
                }
                if (null != newResp && null != newResp.getResult()) {
                    newValue = newResp.getResult().getTitle();
                }
                sb.append(title).append("「").append(oldValue).append("」变更「").append(newValue).append("」");
                return sb.toString();
            }
        }
        // 分批规则
        if (type == 3) {
            JSONObject oldStoreRuleObj = JSONObject.parseObject(oldValue);
            JSONObject newStoreRuleObj = JSONObject.parseObject(newValue);
            logger.info("{},{}", oldStoreRuleObj, newStoreRuleObj);
            // 服务门店
            HmLinkStoreSettingDTO oldFwStore = oldStoreRuleObj.getObject("fw_store", HmLinkStoreSettingDTO.class);
            HmLinkStoreSettingDTO newFwStore = newStoreRuleObj.getObject("fw_store", HmLinkStoreSettingDTO.class);
            sb.append(ruleLog(oldFwStore, newFwStore, 1));
            // 协管门店
            HmLinkStoreSettingDTO oldXgStore = oldStoreRuleObj.getObject("xg_store", HmLinkStoreSettingDTO.class);
            HmLinkStoreSettingDTO newXgStore = newStoreRuleObj.getObject("xg_store", HmLinkStoreSettingDTO.class);
            sb.append(ruleLog(oldXgStore, newXgStore, 2));
            return sb.toString();
        }
        return null;
    }

    private String otherStoreRuleLog(JSONObject oldStoreRuleObj, JSONObject newStoreRuleObj, HmLinkDTO oldDTO,
            HmLinkDTO newDTO) {
        StringBuilder tempSb = new StringBuilder();
        int oldOpenFlag = oldStoreRuleObj.getIntValue("open");
        int newOpenFlag = newStoreRuleObj.getIntValue("open");
        if (oldOpenFlag != newOpenFlag && newOpenFlag == 0) {
            tempSb.append("关闭").append("「").append("其他门店").append("」");
        } else {
            int oldStoreType = oldStoreRuleObj.getIntValue("store_type");
            int newStoreType = newStoreRuleObj.getIntValue("store_type");
            HmLinkStoreSettingDTO oldtore = oldStoreRuleObj.getObject("store", HmLinkStoreSettingDTO.class);
            HmLinkStoreSettingDTO newStore = newStoreRuleObj.getObject("store", HmLinkStoreSettingDTO.class);
            HmLinkStoreSettingDTO oldCityStore = oldStoreRuleObj.getObject("city_store", HmLinkStoreSettingDTO.class);
            HmLinkStoreSettingDTO newCityStore = newStoreRuleObj.getObject("city_store", HmLinkStoreSettingDTO.class);
            if ((oldOpenFlag == 0 && newOpenFlag == 1) || (oldStoreType != newStoreType)) {
                // 开启
                tempSb.append("开启");
                if (newStoreType == 1) {
                    tempSb.append(otherOpenLog(newStore, 5));
                } else if (newStoreType == 2) {
                    tempSb.append(otherOpenLog(newStore, 6));
                }
                String cityLog = otherOpenLog(newCityStore, 4);
                tempSb.append(cityLog);
                // 门店
                tempSb.append(this.getStoreListLog(null, newDTO, 1));
            } else {
                if (newStoreType == 1) {
                    tempSb.append(otherChangeLog(oldtore, newStore, 5));
                } else if (newStoreType == 2) {
                    tempSb.append(otherChangeLog(oldtore, newStore, 6));
                }
                tempSb.append(ruleLog(oldCityStore, newCityStore, 4));
                tempSb.append(this.getStoreListLog(oldDTO, newDTO, 2));
            }
        }
        return tempSb.toString();
    }

    private String getStoreListLog(HmLinkDTO oldDTO, HmLinkDTO newDTO, int type) {
        StringBuilder tempSb = new StringBuilder();
        if (1 == type && null != newDTO && CollectionUtils.isNotEmpty(newDTO.getStoreList())) {
            tempSb.append("门店为「");
            List<String> list = new ArrayList<>();
            newDTO.getStoreList().forEach(item -> {
                list.add(item.getStoreName() + "(" + item.getStoreCode() + ")");
            });
            tempSb.append(list.stream().collect(Collectors.joining("、")));
            tempSb.append("」");
        }
        if (2 == type) {
            // 本次新加的
            List<String> addList = new ArrayList<>();
            List<String> delIdList = new ArrayList<>();
            List<String> oldStoreIdList = new ArrayList<>();
            List<HmLinkStoreDTO> oldList = oldDTO.getStoreList();
            List<HmLinkStoreDTO> newList = newDTO.getStoreList();
            if (CollectionUtils.isEmpty(oldList) && CollectionUtils.isEmpty(newList)) {
                return "";
            }
            if (CollectionUtils.isNotEmpty(oldList)) {
                oldStoreIdList = oldList.stream().map(dto -> dto.getStoreId()).collect(Collectors.toList());
                for (HmLinkStoreDTO dto : newList) {
                    if (!oldStoreIdList.contains(dto.getStoreId())) {
                        addList.add(dto.getStoreName() + "(" + dto.getStoreCode() + ")");
                    }
                }
                if (CollectionUtils.isNotEmpty(addList)) {
                    tempSb.append("新增门店「").append(addList.stream().collect(Collectors.joining("、"))).append("」");
                }
            }

            if (CollectionUtils.isNotEmpty(newList)) {
                List<String> newStoreIdList = newList.stream().map(dto -> dto.getStoreId())
                        .collect(Collectors.toList());
                for (HmLinkStoreDTO item : oldList) {
                    if (!newStoreIdList.contains(item.getStoreId())) {
                        delIdList.add(item.getStoreName() + "(" + item.getStoreCode() + ")");
                    }
                }
                if (CollectionUtils.isNotEmpty(delIdList)) {
                    tempSb.append("删除门店「").append(delIdList.stream().collect(Collectors.joining("、"))).append("」");
                }
            }
        }
        // 更新
        return tempSb.toString();
    }

    // 其他门店-开启的日志
    private String otherOpenLog(HmLinkStoreSettingDTO newStore, int level) {
        StringBuilder tempSb = new StringBuilder();
        String title = "";
        if (level == 4) {
            title = "省市筛选";
        }
        if (level == 5) {
            title = "其他门店-推荐门店";
        }
        if (level == 6) {
            title = "其他门店-附近门店";
        }
        String newTitle = "";
        int newDz = newStore.getDz();
        int newDy = newStore.getDy();
        int newNdy = newStore.getNdy();
        int newNdz = newStore.getNdz();
        if (level == 5 || level == 4) {
            newTitle = getLogOption(0, 0, newDz, newDy, 0, 0, level);
        }
        if (level == 6) {
            newTitle = getLogOption(0, 0, newNdz, newNdy, newNdz, newNdy, level);
        }
        tempSb.append("「").append(title).append("-").append(newTitle).append("」");
        return tempSb.toString();

    }

    // 其他门店-变更的日志
    private String otherChangeLog(HmLinkStoreSettingDTO oldStore, HmLinkStoreSettingDTO newStore, int level) {
        StringBuilder tempSb = new StringBuilder();
        String title = "";
        if (level == 5) {
            title = "推荐门店";
        }
        if (level == 6) {
            title = "附近门店";
        }
        String oldTitle = "";
        String newTitle = "";
        int oldDz = oldStore.getDz();
        int oldDy = oldStore.getDy();
        int newDz = newStore.getDz();
        int newDy = newStore.getDy();
        int oldNdz = oldStore.getNdz();
        int oldNdy = oldStore.getNdy();
        int newNdy = newStore.getNdy();
        int newNdz = newStore.getNdz();
        if (level == 5) {
            oldTitle = getLogOption(0, 0, oldDz, oldDy, 0, 0, level);
            newTitle = getLogOption(0, 0, newDz, newDy, 0, 0, level);
        }
        if (level == 6) {
            oldTitle = getLogOption(0, 0, oldNdz, oldNdy, oldNdz, oldNdy, level);
            newTitle = getLogOption(0, 0, newNdz, newNdy, newNdz, newNdy, level);
        }
        if (!oldTitle.equals(newTitle)) {
            tempSb.append("分配规则").append("「").append(title).append("-").append(oldTitle).append("」").append("变更为")
                    .append("「").append(title).append("-").append(newTitle).append("」");
        }
        tempSb.append(tempSb);
        return tempSb.toString();
    }

    // 服务门店、协管门店 、省市筛选
    private String ruleLog(HmLinkStoreSettingDTO oldStore, HmLinkStoreSettingDTO newStore, int level) {
        if (null == oldStore) {
            oldStore = new HmLinkStoreSettingDTO();
        }
        if (null == newStore) {
            newStore = new HmLinkStoreSettingDTO();
        }
        StringBuilder tempSb = new StringBuilder();
        int oldOpenFlag = oldStore.getOpen();
        int newOpenFlag = newStore.getOpen();
        String title = "";
        if (level == 1) {
            title = "服务门店";
        }
        if (level == 2) {
            title = "协管门店";
        }
        // 省市筛选
        if (level == 4) {
            title = "省市筛选";
        }
        String oldTitle = "";
        String newTitle = "";
        int oldZs = oldStore.getZs();
        int oldDz = oldStore.getDz();
        int oldDy = oldStore.getDy();
        int oldxg = oldStore.getXg();
        int newZs = newStore.getZs();
        int newDz = newStore.getDz();
        int newDy = newStore.getDy();
        int newXg = newStore.getXg();

        if (level == 1) {
            oldTitle = getLogOption(oldZs, 0, oldDz, oldDy, 0, 0, level);
            newTitle = getLogOption(newZs, 0, newDz, newDy, 0, 0, level);
        }
        if (level == 2) {
            oldTitle = getLogOption(0, oldxg, oldDz, oldDy, 0, 0, level);
            newTitle = getLogOption(0, newXg, newDz, newDy, 0, 0, level);
        }
        if (level == 4) {
            oldTitle = getLogOption(0, 0, oldDz, oldDy, 0, 0, level);
            newTitle = getLogOption(0, 0, newDz, newDy, 0, 0, level);
        }

        if (oldOpenFlag != newOpenFlag && newOpenFlag == 0) {
            tempSb.append("关闭").append("「").append(title).append("」");
        }
        if (newOpenFlag == 1) {
            if (!oldTitle.equals(newTitle)) {
                if (oldOpenFlag == 0) {
                    tempSb.append("开启").append("「").append(title).append("-").append(newTitle).append("」");
                } else {
                    tempSb.append("分配规则").append("「").append(title).append("-").append(oldTitle).append("」")
                            .append("变更为").append("「").append(title).append("-").append(newTitle).append("」");
                }
            }
        }
        return tempSb.toString();
    }

    // 拼接选项名称
    private String getLogOption(int zs, int xg, int dz, int dy, int ndz, int ndy, int level) {
        List<String> list = new ArrayList<>();
        if (zs == 1) {
            list.add("专属导购");
        }
        if (xg == 1) {
            list.add("协管导购");
        }
        String s1 = "(同意授权)";
        if (dz == 1) {
            if (level == 6) {
                list.add(s1 + "店长");
            } else {
                list.add("店长");
            }
        }
        if (dy == 1) {
            if (level == 6 && !list.toString().contains(s1)) {
                list.add(s1 + "导购");
            } else {
                if (level == 1 && level == 2) {
                    list.add("其他导购");
                } else {
                    list.add("导购");
                }
            }
        }
        String s2 = "(拒绝授权)";
        if (ndz == 1) {
            list.add(s2 + "店长");
        }
        if (ndy == 1) {
            if (!list.toString().contains(s2)) {
                list.add(s2 + "导购");
            } else {
                list.add("导购");
            }
        }
        return list.stream().collect(Collectors.joining("、"));
    }

    @RequestMapping("page")
    public RestResponse<Object> page(HmLinkSearchQDTO qdto, BasePageInfo basePageInfo) {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("enterpriseId", loginUser.getEnterpriseId());
        jsonObject.put("wxEnterpriseId", loginUser.getWxEnterpriseId());
        if (qdto.getLinkId() != null) {
            jsonObject.put("linkId", qdto.getLinkId());
        }
        if (StringUtils.isNotBlank(qdto.getStoreId())) {
            jsonObject.put("storeId", qdto.getStoreId());
        }
        if (qdto.getLinkType() != null) {
            jsonObject.put("linkType", qdto.getLinkType());
        } else {
            jsonObject.put("linkType", "1,2");
        }
        if (qdto.getStartDate() != null) {
            jsonObject.put("startDate", DateUtil.datetimeToString19(qdto.getStartDate()));
        }
        if (qdto.getEndDate() != null) {
            jsonObject.put("endDate", DateUtil.datetimeToString19(qdto.getEndDate()));
        }
        if (StringUtils.isNotBlank(qdto.getSearchParams())) {
            jsonObject.put("vagueQuery", qdto.getSearchParams());
        }
        List<String> creatorIdList = CreatorUtils.getCreatorIdList(0);
        if (CollectionUtils.isNotEmpty(creatorIdList)) {
            jsonObject.put("creatorIdList", creatorIdList.stream().collect(Collectors.joining(",")));
        }
        if (StringUtils.isBlank(qdto.getSortColumn())) {
            qdto.setSortColumn("createTime");
        }
        if (StringUtils.isBlank(qdto.getSortType())) {
            qdto.setSortType("desc");
        }
        jsonObject.put("orderByType", DataApiUtils.getOrderByType(qdto.getSortType()));
        Map<String, Integer> orderByFieldMap = new HashMap<String, Integer>(8){{
            put("createTime", 13);
            put("addNumT", 6);
            put("addNum", 7);
            put("clickTimesT", 8);
            put("clickTimes", 9);
            put("clickNumT", 10);
            put("clickNum", 11);
        }};
        jsonObject.put("orderByFields", DataApiUtils.getOrderByFields(qdto.getSortColumn(), "createTime",orderByFieldMap));
//        jsonObject.put("orderByField", qdto.getSortColumn() + " " + qdto.getSortType());
        jsonObject.put("pageNum", basePageInfo.getPageNum());
        jsonObject.put("pageSize", basePageInfo.getPageSize());
//        Page page = DataStatisticsParamUtils
//                .getPage(DataHttpUtil.post(StatisticsApolloKeyConstant.data_haoban_link_list, param));
//        if (page == null) {
//            return RestResponse.successResult();
//        }
        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), StatisticsApolloKeyConstant.data_haoban_link_list);
        Page page = DataApiUtils.getPageData(res);

        Page<HmLinkListVO> retPage = EntityUtil.changeEntityByJSON(Page.class, page);
        if (CollectionUtils.isEmpty(page.getResult())) {
            return RestResponse.successResult(retPage);
        }
        List<HmLinkListVO> list = EntityUtil.changeEntityListByJSON(HmLinkListVO.class, page.getResult());
        ServiceResponse<String> urlResp = this.hmLinkApiService.getHmLinkUrl();
        list.forEach(item -> {
            item.setLinkUrl(urlResp.getResult() + item.getShortCode());
        });
        retPage.setResult(list);
        return RestResponse.successResult(retPage);
    }

    @RequestMapping("detail")
    public RestResponse<Object> detail(Long linkId) {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = loginUser.getWxEnterpriseId();
        String enterpriseId = loginUser.getEnterpriseId();
        ServiceResponse<HmLinkDTO> linkResp = this.hmLinkApiService.getByLinkId(wxEnterpriseId, enterpriseId, linkId);
        if (!linkResp.isSuccess()) {
            return RestResponse.failure("1", "链接不存在");
        }
        HmLinkDTO link = linkResp.getResult();
        Map<String, Object> retMap = new HashMap<>();
        HmLinkVO linkVO = EntityUtil.changeEntityByJSON(HmLinkVO.class, link);
        // 是否达上线
        if (CollectionUtils.isNotEmpty(linkVO.getStoreList())) {
            List<String> storeIdList = this.hmQrcodeApiService.getHmStoreForWxa(wxEnterpriseId, enterpriseId);
            linkVO.getStoreList().forEach(item -> {
                if (storeIdList.contains(item.getStoreId())) {
                    item.setIsOver(0);
                } else {
                    item.setIsOver(1);
                }
            });
        }

        String memberLabelId = link.getMemberLabelId();
        if (StringUtils.isNotBlank(memberLabelId)) {
            MemberTagItemDTO tagItem = this.memberTagApiService.findMemberTagItem(memberLabelId);
            if (null != tagItem) {
                String tagId = tagItem.getTagId();
                MemberTagDTO tag = this.memberTagApiService.getMemberTagById(tagId);
                linkVO.setMemberLabelName(tag.getTagName() + "-" + tagItem.getTagItemName());
                linkVO.setMemberLabelStatus(tagItem.getStatus());
            }
        }
        ServiceResponse<String> urlResp = this.hmLinkApiService.getHmLinkUrl();
        linkVO.setLinkUrl(urlResp.getResult() + linkVO.getShortCode());
        retMap.put("link", linkVO);
        // 落地页
        Long pageId = link.getPageId();
        if (null != pageId) {
            ServiceResponse<HmPageDTO> resp = this.hmPageApiService.queryPageDetail(pageId);
            retMap.put("page", resp.getResult());
        }
        // 查询欢迎语
        String welcomeId = link.getWelcomeId();
        if (StringUtils.isNotBlank(welcomeId)) {
            ServiceResponse<WelcomeDetailDTO> resp = this.welcomeApiService.getWelcome(welcomeId, enterpriseId);
            if (resp.isSuccess() && null != resp.getResult()) {
                retMap.put("welcome", resp.getResult());
            }
        }
        return RestResponse.successResult(retMap);
    }

    // 链接统计
    @RequestMapping("statistics/total")
    public RestResponse<Object> statistics(@RequestBody HmLinkChartQO qo) {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("enterpriseId", loginUser.getEnterpriseId());
        jsonObject.put("linkId", qo.getLinkId());
        JSONObject param = DataStatisticsParamUtils.getParamNoPage(jsonObject);
//        DataStatisticsParamUtils.responseOne(DataHttpUtil.post(StatisticsApolloKeyConstant.data_haoban_link_overview, param));
        // HmLinkStatisticsVO vo = new HmLinkStatisticsVO();
        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), StatisticsApolloKeyConstant.data_haoban_link_overview);
        return RestResponse.successResult(getDataOne(res));
    }

    // 统计图表
    @RequestMapping("statistics/chart")
    public RestResponse<Object> statisticsChart(@RequestBody HmLinkChartQO qo) throws ParseException {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();

        Long linkId = qo.getLinkId();
        String startTimeStr = qo.getStartTime();
        String endTimeStr = qo.getEndTime();
        JSONObject jsonObject = new JSONObject();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = DateUtils.getStartTime(startTimeStr);
        Date endTime = DateUtils.getEndTime(endTimeStr);

        jsonObject.put("enterpriseId", loginUser.getEnterpriseId());
        jsonObject.put("linkId", linkId);
        jsonObject.put("startDate", df.format(startTime));
        jsonObject.put("endDate", df.format(endTime));
        // 日期填充
        List<String> dateList = DateUtils.getDateList(startTimeStr, endTimeStr, null);
        // 用于链接添加趋势图数据 企业+链接+日期
        String apolloKey = "data_haoban_link_add_trend_d";
        // 用于链接点击趋势图数据 企业+链接+日期
        String clickApolloKey = "data_haoban_link_click_trend_d";
        // 如果天数大于60，调用月接口
        if (DateUtil.daysBetween(startTime, endTime) > 60) {
            apolloKey = "data_haoban_link_add_trend_m";
            clickApolloKey = "data_haoban_link_click_trend_m";
        }
//        JSONObject param = DataStatisticsParamUtils.getParamNoPage(jsonObject);
//        StatisticsDTO newDTO = DataHttpUtil.post(apolloKey, param);

        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), apolloKey);
        List<JSONObject> resList = DataApiUtils.getDataList(res);
        Map<String, JSONObject> newMap = getTrendMapNew(resList);
        //
//        StatisticsDTO clickDTO = DataHttpUtil.post(clickApolloKey, param);
        Map<String, Object> clerkRes = DataApiUtils.http(jsonObject.toJSONString(), clickApolloKey);
        List<JSONObject> clerkResList = DataApiUtils.getDataList(clerkRes);
        Map<String, JSONObject> clickMap = getTrendMapNew(clerkResList);
        List<JSONObject> resultList = new ArrayList<>();
        for (String date : dateList) {
            JSONObject vo = new JSONObject();
            vo.put("bizDate", date);
            JSONObject newJson = newMap.get(date);
            if (newJson == null) {
                vo.put("addNum", 0);
            } else {
                vo.put("addNum", newJson.get("addNum"));
            }
            JSONObject clickJson = clickMap.get(date);
            if (clickJson == null) {
                vo.put("clickTimes", 0);
                vo.put("clickNum", 0);
            } else {
                vo.put("clickTimes", clickJson.get("clickTimes"));
                vo.put("clickNum", clickJson.get("clickNum"));
            }
            resultList.add(vo);
        }
        return RestResponse.successResult(resultList);
    }

    // 导购统计
    @RequestMapping("statistics/clerk")
    public RestResponse<Object> statisticsClerk(@RequestBody HmLinkClerkListQO qo) {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        qo.getInFields().setEnterpriseId(loginUser.getEnterpriseId());

        JSONObject paramJson = (JSONObject) JSON.toJSON(qo.getInFields());
        DataApiUtils.dealParamJson(paramJson, "linkSelect1", "vagueQueryStore");
        DataApiUtils.dealParamJson(paramJson, "linkSelect2", "vagueQueryClerk");
        DataApiUtils.dealParamJson(paramJson, "startTime", "startDate");
        DataApiUtils.dealParamJson(paramJson, "endTime", "endDate");
        Map<String, Integer> orderByFieldMap = new HashMap<String, Integer>(8){{
            put("addNumT", 8);
            put("addNum", 9);
        }};
        paramJson.put("orderByType", DataApiUtils.getOrderByType( qo.getInFields().getOrderByField()));
        paramJson.put("orderByFields", DataApiUtils.getOrderByFields( qo.getInFields().getOrderByField(),
                "addNum", orderByFieldMap));
        Map<String, Object> res = DataApiUtils.http(paramJson.toJSONString(), StatisticsApolloKeyConstant.data_haoban_link_detail);

        return RestResponse.successResult(DataApiUtils.getPageData(res));
    }

    @RequestMapping("statistics/clerk/excel")
    public RestResponse<String> statisticsClerkExcel(@RequestBody HmLinkClerkListQO qo) {
        qo.setPageNo(1);
        qo.setPageSize(1);
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        qo.getInFields().setEnterpriseId(loginUser.getEnterpriseId());
        JSONObject paramJson = (JSONObject) JSON.toJSON(qo.getInFields());
        DataApiUtils.dealParamJson(paramJson, "linkSelect1", "vagueQueryStore");
        DataApiUtils.dealParamJson(paramJson, "linkSelect2", "vagueQueryClerk");
        DataApiUtils.dealParamJson(paramJson, "startTime", "startDate");
        DataApiUtils.dealParamJson(paramJson, "endTime", "endDate");
        Map<String, Integer> orderByFieldMap = new HashMap<String, Integer>(8){{
            put("addNumT", 8);
            put("addNum", 9);
        }};
        paramJson.put("orderByType", DataApiUtils.getOrderByType( qo.getInFields().getOrderByField()));
        paramJson.put("orderByFields", DataApiUtils.getOrderByFields( qo.getInFields().getOrderByField(),
                "addNum", orderByFieldMap));
        Map<String, Object> res = DataApiUtils.http(paramJson.toJSONString(), StatisticsApolloKeyConstant.data_haoban_link_detail);
        Page page = DataApiUtils.getPageData(res) ;
        final int totalCount = page.getTotalCount() ;
        if (totalCount == 0) {
            return RestResponse.failure("9999", "导出数据条数为0");
        }
        Long linkId = qo.getInFields().getLinkId() ;
        ServiceResponse<HmLinkDTO> linkResp = this.hmLinkApiService.getByLinkId(loginUser.getWxEnterpriseId(), loginUser.getEnterpriseId(), linkId);
        if (!linkResp.isSuccess()) {
            return RestResponse.failure("1", "链接不存在");
        }
        AuthorizedUser user = new AuthorizedUser();
        user.setUserId(loginUser.getClerkId());
        user.setEnterpriseId(loginUser.getEnterpriseId());
        user.setRealName(loginUser.getClerkName());
        String fileName = "引流加人数据-"+linkResp.getResult().getName() ;
        String startDate = qo.getInFields().getStartTime() ;
        String endDate = qo.getInFields().getEndTime() ;
        if (null != startDate && null != endDate) {
            fileName = fileName + "-" + startDate  + "到" +  endDate ;
        }
        DownloadTask task = new DownloadTask();
        task.setTaskTypeEnum(TaskTypeEnum.QYWX_HM_LINK_DATA);
        task.setUser(user);
        task.setDataType(1);
        task.setTotalCount(totalCount);
        task.setFileName(fileName);
        task.setChannelName(TaskTypeEnum.QYWX_HM_LINK_DATA.getName());
        task.setBucketName(BucketNameEnum.REPORT_50000.getName());
        task.setSearchDataParams(JSON.toJSONStringWithDateFormat(qo, DatePattern.NORM_DATETIME_PATTERN));
        task.setHandler(linkDataExcelHandler);
        JSONResponse jsonResponse = DownloadTaskUtil.createDownloadTask(task);
        final String reportId;
        if (jsonResponse.isSuccess()) {
            reportId = (String) jsonResponse.getResult();
        } else {
            return RestResponse.failure("9999", jsonResponse.getErrorMessage());
        }
        return RestResponse.successResult(reportId);
    }

    /**
     * com.gic.haoban.manage.web.controller.hm.HmQrcodeController.wxUserAddLogList 一样
     */
    @RequestMapping("statistics/log")
    public RestResponse<Object> statisticsDetail(@RequestBody WxUserAddLogSearchQDTO qdto) {
        BasePageInfo pageInfo = new BasePageInfo();
        pageInfo.setPageNum(qdto.getPageNum());
        pageInfo.setPageSize(qdto.getPageSize());
        ServiceResponse<Page<WxUserAddLogDTO>> pageResp = this.wxUserAddLogApiService.page(qdto, pageInfo);
        Page<WxUserAddLogVO> retPage = PageHelperUtils.changePageHelperToCurrentPage(pageResp.getResult().getResult(),
                WxUserAddLogVO.class);
        return RestResponse.successResult(retPage);
    }

    private static Map<String, JSONObject> getTrendMap(StatisticsDTO newDTO) {
        Map<String, JSONObject> newMap = new HashMap<>();
        if (newDTO != null) {
            List<JSONObject> newList = newDTO.getData();
            if (CollectionUtils.isNotEmpty(newList)) {
                for (JSONObject temp : newList) {
                    newMap.put(temp.getString("bizDate"), temp);
                }
            }
        }
        return newMap;
    }

    private static Map<String, JSONObject> getTrendMapNew(List<JSONObject> list) {
        Map<String, JSONObject> newMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (JSONObject temp : list) {
                newMap.put(temp.getString("bizDate"), temp);
            }
        }
        return newMap;
    }

    public static JSONObject getDataOne(Map<String, Object> res) {
        List<JSONObject> list = DataApiUtils.getDataList(res);
        return CollectionUtils.isNotEmpty(list) ? list.get(0) : null;
    }

}
