package com.persagy.dmp.sender.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.dmp.common.utils.Base64Utils;
import com.persagy.dmp.common.utils.ExcelUtils;
import com.persagy.dmp.message.model.dto.AttachmentDTO;
import com.persagy.dmp.message.model.vo.MessageVO;
import com.persagy.dmp.message.model.vo.SenderRegister;
import com.persagy.dmp.sender.service.IMessageSender;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 邮件消息
 * @author Charlie Yu
 * @date 2021-05-24
 */
@Service
public class MailMessageSender implements IMessageSender {

    @Autowired
    private JavaMailSenderImpl mailSender;

    @Value("${spring.mail.username}")
    private String userFrom;

    @Override
    public boolean initParam(SenderRegister register) {
        Properties javaMailProperties = new Properties();
        javaMailProperties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        javaMailProperties.setProperty("mail.smtp.socketFactory.port", "465");
        javaMailProperties.setProperty("mail.smtp.port", "465");
        mailSender.setJavaMailProperties(javaMailProperties);
        return false;
    }

    @Override
    public void send(MessageVO vo) throws Exception{
        //邮件发送参数校验
        checkParam(vo);
        //邮件发送
        this.push(vo);
    }

    /**
     * 邮件发送
     * @param vo
     */
    private void push(MessageVO vo){
        MimeMessage mimeMessage = this.mailSender.createMimeMessage();
        List<String> tempFiles = new ArrayList<>();
        MimeMessageHelper helper = null;
        try {
            helper = new MimeMessageHelper(mimeMessage, true);
            //设置发送人
            helper.setFrom(userFrom);
            //设置接收人
            helper.setTo(vo.getUserId());
            //设置抄送人
            if (StringUtils.isNotEmpty(vo.getCopyToUserId())) {
                helper.setCc(vo.getCopyToUserId().split(","));
            }
            //设置主题
            helper.setSubject(vo.getTitle());
            //设置邮件内容
            helper.setText(vo.getContent());

            //设置邮件附件信息
            List<AttachmentDTO> attachments = vo.getAttachments();
            String html = "";
            for (AttachmentDTO attachment : attachments) {
                //根据附件base64字符串添加附件信息
                if(StringUtils.isNotEmpty(attachment.getAttachmentValue())){
                    File file = Base64Utils.base64ToFile(attachment.getAttachmentValue());
                    helper.addAttachment(attachment.getAttachmentName(), file);
                    tempFiles.add(file.getAbsolutePath());
                    continue;
                }

                //根据sheet页填充附件内容
                ExcelUtils.ExcelModel excelModel = new ExcelUtils.ExcelModel();
                for (int i = 0; i < attachment.getAttachmentExcelArray().size(); i++) {
                    AttachmentDTO attachmentExcel = attachment.getAttachmentExcelArray().get(i);
                    ExcelUtils.ExcelModel sheet = new ExcelUtils.ExcelModel();
                    sheet.setSheetName(attachmentExcel.getSheetName());
                    sheet.setSheetLines(attachmentExcel.getSheetLines());
                    html += ExcelUtils.html(attachmentExcel.getSheetLines());
                    excelModel.addSheet(sheet);
                }
                //添加附件信息
                String tempFile = attachment.getAttachmentName().endsWith("xls") ? IdUtil.simpleUUID() + "xls" : IdUtil.simpleUUID() + ".xlsx";
                ExcelUtils.writeInfoToExcel(tempFile, excelModel);
                helper.addAttachment(attachment.getAttachmentName(), new File(tempFile));
                tempFiles.add(tempFile);
            }
            //邮件发送
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //删除临时文件
            if (tempFiles.size() > 0) {
                for (String tempFile : tempFiles) {
                    ExcelUtils.deleteFile(tempFile);
                }
            }
        }
    }

    /**
     * 邮箱发送请求校验
     * @param messageVO
     * @throws Exception
     */
    private void checkParam(MessageVO messageVO) throws Exception{
        //校验邮箱发送时间是否超时
        long creationTime = messageVO.getCreationTime().getDate().getTime();
        long nowDate = new Date().getTime();
        if(nowDate - creationTime > 1000*60*10){
            throw new BusinessException("请求超时");
        }
        List<AttachmentDTO> attachments = messageVO.getAttachments();
        if(CollUtil.isNotEmpty(attachments)){
            for (AttachmentDTO attachment : attachments) {
                String attachmentName = attachment.getAttachmentName();
                //附件名称校验
                if(StringUtils.isNotEmpty(attachmentName)){
                    throw new BusinessException("附件名称不能为空");
                }

                //附件内容校验
                String attachmentValue = attachment.getAttachmentValue();
                List<AttachmentDTO> attachmentExcelArray = attachment.getAttachmentExcelArray();
                if (StringUtils.isEmpty(attachmentValue) && CollUtil.isEmpty(attachmentExcelArray)) {
                    throw new BusinessException("attachmentValue或attachmentExcelArray不能同时为空");
                }
                if(CollUtil.isNotEmpty(attachmentExcelArray)){
                    for (AttachmentDTO attach : attachmentExcelArray) {
                        //sheet页名称非空校验
                        if(StringUtils.isEmpty(attach.getSheetName())){
                            throw new BusinessException("未设置excel sheet名称");
                        }
                        //excel内容非空校验
                        if(CollUtil.isEmpty(attach.getSheetLines())){
                            throw new BusinessException("excel未设置内容");
                        }
                    }
                }
            }
        }
    }
}
