package com.ruoyi.postCheck.util.cnooc;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.PostCheckedConfig;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 工业互联网平台，发送邮件接口
 */
@Component
@Slf4j
public class SendMailUtils {


    @Autowired
    private PostCheckedConfig config;

    /**
     * 发送邮件：纯文本
     * 未使用到：param cc:抄送人地址
     *
     * @param subject:邮件名称
     * @param content:邮件内容
     * @param to:收件人地址
     * @return
     */
    public boolean sendText(String subject, String content, String to) throws BaseException {
//        String urlAddr, String subject, String content, String to, String[] filePaths
        String result = sendHttp(config.getSendEmailTxt(), subject, content, to, null);
        if (StringUtils.isBlank(result) || !"success".equalsIgnoreCase(result)) {
            throw new BaseException(result);
        }
        return true;
    }

    /**
     * 发送邮件：HTML
     * 未使用到：param cc:抄送人地址
     *
     * @param subject:邮件名称
     * @param content:邮件内容
     * @param to:收件人地址
     * @return
     */
    public boolean sendHtml(String subject, String content, String to) {
//        String urlAddr, String subject, String content, String to, String[] filePaths
        String result = sendHttp(config.getSendEmailHtml(), subject, content, to, null);
        if (StringUtils.isBlank(result) || !"success".equalsIgnoreCase(result)) {
            throw new BaseException(result);
        }
        return true;
    }


    /**
     * 发送邮件：带附件
     * 未使用到：param cc:抄送人地址
     *
     * @param content:邮件内容
     * @param to:收件人地址
     * @param filePaths：附件列表
     * @return
     */
//    public boolean sendFile(String subject, String content, String to, String[] filePaths) {
    public boolean sendFile(String content, String to, String[] filePaths) {

        //TODO lyp邮件推送：测试阶段给指定的人发送邮件，上线后给本人发邮件。
        if (true) {
            content += "<br><br>" +
                    "&nbsp;&nbsp;&nbsp;&nbsp;现在为测试阶段，使用固定的邮箱接收通知，系统上线后真实的收件人邮箱如下：" + to;
//            String addressTempTest = "fangly@cnooc.com.cn;zhangzk@cnooc.com.cn;ex_liuyp5@cnooc.com.cn;";
            String addressTempTest = "ex_liuyp5@cnooc.com.cn;";
            to = addressTempTest;
        }

//        String urlAddr, String subject, String content, String to, String[] filePaths
//        String result = sendHttp(config.getSendEmailFile(), subject, content, to, filePaths);
        String subject = "中海油惠州石化岗检系统通知邮件";
        String result = sendHttp(config.getSendEmailFile(), subject, content, to, filePaths);
        if (StringUtils.isBlank(result) || !"success".equalsIgnoreCase(result)) {
            throw new BaseException(result);
        }
        return true;
    }


    /**
     * 发送邮件
     * 未使用到：param cc:抄送人地址
     *
     * @param urlAddr   接口地址
     * @param subject   邮件名称
     * @param content   邮件内容
     * @param to        收件人地址
     * @param filePaths 附件列表
     * @return
     */
    private String sendHttp(String urlAddr, String subject, String content, String to, String[] filePaths) {
        log.info("【发送邮件】收件人地址 to:{}", to);
        log.info("【发送邮件】邮件名称 subject:{}", subject);
        log.info("【发送邮件】邮件内容 content:{}", content);
        //发送者账号：实际测试无效，始终是系统账号发送
        String from = config.getSendEmailFrom();
        HttpURLConnection conn = null;
        DataOutputStream out = null;
        final String newLine = "\r\n";
        final String prefix = "--";
        try {
            URL url = new URL(urlAddr);
            conn = (HttpURLConnection) url.openConnection();

            String BOUNDARY = "-------7da2e536604c8";
            conn.setRequestMethod("POST");
            //设置超时时间
            conn.setConnectTimeout(25 * 1000);//25秒
            conn.setReadTimeout(25 * 1000);//25秒
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Charsert", "UTF-8");
            // HTTP_POST请求的数据格式
            // Content-type的类型
            // 最常用的三种：
            // application/x-www-form-urlencoded
            // application/json
            // multipart/form-data
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            //创建输出流
            out = new DataOutputStream(conn.getOutputStream());

            //上传附件
            if (filePaths != null && filePaths.length > 0) {
                JSONArray filePathsValues = new JSONArray();
                for (String filePath : filePaths) {
                    // 添加参数file1
                    File file = new File(filePath);
                    filePathsValues.add(file.getPath());//设置文件路径
                    StringBuilder sbFile = new StringBuilder();
                    sbFile.append(prefix);
                    sbFile.append(BOUNDARY);
                    sbFile.append(newLine);
//                    sbFile.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"" + newLine);
//                    sbFile.append("Content-Disposition: form-data;name=\"files\";filename=\"" + file.getName() + "\"" + newLine);
                    sbFile.append("Content-Disposition: form-data;name=\"filePaths\";filename=\"" + file.getName() + "\"" + newLine);
                    sbFile.append("Content-Type:application/octet-stream");
                    sbFile.append(newLine);
                    sbFile.append(newLine);
                    out.write(sbFile.toString().getBytes());
                    DataInputStream in = new DataInputStream(new FileInputStream(file));
                    byte[] bufferOut = new byte[1024];
                    int bytes = 0;
                    while ((bytes = in.read(bufferOut)) != -1) {
                        out.write(bufferOut, 0, bytes);
                    }
                    out.write(newLine.getBytes());
                    in.close();
                }

                // 添加参数filePaths
                JSONObject filePathsJSON = new JSONObject();
                filePathsJSON.put("key", "filePaths");
                filePathsJSON.put("description", "");
                filePathsJSON.put("type", "file");
                filePathsJSON.put("enabled", true);
                filePathsJSON.put("value", filePathsValues.toJSONString());

                StringBuilder sbFilePaths = new StringBuilder();
                sbFilePaths.append(prefix);
                sbFilePaths.append(BOUNDARY);
                sbFilePaths.append(newLine);
                sbFilePaths.append("Content-Disposition: form-data;name=\"filePaths\"");
                sbFilePaths.append(newLine);
                sbFilePaths.append(newLine);
//                sbFilePaths.append("{\"key\":\"filePaths\", \"description\":\"\", \"type\":\"file\", \"enabled\":true, \"value\":[\"C:\\\\test\\\\JAVAUploadTestFile.xlsx\", \"C:\\\\test\\\\JAVAUploadTestFile.docx\"]}");
                sbFilePaths.append(filePathsJSON.toJSONString());
                out.write(sbFilePaths.toString().getBytes());

            }

            //发送者：添加参数from
            StringBuilder sbFrom = new StringBuilder();
            sbFrom.append(newLine);
            sbFrom.append(prefix);
            sbFrom.append(BOUNDARY);
            sbFrom.append(newLine);
            sbFrom.append("Content-Disposition: form-data;name=\"from\"");
            sbFrom.append(newLine);
            sbFrom.append(newLine);
            sbFrom.append(from);
            out.write(sbFrom.toString().getBytes());


            //邮件名称：添加参数subject
            StringBuilder sbSubject = new StringBuilder();
            sbSubject.append(newLine);
            sbSubject.append(prefix);
            sbSubject.append(BOUNDARY);
            sbSubject.append(newLine);
            sbSubject.append("Content-Disposition: form-data;name=\"subject\"");
            sbSubject.append(newLine);
            sbSubject.append(newLine);
            sbSubject.append(subject);
//            out.write(sbSubject.toString().getBytes());
            out.write(new String(sbSubject.toString().getBytes("UTF-8"), "UTF-8").getBytes("UTF-8"));


            //邮件内容：添加参数content
            StringBuilder sbContent = new StringBuilder();
            sbContent.append(newLine);
            sbContent.append(prefix);
            sbContent.append(BOUNDARY);
            sbContent.append(newLine);
            sbContent.append("Content-Disposition: form-data;name=\"content\"");
            sbContent.append(newLine);
            sbContent.append(newLine);
            sbContent.append(content);
//            out.write(sbContent.toString().getBytes());
            out.write(new String(sbContent.toString().getBytes("UTF-8"), "UTF-8").getBytes("UTF-8"));

            //收件人地址：添加参数content
            StringBuilder sbTo = new StringBuilder();
            sbTo.append(newLine);
            sbTo.append(prefix);
            sbTo.append(BOUNDARY);
            sbTo.append(newLine);
            sbTo.append("Content-Disposition: form-data;name=\"to\"");
            sbTo.append(newLine);
            sbTo.append(newLine);
            sbTo.append(to);
            out.write(sbTo.toString().getBytes());

            // 写上结尾标识
            byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            out.write(end_data);
            out.flush();
//            out.close();

            // 定义BufferedReader输入流来读取URL的响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            // { "message": true }
            StringBuilder sbResult = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                log.info("【发送邮件】接口返回信息：{}", line);
                sbResult.append(line);
//                sbResult.append(newLine);
            }
            JSONObject result = JSON.parseObject(sbResult.toString());
            if (result.containsKey("message")) {
                Boolean message = result.getBoolean("message");
                if (message != null && message) {
                    return "success";
                }
            }
            log.error("【发送邮件】发送邮件请求出现未知错误！接口返回信息：{}", sbResult.toString());
            return "未知错误，接口返回信息：" + sbResult.toString();

        } catch (Exception e) {
            log.error("【发送邮件】发送邮件请求出现异常！{}", e.getMessage());
            e.printStackTrace();
            return "发送邮件异常：" + e.getMessage();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                }
            }

            if (conn != null) {
                try {
                    conn.disconnect();
                } catch (Exception e) {
                }
            }


        }

//        log.error("发送邮件请求出现未知错误！");
//        return "未知错误";
    }
}
