package com.yd.rmi.ali.mailinterf.service.impl;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dm.model.v20151123.BatchSendMailRequest;
import com.aliyuncs.dm.model.v20151123.BatchSendMailResponse;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.yd.rmi.ali.mailinterf.service.AliMailInterfService;
import com.yd.rmi.cache.SystemConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.Message.RecipientType;
import javax.mail.internet.*;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

@Service("aliMailInterfService")
public class AliMailInterfServiceImpl implements AliMailInterfService {
	@Autowired
	private SystemConfigService systemConfigService;

//	private String REGION_ID = systemConfigService.getSingleConfigValue("ALI_MAIL_REGION_ID");//"cn-hangzhou";
//	private String ACCESS_KEY_ID = systemConfigService.getSingleConfigValue("ALI_MAIL_ACCESS_KEY_ID");//"LTAI74cjt1JCZnYd";
//	private String ACCESS_KEY_SECRET = systemConfigService.getSingleConfigValue("ALI_MAIL_ACCESS_KEY_SECRET");// "4PhQIwcVkqN0JhN3GGPo4EhBncLCLw";

//	private String TAG_NAME = systemConfigService.getSingleConfigValue("ALI_MAIL_TAG_NAME");//"CompareTheMarket";//邮件标签
//	private String CLICK_TRACE = systemConfigService.getSingleConfigValue("ALI_MAIL_CLICK_TRACE");//"1";

//    private String ALIDM_SMTP_HOST = systemConfigService.getSingleConfigValue("ALI_MAIL_ALIDM_SMTP_HOST");//"smtpdm.aliyun.com";//"smtpdm.aliyun.com"	"smtp.163.com"
//    private int ALIDM_SMTP_PORT = Integer.parseInt(systemConfigService.getSingleConfigValue("ALI_MAIL_ALIDM_SMTP_PORT"));//25;

//    private String ACCOUNT_NAME = systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME");//"service@mail.zuihuibijia.com";
//    private String ACCOUNT_NICK_NAME = systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NICK_NAME");//"安吉保（上海）企业管理咨询有限公司";
//    private String ACCOUNT_PASSWORD = systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_PASSWORD");//"12345abcBE";

//    private String TO_NICK_NAME = systemConfigService.getSingleConfigValue("ALI_MAIL_TO_NICK_NAME");//"尊敬的客户";//收件人昵称
//	private String REPLY_ADDRESS = systemConfigService.getSingleConfigValue("ALI_MAIL_REPLY_ADDRESS");//"tiger.zheng@autogeneral.cn";//回复地址
//	private String REPLY_NICK_NAME = systemConfigService.getSingleConfigValue("ALI_MAIL_REPLY_NICK_NAME");//"安吉保客服中心";//

	/**
	 * 单封邮件发送
	 * @param toAddress
	 * @param subject
	 * @param messageHtml
	 * @param messageText
	 */
	@Override
	public void singleSend(String toAddress,String subject,String messageHtml,String messageText) {
        IClientProfile profile = DefaultProfile.getProfile(systemConfigService.getSingleConfigValue("ALI_MAIL_REGION_ID"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCESS_KEY_ID"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCESS_KEY_SECRET"));
        IAcsClient client = new DefaultAcsClient(profile);
        SingleSendMailRequest request = new SingleSendMailRequest();
        try {
        	/** 去除Action外还有9个入参 **/
            request.setAccountName(systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME"));
            request.setReplyToAddress(true);//是否使用管理控制台中配置的回信地址（状态必须是验证通过）
            request.setAddressType(1);//取值范围0~1: 0为随机账号；1为发信地址
            request.setToAddress(toAddress);//目标地址，多个Email地址可以逗号分隔，最多100个地址。
            request.setFromAlias(systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NICK_NAME"));//发信人昵称,长度小于15个字符 例如:发信人昵称设置为”小红”，发信地址为”test@example.com”，收信人看到的发信地址为"小红"<test@example.com>
            request.setSubject(subject);//邮件主题，建议填写
            request.setHtmlBody(messageHtml);//邮件html正文
            request.setTextBody(messageText);//邮件text正文
            request.setClickTrace(systemConfigService.getSingleConfigValue("ALI_MAIL_CLICK_TRACE"));//取值范围0~1: 1为打开数据跟踪功能; 0为关闭数据跟踪功能；该参数默认值为0。

            /** 下面这个不属于入参，也不属于公共参数 **/
            request.setTagName(systemConfigService.getSingleConfigValue("ALI_MAIL_TAG_NAME"));

            SingleSendMailResponse httpResponse = client.getAcsResponse(request);
            System.out.println("httpResponse.getEnvId() = "+httpResponse.getEnvId());
        }catch (ServerException e) {
            e.printStackTrace();
        }catch (ClientException e) {
            e.printStackTrace();
        }
	}

	/**
	 * 批量邮件发送
	 * @param templateName	邮件模板："成功投保模板"
	 * @param receiversName	收件人列表："测试控制台发邮件"
	 */
	@Override
	public void batchSend(String templateName,String receiversName) {
        IClientProfile profile = DefaultProfile.getProfile(systemConfigService.getSingleConfigValue("ALI_MAIL_REGION_ID"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCESS_KEY_ID"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCESS_KEY_SECRET"));
        IAcsClient client = new DefaultAcsClient(profile);
        BatchSendMailRequest request = new BatchSendMailRequest();
        try {
        	/** 除Action外，共有6个入参，如下 **/
            request.setAccountName(systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME"));
            request.setAddressType(1);//取值范围0~1: 0为随机账号；1为发信地址
            request.setTemplateName(templateName);//预先创建且通过审核的模板名称
            request.setReceiversName(receiversName);//预先创建且上传了收件人的收件人列表名称
            request.setTagName(systemConfigService.getSingleConfigValue("ALI_MAIL_TAG_NAME"));//邮件标签名称
            request.setClickTrace(systemConfigService.getSingleConfigValue("ALI_MAIL_CLICK_TRACE"));//取值范围0~1: 1为打开数据跟踪功能; 0为关闭数据跟踪功能；该参数默认值为0。

            BatchSendMailResponse httpResponse = client.getAcsResponse(request);
            System.out.println("httpResponse.getEnvId() = "+httpResponse.getEnvId());
            httpResponse.getRequestId();
        }catch (ServerException e) {
            e.printStackTrace();
        }catch(ClientException e) {
            e.printStackTrace();
        }
	}

	/**
	 * SMTP邮件发送
     * @param toAddress	收件人地址
     * @param ccAddresses 抄送人地址数组
     * @param subject	邮件标题
     * @param messageText	邮件正文文本
     * @param attachmentFiles	附件路径
     * @param imageFile	图片路径
     */
	@Override
    public void smtpSend(String toAddress,
    						String[] ccAddresses,
							String subject,
							String messageText,
						    List<String> attachmentFiles,
							String imageFile) throws Exception {
    	String messageStyle = "1";//邮件类型 1、纯文本邮件；2、带附件邮件；3、正文带图片，带附件邮件
    	if((attachmentFiles != null) && (imageFile == null || "".equals(imageFile))){
    		messageStyle = "2";
    	}
    	if((attachmentFiles != null) && (imageFile != null && !"".equals(imageFile))){
    		messageStyle = "3";
    	}
        /********** 第一步：配置javax.mail.Session对象 **********/
        System.out.println("为" + systemConfigService.getSingleConfigValue("ALI_MAIL_ALIDM_SMTP_HOST") + "配置mail session对象");
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true"); //使用验证
        props.put("mail.smtp.host", systemConfigService.getSingleConfigValue("ALI_MAIL_ALIDM_SMTP_HOST"));
        props.put("mail.smtp.port", Integer.parseInt(systemConfigService.getSingleConfigValue("ALI_MAIL_ALIDM_SMTP_PORT"))); //google使用465或587端口

        props.put("mail.transport.protocol","smtp");
        props.put("mail.smtp.starttls.enable", "true");//使用 STARTTLS安全连接
        props.put("mail.debug", "true");
        Session mailSession = Session.getInstance(props, new AJBAuthenticator(systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_PASSWORD")));//Default

        /********** 第二步：编写消息 **********/
		System.out.println("编写消息from—>to: " + systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME") + " —> " + toAddress);
		MimeMessage message = new MimeMessage(mailSession);
		message.setFrom(new InternetAddress(systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME"),systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NICK_NAME"), "UTF-8"));//发件人
		message.addRecipient(RecipientType.TO, new InternetAddress(toAddress, systemConfigService.getSingleConfigValue("ALI_MAIL_TO_NICK_NAME"), "UTF-8"));//收件人
		if(ccAddresses != null && ccAddresses.length >0){
			for(int i=0;i<ccAddresses.length;i++){
				message.addRecipient(RecipientType.CC, new InternetAddress(ccAddresses[i], systemConfigService.getSingleConfigValue("ALI_MAIL_TO_NICK_NAME"), "UTF-8"));//收件人
			}
		}
		message.setSentDate(Calendar.getInstance().getTime());//发送时间
		message.setSubject(subject,"UTF-8");//标题
		message.setReplyTo(InternetAddress.parse("\"" + MimeUtility.encodeText(systemConfigService.getSingleConfigValue("ALI_MAIL_REPLY_NICK_NAME")) + "\" <"+systemConfigService.getSingleConfigValue("ALI_MAIL_REPLY_ADDRESS")+">"));//设置回复人(收件人回复此邮件时,默认收件人)

		/** 2.1纯文本邮件 **/
		if("1".equals(messageStyle)){
			message.setContent(messageText, "text/html;charset=UTF-8");
		}

		/** 2.2带附件的邮件 **/
		if("2".equals(messageStyle)){
			Multipart content = new MimeMultipart();
			BodyPart textBody = new MimeBodyPart();
			textBody.setText(messageText);
			content.addBodyPart(textBody);
			for (String attachmentFile : attachmentFiles){
				BodyPart attachmentBody = new MimeBodyPart();
				DataHandler dh = new DataHandler(new FileDataSource(attachmentFile));//读取本地文件
				attachmentBody.setDataHandler(dh);//将附件数据添加到“节点”
				attachmentBody.setFileName(MimeUtility.encodeText(dh.getName()));//设置附件的文件名（需要编码）
				content.addBodyPart(attachmentBody);
			}

			message.setContent(content);
		}

		/**2.3正文带图片，带附件的邮件 **/
		if("3".equals(messageStyle)){
			MimeBodyPart imageBody = new MimeBodyPart();//1.创建图片“节点”
			DataHandler dh = new DataHandler(new FileDataSource(imageFile));//读取本地文件
			imageBody.setDataHandler(dh);//将图片数据添加到“节点”
			imageBody.setContentID("image_fairy_tail");//为“节点”设置一个唯一编号（在文本“节点”将引用该ID）

			BodyPart textBody = new MimeBodyPart();//2.创建文本“节点”
			textBody.setContent(messageText+"<br/><img src='cid:image_fairy_tail'/>", "text/html;charset=UTF-8");// 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片

			MimeMultipart subContent = new MimeMultipart();//3.（文本+图片）设置 文本 和 图片 “节点”的关系（将 文本 和 图片 “节点”合成一个混合“节点”）
			subContent.addBodyPart(textBody);
			subContent.addBodyPart(imageBody);
			subContent.setSubType("related");// 关联关系

			BodyPart textImageBody = new MimeBodyPart();//4.将 文本+图片 的混合“节点”封装成一个普通“节点”，最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart，上面的 mm_text_image 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
			textImageBody.setContent(subContent);

			MimeMultipart content = new MimeMultipart();//6.设置（文本+图片）和 附件 的关系（合成一个大的混合“节点” / Multipart ）
			for (String attachmentFile : attachmentFiles){
				BodyPart attachmentBody = new MimeBodyPart();
				DataHandler dh2 = new DataHandler(new FileDataSource(attachmentFile));//读取本地文件
				attachmentBody.setDataHandler(dh2);//将附件数据添加到“节点”
				attachmentBody.setFileName(MimeUtility.encodeText(dh2.getName()));//设置附件的文件名（需要编码）
				content.addBodyPart(attachmentBody);
			}

			content.addBodyPart(textImageBody);
			content.setSubType("mixed");//混合关系

			message.setContent(content);//7.设置整个邮件的关系（将最终的混合“节点”作为邮件的内容添加到邮件对象）
		}

		/********** 第三步：发送消息 **********/
		message.saveChanges();//保存邮件
		Transport transport = mailSession.getTransport("smtp");
		transport.connect(systemConfigService.getSingleConfigValue("ALI_MAIL_ALIDM_SMTP_HOST"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_NAME"), systemConfigService.getSingleConfigValue("ALI_MAIL_ACCOUNT_PASSWORD"));
		Transport.send(message, message.getAllRecipients());
		transport.close();
		System.out.println("message yes");
    }

    public static void main(String[] args){
    	AliMailInterfServiceImpl service = new AliMailInterfServiceImpl();
    	String toAddress = "water.wang@autogeneral.cn";
    	String[] ccAddresses = new String[]{"water.wang@autogeneral.cn","1034346366@qq.com"};
    	String subject = "您已成功通过安吉保购买保险产品";
    	String messageText = ""
    	+"尊敬的XX，您好!"
    	+"<br>恭喜您，您已成功通过安吉保购买了史带财产保险股份有限公司的 爱自由-境内旅行保障计划 - 计划A ，保单号 AABA000000W2017E00000029 ，保险期限：2017-06-22 00:00:00 至 2017-07-02 23:59:59 。"
    	+"<br>您可以访问http://policy.starrchina.cn/进行保单验真、查询详细保单条款。"
    	+"<br>您也可以关注 \"最会比价\"官方微信获取其他优质增值服务！"
    	+"<br>全国客服热线电话：40099 95507。"
    	+"<br>祝您万事如意！";
    	List<String> attachmentFiles = null;
    	String imageFile = null;
		try {
			service.smtpSend(toAddress, ccAddresses,subject, messageText, attachmentFiles, imageFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class AJBAuthenticator extends Authenticator {
    String userName = "";
    String password = "";
    public AJBAuthenticator() {}
    public AJBAuthenticator(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, password);
    }
}