package com.hzya.frame.sysnew.sendMessageLog.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hzya.frame.sysnew.application.api.dao.ISysApplicationApiDao;
import com.hzya.frame.sysnew.application.api.entity.SysApplicationApiEntity;
import com.hzya.frame.sysnew.application.apiPara.dao.ISysApplicationApiParaDao;
import com.hzya.frame.sysnew.application.apiPara.entity.SysApplicationApiParaEntity;
import com.hzya.frame.sysnew.application.dao.ISysApplicationDao;
import com.hzya.frame.sysnew.application.entity.SysApplicationEntity;
import com.hzya.frame.sysnew.application.service.impl.ApplicationCache;
import com.hzya.frame.sysnew.messageTemplate.dao.ISysMessageTemplateDao;
import com.hzya.frame.sysnew.messageTemplate.entity.SysMessageTemplateEntity;
import com.hzya.frame.sysnew.person.dao.ISysPersonDao;
import com.hzya.frame.sysnew.pushMessage.entity.SysPushMessageEntity;
import com.hzya.frame.sysnew.sendMessageLog.entity.SysSendMessageLogEntity;
import com.hzya.frame.sysnew.sendMessageLog.dao.ISysSendMessageLogDao;
import com.hzya.frame.sysnew.sendMessageLog.service.ISysSendMessageLogService;
import com.hzya.frame.sysnew.user.dao.ISysUserDao;
import com.hzya.frame.sysnew.user.entity.SysUserEntity;
import com.hzya.frame.sysnew.warningConfig.dao.ISysWarningConfigDao;
import com.hzya.frame.sysnew.warningConfig.entity.SysWarningConfigEntity;
import com.hzya.frame.sysnew.warningInterface.dao.ISysWarningInterfaceDao;
import com.hzya.frame.sysnew.warningInterface.entity.SysWarningInterfaceEntity;
import com.hzya.frame.uuid.UUIDUtils;
import com.hzya.frame.web.entity.BaseResult;
import com.hzya.frame.web.entity.JsonResultEntity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;

import com.hzya.frame.basedao.service.impl.BaseService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * (SysSendMessageLog)表服务实现类
 *
 * @author makejava
 * @since 2024-08-30 14:19:30
 */
@Service(value = "sysSendMessageLogService")
public class SysSendMessageLogServiceImpl extends BaseService<SysSendMessageLogEntity, String> implements ISysSendMessageLogService {

    @Resource
    private ApplicationCache applicationCache;
    @Resource
    private ISysWarningInterfaceDao sysWarningInterfaceDao;
    @Resource
    private ISysWarningConfigDao sysWarningConfigDao;
    @Resource
    private ISysMessageTemplateDao sysMessageTemplateDao;
    @Resource
    private ISysUserDao sysUserDao;
    @Resource
    private ISysPersonDao sysPersonsDao;

    @Resource
    private ISysApplicationApiDao sysApplicationApiDao;
    @Resource
    private ISysApplicationApiParaDao sysApplicationApiParaDao;

    @Value("${zt.url}")
    private String url ;

    private ISysSendMessageLogDao sysSendMessageLogDao;

    @Autowired
    public void setSysSendMessageLogDao(ISysSendMessageLogDao dao) {
        this.sysSendMessageLogDao = dao;
        this.dao = dao;
    }

    @Override
    public JsonResultEntity queryEntityPage(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity == null || entity.getPageNum() == null || entity.getPageSize() == null) {
            return BaseResult.getFailureMessageEntity("分页查询参数不存在");
        }
        PageHelper.startPage(entity.getPageNum(), entity.getPageSize());
        List<SysSendMessageLogEntity> list = sysSendMessageLogDao.queryByLike(entity);
        PageInfo pageInfo = new PageInfo(list);
        return BaseResult.getSuccessMessageEntity("查询数据成功", pageInfo);
    }

    @Override
    public JsonResultEntity queryEntity(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity == null) {
            entity = new SysSendMessageLogEntity();
        }
        List<SysSendMessageLogEntity> list = sysSendMessageLogDao.queryByLike(entity);
        return BaseResult.getSuccessMessageEntity("查询数据成功", list);
    }

    @Override
    public JsonResultEntity getEntity(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity == null) {
            return BaseResult.getFailureMessageEntity("参数不能为空");
        }
        if (entity.getId() == null || "".equals(entity.getId())) {
            return BaseResult.getFailureMessageEntity("系统错误");
        }
        entity = sysSendMessageLogDao.get(entity.getId());
        if (entity == null) {
            return BaseResult.getFailureMessageEntity("获取发送消息日志失败");
        }
        return BaseResult.getSuccessMessageEntity("获取发送消息日志成功", entity);
    }

    @Override
    public JsonResultEntity markRead(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity.getAppId() == null || "".equals(entity.getAppId())) {
            return BaseResult.getFailureMessageEntity("传入appId不能为空");
        }
        List<SysSendMessageLogEntity> list = sysSendMessageLogDao.queryBase(entity);
        if (list == null || list.size() == 0) {
            return BaseResult.getSuccessMessageEntity("未找到需要标记已读的消息日志", list);
        }
        for (SysSendMessageLogEntity log : list) {
            log.setState(1);
            log.setUpdate();
            sysSendMessageLogDao.update(log);
        }
        return BaseResult.getSuccessMessageEntity("标记已读成功", list);
    }

    @Override
    public JsonResultEntity saveEntity(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity == null) {
            return BaseResult.getFailureMessageEntity("参数不能为空");
        }
        entity.setCreate();
        sysSendMessageLogDao.save(entity);
        return BaseResult.getSuccessMessageEntity("保存发送消息日志成功", entity);
    }

    @Override
    public JsonResultEntity updateEntity(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity == null) {
            return BaseResult.getFailureMessageEntity("参数不能为空");
        }
        if (entity.getId() == null || "".equals(entity.getId())) {
            return BaseResult.getFailureMessageEntity("系统错误");
        }
        entity.setUpdate();
        sysSendMessageLogDao.update(entity);
        return BaseResult.getSuccessMessageEntity("修改发送消息日志成功", entity);
    }

    @Override
    public JsonResultEntity deleteEntity(JSONObject jsonObject) {
        SysSendMessageLogEntity entity = getData("jsonStr", jsonObject, SysSendMessageLogEntity.class);
        if (entity == null) {
            return BaseResult.getFailureMessageEntity("参数不能为空");
        }
        if (entity.getId() == null || "".equals(entity.getId())) {
            return BaseResult.getFailureMessageEntity("系统错误");
        }
        entity.setUpdate();
        ;
        sysSendMessageLogDao.logicRemove(entity);
        return BaseResult.getSuccessMessageEntity("删除发送消息日志成功", entity);
    }


    /**
     * sendMessage方法：根据请求错误消息，组装成消息模版，推送到三方业务系统
     * 1、先获取接口调用的日志数据
     * 2、如果日志状态为失败，且该接口预警状态为启用，则进行消息推送
     * 3、根据预警配置，找到消息模版，并生成消息内容
     * 4、根据预警配置，找到预警应用，并推送消息
     * 5、保存消息推送日志
     */
    @Override
    public boolean sendMessage(SysPushMessageEntity entity) {
        String status = entity.getStatus();
        Long receiveApiCode = entity.getReceiveApiCode();
        String sendAppName = entity.getSendAppName();
        String receiveApiName = entity.getReceiveApiName();
        String recieveAppName = entity.getReceiveAppName();
        String returnData = entity.getReturnData();
        String sendMsgContent = "";

        //SysWarningInterfaceEntity interfaceEntityApi = new SysWarningInterfaceEntity();
        SysWarningInterfaceEntity interfaceEntity = new SysWarningInterfaceEntity();
        SysWarningConfigEntity configEntity = new SysWarningConfigEntity();
        SysMessageTemplateEntity templateEntity = new SysMessageTemplateEntity();
        SysApplicationApiParaEntity sysApplicationApiParaEntity = new SysApplicationApiParaEntity();

        //interfaceEntityApi.setApiCode(receiveApiCode);
        interfaceEntity.setApiCode(receiveApiCode);
        if (status == null) {
            logger.error("日志状态为空");
            return false;
        }
        //只有发送失败的日志才会推送消息，成功的日志不推送消息
        if ("4".equals(status)) {
            try {
                interfaceEntity = sysWarningInterfaceDao.queryOne(interfaceEntity);
            } catch (Exception e) {
                logger.error("API接口预警信息可能配置了多个");
                return false;
            }
            //List<SysWarningInterfaceEntity> interfaceEntityList =sysWarningInterfaceDao.queryByLike(interfaceEntityApi);
            //for(SysWarningInterfaceEntity interfaceEntity : interfaceEntityList){
                if (interfaceEntity == null) {
                    logger.error("未找到API接口预警信息");
                    return false;
                }
                //只有预警接口状态为启用，才会进行消息推送
                if (interfaceEntity.getStatus() == null || interfaceEntity.getStatus().equals("1") == false) {
                    logger.error("API接口未启用推送");
                    return false;
                }
                //根据主表id，找到主表记录中的消息模版id
                String warningConfigId = interfaceEntity.getWarningConfigId();
                SysWarningConfigEntity statusEntity = new SysWarningConfigEntity();
                statusEntity.setStatus("1");
                statusEntity.setId(warningConfigId);
                if (warningConfigId == null || "".equals(warningConfigId)) {
                    logger.error("未找到该接口预警配置信息的主表id");
                    return false;
                }
                configEntity = sysWarningConfigDao.queryOne(statusEntity);
                if (configEntity == null) {
                    logger.error("未找到该接口预警配置信息");
                    return false;
                }
                String messageTemplateId = configEntity.getMessageTemplateId();
                if (messageTemplateId == null || "".equals(messageTemplateId)) {
                    logger.error("未找到该接口预警配置信息的消息模版id");
                    return false;
                }
                templateEntity = sysMessageTemplateDao.get(messageTemplateId);
                if (templateEntity == null) {
                    logger.error("未找到该接口预警配置信息的消息模版信息");
                    return false;
                }
                if(templateEntity.getState() == null || !"1".equals(templateEntity.getState())){
                    logger.error("当前预警配置中消息模版状态为禁用");
                    return false;
                }

                String messageContent = templateEntity.getMessageContents();
                if (messageContent == null || "".equals(messageContent)) {
                    logger.error("未找到该接口预警配置信息的消息模版内容");
                    return false;
                }
                //推送消息内容拼接
                sendMsgContent = messageContent.replace("${receive_app_name}", recieveAppName);
                sendMsgContent = sendMsgContent.replace("${send_app_name}", sendAppName);
                sendMsgContent = sendMsgContent.replace("${receive_api_name}", receiveApiName);
                sendMsgContent = sendMsgContent.replace("${return_data}", returnData);
                //消息模版名称
                String templateName = templateEntity.getTemplateName();
                String type = "";
                String bodyParams = "";
                String warningAppId = configEntity.getWarningAppId();

                Long warningApiCode = configEntity.getAcceptMessageApiCode();
                String appCode = String.valueOf(warningApiCode).substring(0, 6);
                SysApplicationEntity warningApp = getAppByAppId(appCode);
                String warningAppType = warningApp.getAppType();
                Integer warningAppCode = warningApp.getAppId();

                //查询预警人员id列表
                String recipientIdList = configEntity.getRecipientIdList();
                //根据预警人员id列表，获取预警应用人员id列表
                String warningAppReceiverIdList = getWarningAppReceiverIdList(warningAppType, recipientIdList);

                switch (warningAppType) {
                    case "6WX":
                        //调用微信推送消息
                        break;
                    case "5DD":
                        //消息类型：3表示钉钉
                        type = "3";
                        //获取钉钉发送消息时使用的微应用的AgentID
                        sysApplicationApiParaEntity.setAppId(warningAppId);
                        sysApplicationApiParaEntity.setInterfaceKey("agentId");
                        String agentId = sysApplicationApiParaDao.queryOne(sysApplicationApiParaEntity).getInterfaceValue();
                        //拼接调用钉钉接口的body参数
                        bodyParams = splicingDDBody(sendMsgContent, agentId, warningAppReceiverIdList).toString();
                        break;
                    default:
                        logger.error("未找到该应用类型");
                        break;
                }
                String result = HttpRequest.post(url).
                        header("appId", warningAppCode.toString()).
                        header("apiCode", warningApiCode.toString()).
                        header("publicKey", "ZJYA7v6DubGMm8EdBPGo+Jj9wCpUeCGJEpfBRLiInq4dvDlCe7eDIk+3zDUT+v578prj").
                        header("secretKey", "bsAMm6tvJs/BV1SO/9ZzjlW+OQaK0mwyv6rLvktyNy/OdltLuG2zze9bT7ttfAA9j3JzOP8MtA1LSGvL+2BWG8c/o7DKi92S4mr3zcGearA=").
                        body(bodyParams).
                        execute().
                        body();
                JSONObject resultJson = JSONObject.parseObject(result);
                String body = resultJson.getString("attribute");
                SysApplicationApiEntity warningApiEntity = getApiByAppIdApiCode(warningAppId, warningApiCode.toString());

                //根据预警接口编码，以及返回数据，判断消息推送是否成功
                if (warningApiEntity.getReturnSuccessField() != null && !"".equals(warningApiEntity.getReturnSuccessField())
                        && warningApiEntity.getReturnSuccessValue() != null && !"".equals(warningApiEntity.getReturnSuccessValue())) {
                    //先判断返回值是否为JSON格式
                    if (JSONUtil.isTypeJSON(body)) {
                        JSONObject cheackdatas = JSONObject.parseObject(body);
                        JSONObject datas = JSONObject.parseObject(body);
                        String checkdata = cheackdatas.getString(warningApiEntity.getReturnSuccessField());
                        //判断返回值是否为预警接口预期的返回值(1、返回值匹配2、返回值配置的就是not null3、返回值带.)
                        if (checkdata != null && warningApiEntity.getReturnSuccessValue().equals(checkdata)) {
                            logger.info("推送消息成功,开始保存日志");
                        } else if (warningApiEntity.getReturnSuccessValue().equals("not null") && checkdata != null) {
                            logger.info("推送消息成功,开始保存日志");
                        } else {
                            String fieldname = warningApiEntity.getReturnSuccessField();
                            if (fieldname.contains(".")) {
                                String[] fileds = fieldname.split("\\.");
                                boolean flags = false;
                                for (int i = 0; i < fileds.length; i++) {
                                    if (JSONUtil.isTypeJSON(datas.getString(fileds[i]))) {
                                        datas = datas.getJSONObject(fileds[i]);
                                        if (fileds.length - 2 == i) {
                                            String a = datas.getString(fileds[i + 1]);
                                            if (a != null && warningApiEntity.getReturnSuccessValue().equals(a)) {
                                                flags = true;
                                                break;
                                            } else if (warningApiEntity.getReturnSuccessValue().equals("not null") && a != null) {
                                                flags = true;
                                                break;
                                            } else {
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (flags) {
                                    logger.info("推送消息成功,开始保存日志");
                                } else {
                                    logger.error("推送消息失败,返回值错误");
                                }

                            } else {
                                logger.error("推送消息失败,返回值错误");
                            }
                        }
                    } else {
                        logger.error("接口调用失败,返回格式错误，不是JSON");
                    }
                } else {
                    logger.error("api返回信息字段未配置，开始保存日志");
                }
                saveLog(sendMsgContent, type, resultJson.toString(), templateName, recipientIdList, warningAppReceiverIdList, interfaceEntity.getId());
                logger.info("保存日志成功");
            //}

        } else {
            logger.error("日志状态为成功，不需要推送消息");
            return false;
        }
        return true;
    }

    /**
     * 根据appCode查询缓存中的应用信息
     */
    private SysApplicationEntity getAppByAppId(String appId) {
        String str = "appId" + appId;
        Object o = applicationCache.get("1", str);
        if (o != null) {
            return (SysApplicationEntity) o;
        }
        return null;
    }

    /**
     * 根据appId和apiCode查询缓存中的api信息
     */
    private SysApplicationApiEntity getApiByAppIdApiCode(String appId, String apiCode) {

        String str = "appId" + appId + "apiCode" + apiCode;
        Object o = applicationCache.get("2", str);
        if (o != null) {
            return (SysApplicationApiEntity) o;
        }
        return null;
    }

    /**
     * 保存推送消息日志时，需要循环预警应用人员id列表
     */
    public void saveLog(String sendMsgContent, String type, String resultMessage, String templateName, String recipientIdList, String warningAppReceiverIdList,String warningInterfaceId) {
        SysSendMessageLogEntity logEntity = new SysSendMessageLogEntity();
        logEntity.setSendCount(sendMsgContent);
        logEntity.setType(type);
        logEntity.setSendDatetime(new Date());

        logEntity.setSts("Y");
        logEntity.setCreate_user_id("1");
        logEntity.setModify_user_id("1");
        logEntity.setCreate_time(new Date());
        logEntity.setModify_time(new Date());
        logEntity.setOrg_id("0");
        logEntity.setCompanyId("0");

        logEntity.setSendPersonId("1");
        logEntity.setResultMessage(resultMessage);
        logEntity.setSourceModelName(templateName);
        logEntity.setState(0);
        logEntity.setWarningInterfaceId(warningInterfaceId);
        String[] recipientsInteriorIdList = warningAppReceiverIdList.split(",");
        String[] recipientsPersonIdList = recipientIdList.split(",");

        for (int i = 0; i < recipientsInteriorIdList.length; i++) {
            logEntity.setRecipientsInteriorId(recipientsInteriorIdList[i]);
            logEntity.setRecipientsPersonId(recipientsPersonIdList[i]);
            logEntity.setId(UUIDUtils.getUUID());
            sysSendMessageLogDao.save(logEntity);
        }
    }

    /**
     * 拼接调用钉钉接口的body参数
     */
    public JSONObject splicingDDBody(String sendMsgContent, String agentId, String userid_list) {
        JSONObject bodyJson = new JSONObject();
        JSONObject msg = new JSONObject();
        JSONObject text = new JSONObject();

        text.put("content", sendMsgContent);
        msg.put("msgtype", "text");
        msg.put("text", text);
        bodyJson.put("msg", msg);
        bodyJson.put("to_all_user", "false");
        bodyJson.put("agent_id", agentId);
        bodyJson.put("userid_list", userid_list);

        return bodyJson;
    }

    /**
     * 根据预警应用类型和预警人员id列表,获取预警应用人员id列表
     */
    public String getWarningAppReceiverIdList(String warningAppType, String personIdList) {

        String[] personIdArray = personIdList.split(",");
        List<SysUserEntity> sysUserList = new ArrayList<>();
        SysUserEntity sysUserEntity = new SysUserEntity();
        for (String personId : personIdArray) {
            sysUserEntity.setPersonId(personId);
            sysUserList.add(sysUserDao.queryOne(sysUserEntity));
        }
        String warningAppReceiverIdList = "";
        switch (warningAppType) {
            case "6WX":
                //获取微信预警人员id列表
                break;
            case "5DD":
                //获取钉钉预警人员id列表
                for (SysUserEntity sysUser : sysUserList) {
                    if (sysUser.getDdUserId() == null || "".equals(sysUser.getDdUserId())) {
                        String personName = sysPersonsDao.get(sysUser.getPersonId()).getPersonName();
                        logger.error("接收人:" +personName + "未配置钉钉用户id");
                    }
                    if (sysUser.getDdUserId() != null && !"".equals(sysUser.getDdUserId())) {
                        if (!warningAppReceiverIdList.isEmpty()) {
                            warningAppReceiverIdList += ",";
                        }
                        warningAppReceiverIdList += sysUser.getDdUserId();
                    }
                }
                break;
            default:
                logger.error("未找到该应用类型");
                break;
        }
        return warningAppReceiverIdList;
    }
}
