package com.hotent.portal.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.hotent.base.context.BaseContext;
import com.hotent.base.exception.NotFoundException;
import com.hotent.base.exception.RequiredException;
import com.hotent.base.feign.UCFeignService;
import com.hotent.base.jms.*;
import com.hotent.base.template.impl.FreeMarkerEngine;
import com.hotent.base.util.*;
import com.hotent.base.util.time.DateUtil;
import com.hotent.portal.model.MsgTemplate;
import com.hotent.portal.persistence.manager.MsgTemplateManager;
import com.hotent.sys.persistence.manager.SysAppLogsManager;
import com.hotent.sys.persistence.manager.SysLogsManager;
import com.hotent.sys.persistence.model.SysAppLogs;
import com.hotent.sys.persistence.model.SysLogs;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * @author zhaoxy
 * @company 广州宏天软件股份有限公司
 * @email zhxy@jee-soft.cn
 * @date 2018-06-06 14:20
 * </pre>
 */
@Primary
@Service
public class JmsNoticeConsumerServiceImpl implements JmsNoticeConsumerService {
    private Log logger = LogFactory.getLog(TemplateServiceImpl.class);
    @Resource
    FreeMarkerEngine freeMarkerEngine;
    @Resource
    MsgTemplateManager msgTemplateManager;
    @Resource
    JmsProducer jmsProducer;
    @Resource
    UCFeignService ucFeignService;

    @Override
    public void sendNotice2Jms(Notice notice) {
        jmsProducer.sendToQueue(notice);
    }

    @Override
    public void sendNotice(Notice notice) {
        if (BeanUtils.isEmpty(notice)) {
            throw new RequiredException("The args 'Notice' is required.");
        }
        NoticeMessageType[] messageTypes = notice.getMessageTypes();
        if (messageTypes.length == 0) {
            throw new RequiredException("The 'messageTypes' in 'Notice' is required.");
        }
        List<JmsActor> receiver = notice.getReceiver();
        if (BeanUtils.isEmpty(receiver) && BeanUtils.isNotEmpty(notice.getReceivers())) {
            ArrayNode users = ucFeignService.getUserByAccounts(StringUtils.join(notice.getReceivers(), ","));
            if (BeanUtils.isNotEmpty(users)) {
                receiver = new ArrayList<JmsActor>();
                for (JsonNode j : users) {
                    JmsActor actor = convertUserObject2JmsActor(j);
                    if (BeanUtils.isNotEmpty(actor)) {
                        receiver.add(actor);
                    }
                }
            }
        }
        if (receiver.size() == 0) {
            throw new RequiredException("The 'receivers' in 'Notice' is required.");
        }
        JmsProducer jmsProducer = AppUtil.getBean(JmsProducer.class);
        String templateKey = notice.getTemplateKey();
        String templateType = notice.getTemplateType();
        if (notice.isUseTemplate() && StringUtil.isEmpty(templateKey) && StringUtil.isEmpty(templateType)) {
            throw new RequiredException("Nor the 'templateKey' and the 'templateType' is empty, so we can not find out the template to send with.");
        }

        JsonNode sender = null;
        String senderAccount = notice.getSender();
        if (StringUtil.isNotEmpty(senderAccount)) {
            sender = ucFeignService.loadUserByUsername(senderAccount);
        }
//		List<JsonNode> receiveUsers = new ArrayList<>();
//		JmsActor[] receiverAccounts = ArrayUtil.unique(receivers);
//		for(String account : receiverAccounts) {
//			JsonNode receiver = ucFeignService.loadUserByUsername(account);
//			if(BeanUtils.isEmpty(receiver)){
//				CommonResult<JsonNode> userById = ucFeignService.getUserById(account);
//				if(userById.getState()) {
//					receiver = userById.getValue();
//				}
//			}
//			if(BeanUtils.isNotEmpty(receiver)) {
//				receiveUsers.add(receiver);
//			}
//		}
//		if(receiveUsers.size()==0) {
//			throw new RequiredException("The accounts of 'receivers' in 'Notice' can not find the match user, so we did not send the message.");
//		}
        String subject = notice.getSubject();
        String content = notice.getContent();
        String plainContent = "";
        String templateAlias = "";
        String smsTemplateNo = "";//阿里大鱼短信模板code
        String voiceTemplateNo = "";//阿里大鱼语音模板code
        Map<String, Object> vars = notice.getVars();
        if (notice.isUseTemplate()) {
            MsgTemplate templateVo = null;
            if (StringUtil.isNotEmpty(templateKey)) {
                templateVo = this.getTemplate(templateKey);
                if (BeanUtils.isEmpty(templateVo)) {
                    throw new NotFoundException(String.format("The is no template key was '%s'.", templateKey));
                }
            } else {
                templateVo = this.getDefaultTemplate(templateType);
                if (BeanUtils.isEmpty(templateVo)) {
                    throw new NotFoundException(String.format("The is no default template for type: '%s'.", templateType));
                }
            }
            subject = this.parseSubject(templateVo, vars);
            content = this.parseHtmlContent(templateVo, vars);
            plainContent = this.parsePlainContent(templateVo, vars);
            templateAlias = templateVo.getKey();
            if (StringUtil.isNotEmpty(templateVo.getSmsTemplateNo())) {
                smsTemplateNo = templateVo.getSmsTemplateNo();
            }
            if (StringUtil.isNotEmpty(templateVo.getVoiceTemplateNo())) {
                voiceTemplateNo = templateVo.getVoiceTemplateNo();
            }
        }

//		List<JmsActor> receives = new ArrayList<>();
//		for(JsonNode user : receiveUsers) {
//			receives.add(convertUserObject2JmsActor(user));
//		}

        for (NoticeMessageType type : messageTypes) {
            JmsMessage jmsMessage = null;
            if (type.isPlain() && notice.isUseTemplate()) {
                jmsMessage = new JmsMessage(templateAlias, subject, plainContent, convertUserObject2JmsActor(sender), receiver, type.key());
            } else {
                jmsMessage = new JmsMessage(templateAlias, subject, content, convertUserObject2JmsActor(sender), receiver, type.key());
            }
            if (StringUtil.isNotEmpty(smsTemplateNo)) {
                jmsMessage.setSmsTemplateNo(smsTemplateNo);
            }
            if (StringUtil.isNotEmpty(voiceTemplateNo)) {
                jmsMessage.setVoiceTemplateNo(voiceTemplateNo);
            }
            if (notice.isBatchSend()) {
                jmsMessage.setExtendVars(vars);
                jmsProducer.sendToQueue(jmsMessage);
            } else {
                notice.getVars();
                //不是批量发送，则每个接收者重新解析一次模板，发送一次
                String needParseContent = jmsMessage.getContent();
                String needParseSubject = jmsMessage.getSubject();
                for (JmsActor receive : receiver) {
                    vars.put("receiver", receive.getName());
                    vars.put("receiverId", receive.getId());
                    try {
                        jmsMessage.setContent(freeMarkerEngine.parseByTemplate(needParseContent, vars));
                        jmsMessage.setSubject(freeMarkerEngine.parseByTemplate(needParseSubject, vars));
                    } catch (Exception e) {
                        logger.error(String.format("parse template fail:'%s'.", e.getMessage()));
                    }
                    jmsMessage.setReceivers(new ArrayList<>(Arrays.asList(receive)));
                    jmsMessage.setExtendVars(vars);
                    jmsProducer.sendToQueue(jmsMessage);
                }
            }
        }
    }

    @Override
    public void addSysLogs(String id, String opeName, String executor, String ip, String logType, String moduleType, String reqUrl, String opeContent) {
        SysLogsManager sysLogsManager = AppUtil.getBean(SysLogsManager.class);
        if (StringUtil.isEmpty(executor) || executor.startsWith("null")) {
            executor = "系统[无用户登录系统]";
        }
        // 对于操作内容的记录设置最多记录3999
        if (StringUtil.isNotEmpty(opeContent) && opeContent.length() > 3999) {
            opeContent = opeContent.substring(0, 3999);
        }
        SysLogs sysLogs = new SysLogs(opeName, DateUtil.getCurrentDate(), executor, ip, logType, moduleType, reqUrl, opeContent);
        sysLogs.setId(id);
        sysLogsManager.create(sysLogs);
    }



    public MsgTemplate getTemplate(String templateKey) {
        MsgTemplate msgTemplate = msgTemplateManager.getByKey(templateKey);
        return msgTemplate;
    }

    public MsgTemplate getDefaultTemplate(String typeKey) {
        MsgTemplate msgTemplate = msgTemplateManager.getDefault(typeKey.toLowerCase());
        if (msgTemplate == null)
            throw new RuntimeException("There is not a default msgTemplate in table.");
        return msgTemplate;
    }

    public String parseSubject(MsgTemplate templateVo, Map<String, Object> vars) {
        String subject = "";
        try {
            subject = freeMarkerEngine.parseByTemplate(templateVo.getSubject(), vars);
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug(e.getMessage());
        }
        return subject;
    }

    public String parsePlainContent(MsgTemplate templateVo, Map<String, Object> vars) {
        String content = "";
        try {
            content = freeMarkerEngine.parseByTemplate(templateVo.getPlain(), vars);
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug(e.getMessage());
        }
        return content;
    }

    /**
     * 转换IUser对象为JmsActor
     *
     * @param jsonNode
     * @return
     */
    public JmsActor convertUserObject2JmsActor(JsonNode jsonNode) {
        if (BeanUtils.isEmpty(jsonNode) || !jsonNode.isObject()) return null;
        ObjectNode userNode = (ObjectNode) jsonNode;
        String userId = JsonUtil.getString(userNode, "userId");
        if (StringUtil.isEmpty(userId)) {
            userId = JsonUtil.getString(userNode, "id");
        }
        String account = JsonUtil.getString(userNode, "account");
        String fullname = JsonUtil.getString(userNode, "fullname");
        String email = JsonUtil.getString(userNode, "email");
        String mobile = JsonUtil.getString(userNode, "mobile");
        String weixin = JsonUtil.getString(userNode, "weixin");
        String clientId = JsonUtil.getString(userNode, "clientId");
        String clientToken = JsonUtil.getString(userNode, "clientToken");
        return new JmsActor(userId, account, fullname, email, mobile, weixin, clientId, clientToken);
    }

    public String parseHtmlContent(MsgTemplate templateVo, Map<String, Object> vars) {
        String content = "";
        try {
            content = freeMarkerEngine.parseByTemplate(templateVo.getHtml(), vars);
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug(e.getMessage());
        }
        return content;
    }

}
