package com.tanpu.feo.feojob.jobs;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanpu.common.constant.BizStatus;
import com.tanpu.feo.feojob.config.MorningPaperProperties;
import com.tanpu.feo.feojob.dao.user.entity.*;
import com.tanpu.feo.feojob.dao.user.mapper.*;
import com.tanpu.feo.feojob.feign.wxcp.FeignClientForWxCp;
import com.tanpu.feo.feojob.feign.wxmp.FeignClientForWxMp;
import com.tanpu.feo.feojob.service.RedirectService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zejia zj wu
 * @date 2021-08-10
 * @Description 早报推送
 */
@Component
@Slf4j
public class DaySubJob {

    @Resource
    private DaySubjectMapper daySubjectMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private OrgExtMapper orgExtMapper;
    @Resource
    MorningPaperProperties morningPaperProperties;
    @Value("${daySubject.daySubjectUrl}")
    private String daySubjectUrl;
    @Resource
    private FeignClientForWxCp feignClientForWxCp;
    @Resource
    private FeignClientForWxMp feignClientForWxMp;
    @Resource
    private DaySelectionMapper daySelectionMapper;
    @Resource
    private OrgMapper orgMapper;
    @Resource
    private RedirectService redirectService;


    @Scheduled(cron = "0 30 7 * * ? ")   //
    public void execute() {
        log.info("====== 开始执行 DaySubJob ======");
        try {
            sendDaySubjectMessage();
        } catch (Exception e) {
            log.error("====== 异常结束执行 DaySubJob ,错误:{}=======", e);
        }
        log.info("====== 结束执行 DaySubJob ======");
    }

    public void sendDaySubjectMessage() {
        List<DaySubjectEntity> daySubjectList = getDaySubList(DateUtil.today());
        if (CollectionUtils.isEmpty(daySubjectList)) {
            log.info("====== DaySubJob 暂无需要推送的早报");
            return;
        }
        Map<String, List<DaySubjectEntity>> stringListMap = daySubjectList.stream().collect(Collectors.groupingBy(DaySubjectEntity::getDsPt));
        String mainTitle = getOneMorningTitle();
        for (String orgId : stringListMap.keySet()) {
            log.info("开始推送机构(orgId={})的早报", orgId);
            //查询orgCode
            OrgEntity orgEntity = orgMapper.selectOne(new LambdaQueryWrapper<OrgEntity>().eq(OrgEntity::getId, orgId).last("limit 1"));
            if (ObjectUtil.isNull(orgEntity)) {
                log.error("找不到机构(orgId={})的信息", orgId);
                return;
            }
            List<DaySubjectEntity> daySubjectEntities = stringListMap.get(orgId);
            if (CollectionUtils.isEmpty(daySubjectEntities)) {
                log.warn("当前机构(orgCode={})没有要推送的早报", orgEntity.getOrgCode());
                return;
            }
            sendDaySubject(orgId, daySubjectEntities, mainTitle);
        }
    }

    public void sendDaySubject(String orgId, List<DaySubjectEntity> daySubjectList,String mainTitle){
        if (CollectionUtils.isEmpty(daySubjectList) || StringUtils.isBlank(orgId) || StringUtils.isBlank(mainTitle)) {
            return;
        }
        OrgEntity orgEntity = orgMapper.selectOne(new LambdaQueryWrapper<OrgEntity>().eq(OrgEntity::getId, orgId).last("limit 1"));
        if (orgEntity == null) {
            return;
        }
        // 查询 机构配置信息
        OrgExtEntity orgExtEntity = orgExtMapper.selectOne(new LambdaQueryWrapper<OrgExtEntity>()
                .eq(OrgExtEntity::getOrgId, orgId)
                .eq(OrgExtEntity::getDeleteTag, BizStatus.DeleteTag.tag_init_str));
        String jsonKey = ObjectUtil.isNotNull(orgExtEntity) ? orgExtEntity.getJsonWxcpKey() : null;
        if (StringUtils.isBlank(jsonKey)) {
            return;
        }

        //在orgExt 表中有查到 jsonKey 执行消息推送任务
        JSONObject jsonKeyInfo = JSONUtil.parseObj(jsonKey);
        // 查询该机构下 用户
        LambdaQueryWrapper<UserInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfoEntity::getDeletetag, BizStatus.DeleteTag.tag_init_str)
                .eq(UserInfoEntity::getOrgId, orgId)
                .eq(UserInfoEntity::getLevel, "2");
        List<UserInfoEntity> userInfoEntities = userInfoMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(userInfoEntities)) {
            log.info("机构(orgCode={})没有需要推送早报的人员", orgEntity.getOrgCode());
            return;
        }
        log.info("机构(orgCode={})本次推送{}人,早报文章{}篇", orgEntity.getOrgCode(), userInfoEntities.size(), daySubjectList.size());


        for (UserInfoEntity userInfoEntity : userInfoEntities) {
            for (DaySubjectEntity daySubjectEntity : daySubjectList) {
                HashMap<String, String> parmMap = new HashMap<>();
                parmMap.put("type", "text");
                String wxOpenId = userInfoEntity.getUiOpenid();
                String wxcpUId = userInfoEntity.getWxcpUid();
                if (StringUtils.isNotBlank(wxcpUId)) {
                    // 1 企业微信 推送
                    String agentId = jsonKeyInfo.getStr("agentId");
                    String corpId = jsonKeyInfo.getStr("corpId");
                    // ww=corpId&orgCode=orgCode
                    String link = String.format(daySubjectUrl, corpId, orgEntity.getOrgCode(), daySubjectEntity.getId());
                    String url = redirectService.getRedirectLink(link);
                    log.info("早报推送使用重定向链接, redirect-url: {}, origin-url: {}", url, link);
                    StringBuilder sb = new StringBuilder();
                    sb.append(mainTitle).append("\n\n")
                            .append(morningPaperProperties.getSubTitle()).append("\n\n")
                            .append("<a href=\"")
                            .append(url).append("\">")
                            .append("快去转发获客吧")
                            .append("</a>\n\n");
                    parmMap.put("content", sb.toString());
                    log.info("===企业微信 推送===userID:{} agentId:{} corpId:{} wxcpUId:{} parmMap:{}", userInfoEntity.getId(), agentId, corpId, wxcpUId, JSONUtil.toJsonStr(parmMap));
                    if (StrUtil.isNotBlank(agentId) && StrUtil.isNotBlank(corpId) && StrUtil.isNotBlank(wxcpUId) && StrUtil.isNotBlank(JSONUtil.toJsonStr(parmMap))) {
                        feignClientForWxCp.sendMessage(agentId, corpId, wxcpUId, JSONUtil.toJsonStr(parmMap));
                    }
                }else if (StringUtils.isNotBlank(wxOpenId)) {
                    // 2 公众号推送
                    String wxAppID = jsonKeyInfo.getStr("sendMessageAppId");
                    // ww=wxAppID&orgCode=orgCode
                    String link = String.format(daySubjectUrl, wxAppID, orgEntity.getOrgCode(), daySubjectEntity.getId());
                    String url = redirectService.getRedirectLink(link);
                    log.info("早报推送使用重定向链接, redirect-url: {}, origin-url: {}", url, link);
                    StringBuilder sb = new StringBuilder();
                    sb.append(mainTitle).append("\n\n")
                            .append(morningPaperProperties.getSubTitle()).append("\n\n")
                            .append("<a href=\"")
                            .append(url).append("\">")
                            .append("快去转发获客吧")
                            .append("</a>\n\n");
                    parmMap.put("content", sb.toString());
                    log.info("===公众号 推送=== userID:{} wxAppID:{} wxOpenId:{} parmMap:{}", userInfoEntity.getId(), wxAppID, wxOpenId, JSONUtil.toJsonStr(parmMap));
                    if (StrUtil.isNotBlank(wxAppID) && StrUtil.isNotBlank(wxOpenId) && StrUtil.isNotBlank(JSONUtil.toJsonStr(parmMap))) {
                        feignClientForWxMp.sendMessage(wxAppID, wxOpenId, JSONUtil.toJsonStr(parmMap));
                    }
                } else {
                    if (userInfoEntity.getUiTelphone() != null && userInfoEntity.getUiTelphone().startsWith("1700000")) {
                        log.info("内部测试账号,跳过, uid: {}, telphone: {}", userInfoEntity.getId(), userInfoEntity.getUiTelphone());
                        continue;
                    }
                    log.error("======用户ID:{} 没有微信或企业微信id======", userInfoEntity.getId());
                }
            }
        }
    }

    public List<DaySubjectEntity> getDaySubList(String today) {
        //查询今日早报 已上架
        LambdaQueryWrapper<DaySubjectEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DaySubjectEntity::getDeletetag, BizStatus.DeleteTag.tag_init_str)
                .eq(DaySubjectEntity::getDsDate, today)
                .le(DaySubjectEntity::getDsTaskuptime, new Date())
                .eq(DaySubjectEntity::getDsStatus, "1");
        List<DaySubjectEntity> daySubjectEntities = daySubjectMapper.selectList(queryWrapper);
        List<DaySubjectEntity> daySubjectEntityList = daySubjectEntities.stream().filter(daySubjectEntity -> {
            // 过滤掉 早报下没有文章的
            List<DaySelection> daySelections = daySelectionMapper.selectList(new LambdaQueryWrapper<DaySelection>()
                    .eq(DaySelection::getDsSubjectId, daySubjectEntity.getId())
                    .eq(DaySelection::getDeletetag, BizStatus.DeleteTag.tag_init_str));
            return CollectionUtils.isNotEmpty(daySelections);
        }).collect(Collectors.toList());
        return daySubjectEntityList;
    }

    public List<DaySubjectEntity> getDaySubject(String date, String orgId) {
        LambdaQueryWrapper<DaySubjectEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DaySubjectEntity::getDeletetag, BizStatus.DeleteTag.tag_init_str)
                .eq(DaySubjectEntity::getDsDate, DateUtil.parseDate(date))
                .eq(DaySubjectEntity::getDsPt, orgId)
                .eq(DaySubjectEntity::getDsStatus, "1");
        return daySubjectMapper.selectList(queryWrapper);
    }

    public String getOneMorningTitle() {
        return morningPaperProperties.getTodayMailTitle();
    }


    public static void main(String[] args) throws Exception {
        log.info("=========================");
    }

}