package com.yeejoin.amos.boot.module.cylinder.biz.action;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.cylinder.api.dto.WarningMsgDto;
import com.yeejoin.amos.boot.module.cylinder.api.dto.WechatMessageDto;
import com.yeejoin.amos.boot.module.cylinder.api.entity.MsgLog;
import com.yeejoin.amos.boot.module.cylinder.api.entity.WechatRelation;
import com.yeejoin.amos.boot.module.cylinder.api.enums.EarlyWarningLevelEnum;
import com.yeejoin.amos.boot.module.cylinder.api.enums.WarningEnum;
import com.yeejoin.amos.boot.module.cylinder.biz.service.impl.MsgLogServiceImpl;
import com.yeejoin.amos.boot.module.cylinder.biz.service.impl.WechatRelationServiceImpl;
import com.yeejoin.amos.boot.module.cylinder.biz.service.impl.WechatServiceImpl;
import com.yeejoin.amos.boot.module.cylinder.flc.biz.service.impl.CylinderInfoServiceImpl;
import com.yeejoin.amos.component.rule.RuleActionBean;
import com.yeejoin.amos.component.rule.RuleMethod;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
@RuleActionBean(beanLabel = "预警消息")
public class WarningMsgAction{
    private final Logger logger = LoggerFactory.getLogger(WarningMsgAction.class);
    @Value("${tzs.wechat.tempId.warning}")
    private String templateId_Warning;
    @Autowired
    WechatRelationServiceImpl wechatRelationService;
    @Autowired
    WechatServiceImpl wechatServiceImpl;
    @Autowired
    CylinderInfoServiceImpl cylinderInfoServiceImpl;
    @Autowired
    MsgLogServiceImpl msgLogServiceImpl;
    @Autowired
    private EmqKeeper emqKeeper;

    @Value("${mqtt.topic.cyl.warning.push}")
    private String cylpushTopic;

//	@ExposeAction("气瓶预警消息")
    @RuleMethod(methodLabel = "预警消息方法", project = "预警消息")
	public void sendWebMessageTip(Object bizobj, String level,String orgUserName,String phone ,String text)
	{
		WarningMsgDto warningMsgDto = (WarningMsgDto)bizobj;
        List<MsgLog> msgLogList = msgLogServiceImpl.list(new LambdaQueryWrapper<MsgLog>().eq(MsgLog::getRelationCode,warningMsgDto.getCode()).eq(MsgLog :: getMsgTypeName,WarningEnum.getEumByLevel(level).getName()).eq(MsgLog::getIsDelete,false));
        if(!ValidationUtil.isEmpty(msgLogList)){
            logger.info("气瓶唯一标识码为  "+warningMsgDto.getCode()+"  的气瓶已有数据！");
            return;
        }
		//更新气瓶等级
//		logger.info("更新气瓶等级："+level);
//		logger.info("预警区间："+warningMsgDto.getNum());
//		cylinderInfoServiceImpl.updateEarlyWarningLevel(warningMsgDto.getCylSeq(), level);
		//增加消息日志数据
		MsgLog msgLog = msgLogServiceImpl.getOne(new LambdaQueryWrapper<MsgLog>().eq(MsgLog::getRelationCode,warningMsgDto.getCode()).eq(MsgLog::getIsDelete,false));
        if(ValidationUtil.isEmpty(msgLog)){
            msgLog = new MsgLog();
        }
        //气瓶所属公司
        String companyName = warningMsgDto.getCompanyName();
        msgLog.setCompanyName(companyName);
        //公司区域
        if(!ValidationUtil.isEmpty(companyName)) {
            CompanyModel companyModel = Privilege.companyClient.queryByCompanyName(companyName).getResult();
            String regionCode = getCompanyRegionCode("", companyModel);
            msgLog.setRegionCode(regionCode);
        }

		msgLog.setRelationCode(warningMsgDto.getCode());
		msgLog.setMsgType(WarningEnum.getEumByLevel(level).getCode());
		msgLog.setMsgTypeName(WarningEnum.getEumByLevel(level).getName());
		msgLog.setBody(instedParams(text, warningMsgDto));

		msgLog.setTargetCode(instedParams(phone, warningMsgDto));
		msgLog.setTargetName(instedParams(orgUserName, warningMsgDto));

		msgLog.setTerminalType("WEB");
		msgLog.setSendTime(new Date());
        msgLog.setRecDate(new Date());
		msgLogServiceImpl.saveOrUpdate(msgLog);
		logger.info("增加消息日志数据："+msgLog.toString());
		//发送web消息
        try {
            emqKeeper.getMqttClient().publish(cylpushTopic, instedParams(text, warningMsgDto).getBytes("UTF-8"), 2, false);
            logger.info(warningMsgDto.getWarningType()+"消息发送成功：");
        } catch (MqttException e) {
        	e.printStackTrace();
            logger.error("mqtt发送失败" +text );
        } catch (UnsupportedEncodingException e) {
        	e.printStackTrace();
            logger.error("mqtt发送失败" +text );
        }
	}

    public String getCompanyRegionCode(String regionCode,CompanyModel companyModel){
        Long companyId = companyModel.getParentId();
        if(companyId!=0L){
            CompanyModel parentCompany = Privilege.companyClient.seleteOne(companyId).getResult();
            if(!ValidationUtil.isEmpty(parentCompany)) {
                String regionSeq = parentCompany.getRegionSeq();
                if (!ValidationUtil.isEmpty(regionSeq)) {
                    RegionModel regionModel = Systemctl.regionClient.getRegion(Long.valueOf(regionSeq)).getResult();
                    if (!ValidationUtil.isEmpty(regionCode)) {
                        regionCode = "#" + regionCode;
                    }
                    regionCode = regionModel.getRegionCode() + regionCode;
                }
                regionCode = getCompanyRegionCode(regionCode,parentCompany);
            }
        }
        return regionCode;
    }

    @RuleMethod(methodLabel = "气瓶公众号", project = "气瓶监管")
	public void sendCylWechatMessageTip(Object bizobj, String level,String orgUserName,String phone ,String text)
	{
		//增加消息日志数据
		WarningMsgDto warningMsgDto = (WarningMsgDto)bizobj;
		MsgLog msgLog = new MsgLog();
		msgLog.setRelationCode(warningMsgDto.getCode());
		msgLog.setMsgType(EarlyWarningLevelEnum.getEumByLevel(level).getCode());
		msgLog.setMsgTypeName(EarlyWarningLevelEnum.getEumByLevel(level).getName());
		msgLog.setBody(instedParams(text, warningMsgDto));
		msgLog.setTargetCode(instedParams(phone, warningMsgDto));
		msgLog.setTargetName(instedParams(orgUserName, warningMsgDto));
		msgLog.setTerminalType("APP");
		msgLog.setSendTime(new Date());
		msgLogServiceImpl.save(msgLog);
		//发送公众号消息
    	logger.info("气瓶预警消息发送开始："+phone);
		WechatRelation wechatRelation =wechatRelationService.getOne(new LambdaQueryWrapper<WechatRelation>().eq(WechatRelation::getPhone,phone));
		logger.info("气瓶预警消息发送OpenId："+wechatRelation.toString());
		if(null != wechatRelation) {
        	WechatMessageDto wechatMessageDto1 = new WechatMessageDto();
        	wechatMessageDto1.setTemplateId(templateId_Warning);
        	Map<String, String> data1 = Maps.newHashMap();
        	data1.put("first", "【陕西特种设备安全监察局】风险预警提醒");
        	data1.put("keyword1", instedParams(text, warningMsgDto));
        	data1.put("keyword2", DateUtils.date2LongStr(new Date()));
        	wechatMessageDto1.setData(data1);
        	wechatServiceImpl.sendWechatModelMessage(wechatRelation.getOpenId(), wechatMessageDto1);
        	logger.info("公众号消息发送成功：");
        }
	}
    private String instedParams(String content, WarningMsgDto contingencyRo) {

//        Map<String, String> strengthMap = this.getStrengthMap(contingencyRo);
//        for (String key : strengthMap.keySet())
//            content = content.replaceAll("\\$\\{" + key + "}", strengthMap.get(key));
    	if(null == content || !content.contains("$")) {
    		return content;
    	}
          Field[] fields = contingencyRo.getClass().getDeclaredFields();
          Method getMethod = null;
          try {
              for (Field field : fields) {
                  if (field.getName().equals("serialVersionUID"))
                      continue;
                  String fileNameInMethod = String.valueOf(field.getName().charAt(0)).toUpperCase() + field.getName().substring(1);
                  getMethod = contingencyRo.getClass().getMethod("get" + fileNameInMethod);
                  String value = String.valueOf(getMethod.invoke(contingencyRo));
                  content = content.replaceAll("\\$\\{" + field.getName() + "}", value.equals("null")?"":value);
              }

              content = getNative(content);
          } catch (Exception e) {
              e.printStackTrace();
          }
        return content;
    }
    public String getNative(String str)
    {
      Pattern p = Pattern.compile("\\$\\{(.*?)\\}");
      Matcher m = p.matcher(str);
      while (m.find())
      {
        String parameter = m.group();

        Object parametervalue = ELEvaluationContext
            .getValue(parameter.substring(1, parameter.length() - 1));
        if(parametervalue != null)
          str = str.replace(parameter,
            parametervalue != null ? parametervalue.toString() : null);
      }
      return str;
    }
}
