package com.huigou.tech.message.impl;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.huigou.cache.SystemCache;
import com.huigou.context.ThreadLocalUtil;
import com.huigou.tech.common.domain.TechNoticeKind;
import com.huigou.tech.common.domain.model.Notice;
import com.huigou.tech.message.TechEmailSender;
import com.huigou.tech.message.TechEmailSenderThread;
import com.huigou.uasp.bmp.opm.OpmUtil;
import com.huigou.uasp.bmp.opm.domain.model.org.Person;
import com.huigou.uasp.bmp.opm.proxy.OrgApplicationProxy;
import com.huigou.uasp.bpm.MessageModelSender;
import com.huigou.uasp.bpm.MessageSendModel;
import com.huigou.uasp.bpm.engine.application.ActApplication;
import com.huigou.uasp.bpm.engine.domain.model.TaskExtension;
import com.huigou.uasp.tool.mail.EmailSender;
import com.huigou.util.ClassHelper;
import com.huigou.util.LogHome;
import com.huigou.util.StringUtil;

/**
 * 上科大邮件发送
 * 
 * @author xiexin
 */
public class TechEmailSenderImpl implements MessageModelSender, TechEmailSender {

    private static final String THIS_NAME = "tech.message.sender";

    private static final Logger logger = Logger.getLogger(THIS_NAME);

    @Autowired
    private OrgApplicationProxy application;

    @Autowired
    private ActApplication actApplication;

    // 邮件发送类 xml 配置注入
    private EmailSender emailSender;

    // 是否启用邮件发送
    private String enable;

    public boolean isEnable() {
        return ClassHelper.convert(enable, Boolean.class, false);
    }

    public void setEnable(String enable) {
        this.enable = enable;
    }

    public void setEmailSender(EmailSender emailSender) {
        this.emailSender = emailSender;
    }

    private String getFormUrl(TaskExtension taskExtension) {
        String webBasePath = SystemCache.getParameter("webBasePath", String.class);
        String url = String.format("bizId=%s&taskId=%s", taskExtension.getBusinessKey(), taskExtension.getId());
        String executorUrl = taskExtension.getExecutorUrl();
        if (executorUrl.indexOf("?") > -1) {
            url = String.format("%s&%s", executorUrl, url);
        } else {
            url = String.format("%s?%s", executorUrl, url);
        }
        return String.format("%s/%s", webBasePath, url);
    }

    private String getFormUrl(String url) {
        String webBasePath = SystemCache.getParameter("webBasePath", String.class);
        return String.format("%s/%s", webBasePath, url);
    }

    private String getFormUrl(Map<String, Object> map) {
        String webBasePath = SystemCache.getParameter("webBasePath", String.class);
        String url = String.format("bizId=%s&taskId=%s", map.get("bizId"), map.get("id"));
        String executorUrl = ClassHelper.convert(map.get("executorUrl"), String.class);
        if (executorUrl.indexOf("?") > -1) {
            url = String.format("%s&%s", executorUrl, url);
        } else {
            url = String.format("%s?%s", executorUrl, url);
        }
        return String.format("%s/%s", webBasePath, url);
    }

    @SuppressWarnings("unchecked")
    private void putMessageSendModelInThreadLocal(MessageSendModel messageSendmodel) {
        List<MessageSendModel> models = (List<MessageSendModel>) ThreadLocalUtil.getVariable(THIS_NAME);
        if (models == null) {
            models = new ArrayList<MessageSendModel>();
            ThreadLocalUtil.putVariable(THIS_NAME, models);
        }
        models.add(messageSendmodel);
    }

    @Override
    public void send(MessageSendModel messageSendmodel) {
        // 没启用直接返回
        if (!isEnable()) {
            return;
        }
        // 不需要发送消息直接返回
        if (!messageSendmodel.getIsSend()) {
            return;
        }
        String adminId = SystemCache.getParameter("adminPersonId", String.class);
        String creatorPersonMemberName = messageSendmodel.getTaskExtension().getApplicantPersonMemberName();
        if (adminId != null) {
            String adminPersonId = OpmUtil.getPersonIdFromPersonMemberId(adminId);
            if (adminPersonId.equals(messageSendmodel.getSenderId())) {
                creatorPersonMemberName = "系统";
            }
        }
        messageSendmodel.setRemark(String.format("%s创建的任务:", creatorPersonMemberName));
        // 将需要发送的消息保存到线程局部变量
        this.putMessageSendModelInThreadLocal(messageSendmodel);

        
          //考虑 egate 同步任务中心可能失败 为保证任务创建成功后才发送邮件，这里通过将待发送消息保存到线程局部变量中调整邮件发送再同步egate后执行,
          // 获取接收人email
          Map<String, Object> param = ClassHelper.toMap(messageSendmodel.getTaskExtension());
          String subject = messageSendmodel.getTaskExtension().getDescription();
          Person person = application.loadPerson(messageSendmodel.getReceiverId());
          if (person == null) {
          logger.error(String.format("%s未找到人员!", messageSendmodel.getReceiverId()));
          return;
          }
          String email = person.getEmail();
          if (StringUtil.isBlank(email)) {
          logger.error(String.format("%s的邮件地址为空!", person.getName()));
          return;
          }
          // 组合邮件显示连接
          param.put("emailTitle", messageSendmodel.getRemark());
          param.put("executorUrl", this.getFormUrl(messageSendmodel.getTaskExtension()));
          this.doSend(email, subject, param);
         
    }

    @Override
    public void sendAsTitle(MessageSendModel messageSendmodel, String emailTitle) {
        // 没启用直接返回
        if (!isEnable()) {
            return;
        }
        // 不需要发送消息直接返回
        if (!messageSendmodel.getIsSend()) {
            return;
        }
        messageSendmodel.setRemark(emailTitle);
        // 将需要发送的消息保存到线程局部变量
        this.putMessageSendModelInThreadLocal(messageSendmodel);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void sendThreadLocalMessages() {
        // 没启用直接返回
        if (!isEnable()) {
            return;
        }
        List<MessageSendModel> models = (List<MessageSendModel>) ThreadLocalUtil.getVariable(THIS_NAME);
        if (models != null && models.size() > 0) {
            for (MessageSendModel messageSendmodel : models) {
                // 获取接收人email
                Map<String, Object> param = ClassHelper.toMap(messageSendmodel.getTaskExtension());
                String subject = messageSendmodel.getTaskExtension().getDescription();
                Person person = application.loadPerson(messageSendmodel.getReceiverId());
                if (person == null) {
                    logger.error(String.format("%s未找到人员!", messageSendmodel.getReceiverId()));
                    continue;
                }
                String email = person.getEmail();
                if (StringUtil.isBlank(email)) {
                    logger.error(String.format("%s的邮件地址为空!", person.getName()));
                    continue;
                }
                param.put("emailTitle", messageSendmodel.getRemark());
                // 组合邮件显示连接
                param.put("executorUrl", this.getFormUrl(messageSendmodel.getTaskExtension()));
                this.doSend(email, subject, param);
            }
        }
    }

    @Override
    public void sendByNotice(Notice notice, String receiverId) {
        // 没启用直接返回
        if (!isEnable()) {
            return;
        }
        // 获取接收人email
        Map<String, Object> param = new HashMap<>();
        String subject = notice.getSubject();
        String personId = OpmUtil.getPersonIdFromPersonMemberId(receiverId);
        Person person = application.loadPerson(personId);
        if (person == null) {
            logger.error(String.format("%s未找到人员!", receiverId));
            return;
        }
        String email = person.getEmail();
        if (StringUtil.isBlank(email)) {
            logger.error(String.format("%s的邮件地址为空!", person.getName()));
            return;
        }
        param.put("emailTitle", "系统创建任务:");
        param.put("description", notice.getContent());
        TechNoticeKind noticeKind = TechNoticeKind.fromId(notice.getNoticeKind());
        if (noticeKind == TechNoticeKind.CHART) {
            param.put("executorUrl", this.getFormUrl(notice.getUrl()));
        } else {
            // 查询是否存在当前任务
            if (StringUtil.isNotBlank(notice.getBizId())) {
                Map<String, Object> map = actApplication.loadHistoricTaskById(notice.getCurrentTaskId());
                if (map != null && map.size() > 0) {
                    // 组合邮件处理连接
                    param.put("executorUrl", this.getFormUrl(map));
                }
            }
        }
        this.doSend(email, subject, param);
    }

    private void doSend(String email, String subject, Map<String, Object> param) {
        UncaughtExceptionHandler exceptionHandler = new UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable e) {
                LogHome.getLog().error(e.getMessage(), e);
            }
        };
        Thread t = new Thread(new TechEmailSenderThread(emailSender, email, subject, param));
        t.setUncaughtExceptionHandler(exceptionHandler);
        t.setName("TechEmailSenderThread");
        t.start();
    }
}
