package cn.com.agree;

import org.apache.poi.ss.usermodel.*;
import org.simplejavamail.email.Email;
import org.simplejavamail.mailer.Mailer;
import org.simplejavamail.mailer.config.ServerConfig;
import org.simplejavamail.mailer.config.TransportStrategy;

import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.Message;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class MailTool {
    private static final String ip = "smtp.263.net";
    private  static final int port = 25;
    private  static  String user = "yuxiongwei@agree.com.cn";
    private  static  String pwd = "Weiwei01";

    private static int nameColumn=3;

    private  Mailer mailer;

    private  Map<String, String> name2EmailMap;

    private List<List<String>> payrolls;

    private  String template;

    private  int month = new Date().getMonth() + 1;

    private  void sendMail(String to, List<String> payroll) throws Exception {
        Email email = new Email();
        MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
        mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
        mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
        mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
        mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
        mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
        CommandMap.setDefaultCommandMap(mc);

        email.setFromAddress("", user);
        email.addRecipient("", to, Message.RecipientType.TO);

        email.setSubject( "工资明细");

        String html = template;

        for (int i = 0; i < payroll.size(); i++) {
            html = html.replace("{" + i + "}", payroll.get(i));
        }

        email.setTextHTML(html);

        mailer.sendMail(email);
    }

    private  void initServer() throws Exception {
        Properties userProperties = new Properties();
        try {
            userProperties.load(new FileInputStream("user.properties"));
            String prop_user = userProperties.getProperty("user");
            String prop_pwd = userProperties.getProperty("password");
            String nColumn = userProperties.getProperty("name_column");
            if (prop_user != null && !"".equals(prop_user)) {
                user = prop_user;
            }
            if (prop_pwd != null && !"".equals(prop_pwd)) {
                pwd = prop_pwd;
            }
            if (nColumn != null && !"".equals(nColumn)) {
                nameColumn = Integer.parseInt(nColumn);
            }
        }catch (Exception e){
            System.out.println("user.properties not found, use default user and password");
        }
        ServerConfig server = new ServerConfig(ip, port, user, pwd);

        mailer = new Mailer(server, TransportStrategy.SMTP_PLAIN);
    }

    private  void initTemplate() throws Exception {
        InputStream in = MailTool.class.getResourceAsStream("template.html");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            baos.write(buf, 0, len);
        }
        in.close();
        template = new String(baos.toByteArray(), "UTF-8");
    }

    private void initTemplate(File sheethead) throws Exception{
        template = "<!DOCTYPE html>\n" +
                "<html lang=\"zh\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <style>\n" +
                "        table {\n" +
                "            border-spacing: 0;\n" +
                "            border-collapse: collapse;\n" +
                "            width: 100%;\n" +
                "        }\n" +
                "        \n" +
                "        th {\n" +
                "            border: 1px solid;\n" +
                "        }\n" +
                "\n" +
                "        td {\n" +
                "            border: 1px solid;\n" +
                "        }\n" +
                "    </style>\n" +
                "</head>\n" +
                "<body>\n" +
                "<p></p>\n";
        InputStreamReader isr = new InputStreamReader(new FileInputStream(sheethead), "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        String title = "";
        List<String> bodyList = new ArrayList<>();
        int index = 0;
        while((line=br.readLine())!=null){
            if(!line.contains(":")){
                if(!bodyList.isEmpty()){
                    template+="<table>\n" +
                            "    <caption>"+title+"</caption>\n"+
                    "<thead>\n" +
                            "    <tr>\n";
                    for(String head:bodyList){
                        template+="<th>"+head+"</th>\n";
                    }
                    template+="</tr>\n" +
                            "    </thead>\n" +
                            "    <tbody>\n" +
                            "    <tr>\n";
                    for(String head:bodyList){
                        template+="<th>{"+(index++)+"}</th>\n";
                    }
                    template+="</tr>\n" +
                            "    </tbody>\n" +
                            "</table>\n" +
                            "<p></p>\n";
                }
                bodyList.clear();
                title = line;
            }else{
                String element[]=line.split(":");
                bodyList.add(element[1]);
            }
        }
        template+="</body>\n" +
                "</html>";
        MAX_COL = index;
        br.close();
    }

    public static void main(String args[]) throws Exception{
        MailTool tool = new MailTool();
        File file = new File("D:\\work\\工资条群发工具\\sheethead.txt");
        tool.initTemplate(file);
        System.out.println(tool.template);
    }

    private  void initName2EmailMap(String emaiFile) throws Exception {
        name2EmailMap = new HashMap<>();
//        String content = new String(Files.readAllBytes(Paths.get("name2email.txt")), "UTF-8");
//        String[] lines = content.replaceAll("\r\n", "\n").split("\n");
        InputStreamReader isr = new InputStreamReader(new FileInputStream(emaiFile), "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line =null;
        while((line=br.readLine())!=null){
            if (line.trim().length() == 0) {
                continue;
            }
            String[] items = line.split(",");
            if (items.length != 2) {
                continue;
            }
            name2EmailMap.put(items[0].trim(), items[1].trim());
        }
        System.out.println(name2EmailMap.toString());
    }
    int MAX_COL = 49;
    private  List<List<String>> readPayrolls(File file) throws Exception {
        List<List<String>> payrolls = new ArrayList<>();



        Workbook workbook = WorkbookFactory.create(file);
        Sheet sheet = workbook.getSheetAt(0);

        System.out.println(sheet.getFirstRowNum());
        System.out.println(sheet.getLastRowNum());
        Row head = sheet.getRow(0);
        // 计算head有内容的列数
        int headCol = 0;
        for (int i = 0; i < MAX_COL; i++) {
            Cell c = head.getCell(i);
            if (c == null) {
                break;
            }
            headCol++;
        }
        MAX_COL = headCol;
        for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
            List<String> payroll = new ArrayList<>(MAX_COL);
            Row row = sheet.getRow(i);
            boolean ended = false;
            for (int j = 0; j < MAX_COL; j++) {
                if(row==null){
                    ended=true;
                    break;
                }
                Cell c = row.getCell(j);
                if(c==null&&j!=4&&j!=MAX_COL){
                    ended =true;
                    break ;
                }
                if(c==null){
                    payroll.add("");
                }else {
                    payroll.add(c.toString());
                }
            }
            if(ended){
                break;
            }
            payrolls.add(payroll);
        }

        return payrolls;
    }

    public MailTool(){

    };

    public MailTool(String salaryFile,String emailFile) throws Exception {
        initServer();
        File headfile = new File("sheethead.txt");
        System.out.println(headfile.getAbsolutePath());
        initTemplate(new File("sheethead.txt"));
        initName2EmailMap(emailFile);

        payrolls = readPayrolls(new File(salaryFile));

    }

    public void sendMail(){
        int fail=0;
        int noexit=0;
        for (int i = 1; i < payrolls.size(); i++) {
            List<String> payroll = payrolls.get(i);
            String name = payroll.get(nameColumn);
            String email = name2EmailMap.get(name);

            if (email == null) {
                System.out.println("[X]" + name + " email地址不存在");
                for(IMailListener l:listenerList){
                    l.handleMessage("[X]" +name+"email地址不存在");
                }
                noexit++;
                continue;
            }
            for(IMailListener l:listenerList){
                l.handleMessage("正在发送邮件：" +email);
            }
            try {
                sendMail(email, payroll);
                for(IMailListener l:listenerList){
                    l.handleMessage("发送成功：" +email);
                }
            } catch (Exception e) {
                e.printStackTrace();
                for(IMailListener l:listenerList){
                    l.handleMessage("发送失败：" +name);
                }
                fail++;
                System.out.println("[X]" + name);
            }
        }
        if(fail>0||noexit>0){
            for(IMailListener l:listenerList){
                l.handleMessage(fail+"个发送失败，"+noexit+"个邮件不存" );
            }
        }else{
            for(IMailListener l:listenerList){
                l.handleMessage("全部成功");
            }
        }
    }

    List<IMailListener> listenerList = new ArrayList<>();
    public void addMailListener(IMailListener listener){
        listenerList.add(listener);
    }

}

interface IMailListener{
    void handleMessage(String message);
}