package controller

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"log"
	"net/smtp"
	"os"
	"regexp"
	"strings"
	"text/template"
	"time"
	"background/config"
	"background/db"
)

type MailController struct {
}
type RespJson struct {
	Msg      string      `json:"msg"`
	Data     interface{} `json:"data,omitempty"`
	Affected int64       `json:"affected,omitempty"`
}

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsExist(err) {
		return true, nil
	}
	return false, err
}

func GetTemplateFile(template string) ([]byte, error) {
	path := "G:\\GoPath\\Email\\" + template + ".tpl"
	ok, err := PathExists(path)
	if !ok {
		return nil, errors.New("Count not Find File " + path)
	}
	file, err := os.Open(path)
	if err != nil {
		log.Println(err.Error())
	}
	ret, err := ioutil.ReadAll(file)
	file.Close()
	return ret, nil
}

//静态文件存放地
const PATH_STATIC = "G://GoPath//Email//static//"

type ReqSendEmailTpl struct {
	From     string      `json:"from"`
	To       string      `json:"to"`
	Tittle   string      `json:"tittle"`
	TempData interface{} `json:"temp_data"`
	Template string      `json:"template"`
	Generate bool        `json:"generate"`
}
type ReqSendEmail struct {
	Email   string `json:"email_address"`
	Content string `json:"content"`
}

func SendToMailWithUserInfo(title, user, password, host, to, content string) error {
	var content_type string
	hp := strings.Split(host, ":")
	auth := smtp.PlainAuth("", user, password, hp[0])

	msg := []byte("To: " + to + "\r\nFrom: " + user + "\r\nSubject: " + title + "\r\n" +
		content_type + "\r\n\r\n" + content + "\r\n")
	send_to := strings.Split(to, ";")

	//检测是否是邮件地址
	for k, _ := range send_to {
		match, _ := regexp.MatchString("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?", send_to[k])
		if !match {
			return errors.New("Format Error")
		}
	}

	err := smtp.SendMail(host, auth, user, send_to, msg)
	if err != nil {
		return err
	}
	return err
}

func SendToMailTpl(title, user, password, host, to, tplname string, content interface{}, mailtype string, ifgenerate bool) error {
	var content_type string
	var paseresult bytes.Buffer
	writer := bufio.NewWriter(&paseresult)
	hp := strings.Split(host, ":")
	auth := smtp.PlainAuth("", user, password, hp[0])

	if mailtype == "html" {
		content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
	} else {
		content_type = "Content-Type: text/plain" + "; charset=UTF-8"
	}
	//todo 获取模板文件内容
	tpl, err := GetTemplateFile(tplname)
	if err != nil {
		log.Println(err.Error())
		return err
	}
	//todo 渲染
	tparse := template.New(tplname)
	tparse, _ = tparse.Parse(string(tpl))
	tparse.Execute(writer, content)
	writer.Flush()
	if err != nil {
		log.Println(err.Error())
		return err
	}

	msg := []byte("To: " + to + "\r\nFrom: " + user + "\r\nSubject: " + title + "\r\n" +
		content_type + "\r\n\r\n" + paseresult.String() + "\r\n")
	send_to := strings.Split(to, ";")

	//todo 如果生成Html文件
	if ifgenerate {
		file, err := os.Create(PATH_STATIC + tplname + ".html")
		if err != nil {
			log.Println(err.Error())
		}
		file.WriteString(paseresult.String())
		file.Close()
	}
	//检测是否是邮件地址
	for k, _ := range send_to {
		match, _ := regexp.MatchString("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?", send_to[k])
		if !match {
			return errors.New("Format Error")
		}
	}

	err = smtp.SendMail(host, auth, user, send_to, msg)
	if err != nil {
		return err
	}
	return err
}

/*
func OnSendEmailSendCloud(c *gin.Context){
	var req ReqSendEmail
	var resp mysqlcurd.RespJson
	defer func() {
		c.JSON(200, resp)
	}()

	e := c.Bind(&req)
	if e!= nil{
		log.Println(e.Error())
		resp.Msg = "ParaErr"
		return
	}

	sendcloud.UpdateApiInfo("a7458969_test_KIIqjl", "ovErXj6M8UJeiPJt")
	var to = make([]map[string]string, 1)
	to[0] = map[string]string{"to":"290198252@qq.com", "%url%": "http://www.baidu.com"}
	var ok, err, result = sendcloud.SendTemplateMail("test_template_active", "290198252@sendcloud.org", "测试", "", "测试", to, nil)
	if err != nil{
		log.Print(err.Error())
		resp.Msg = "Fail"
	}
	if !ok{
		resp.Msg = "Fail"
	}
	resp.Msg = result
}*/

/*
{
	"tittle":"运维通知",
	"from":"c7458969@163.com",
	"to":"290198252@qq.com",
	"template":"test",
	"generate":true,
	"temp_data":{
		"content":"f发撒旦法时代阿达是否",
		"title":"运维通知2",
		"topimg":"http://img2.imgtn.bdimg.com/it/u=387283908,3372540416&fm=27&gp=0.jpg",
		"button1text":"客服热线",
		"button1url":"http://www.baidu.com",
		"button2text":"查看详情",
		"button2url":"http://www.baidu.com",
		"logoimg":"http://news.tom.com/dimg/2016/1027/img-1479784632271.jpg"
	}
}
*/
//from: 发送人邮箱
//to:接收邮件,可以是"290198252@qq.com;29019822@qq.com;2901982@qq.com" 邮箱之间用分号隔开
//template:模板名字
//content :网页模板的参数 key-value结构
//temp_data 模板内具体要替换的变量名字  Key-value结构
//generate  是否生成静态html
func OnSendEmailTpl(c *gin.Context) {
	var req ReqSendEmailTpl
	var resp RespJson
	defer func() {
		c.JSON(200, resp)
	}()

	e := c.Bind(&req)
	if e != nil {
		log.Println(e.Error())
		resp.Msg = "ParaErr"
		return
	}
	user := "c7458969@163.com"
	password := "caiyu123"
	host := "smtp.163.com:25"
	//抄送给自己
	//e = SendToMail(user,password,host,req.From,req.Template,req.Content,"html")
	//发送
	e = SendToMailTpl(req.Tittle, user, password, host, req.To, req.Template, req.TempData, "html", req.Generate)
	if nil != e {
		log.Println(e.Error())
		resp.Msg = "Error"
		return
	}
	resp.Msg = "OK"
}

//from: 发送人邮箱
//to:接收邮件,可以是"290198252@qq.com;29019822@qq.com;2901982@qq.com" 邮箱之间用分号隔开
//template:模板名字
//content :网页模板的参数 key-value结构
//temp_data 模板内具体要替换的变量名字  Key-value结构
//generate  是否生成静态html
func (this *MailController) OnSendEmailCode(c *gin.Context) {
	var req ReqSendEmail
	var resp RespJson
	defer func() {
		c.JSON(200, resp)
	}()

	e := c.Bind(&req)
	if e != nil {
		log.Println(e.Error())
		resp.Msg = "ParaErr"
		return
	}
	if req.Email != "" {
		type Count struct {
			Count int32 `json:"count"`
		}
		cnt := []Count{}
		query := fmt.Sprintf("select count(*) as count from users where users.email_address = %s", req.Email)
		e := db.GetMysqlClient().Query2(query, &cnt)
		if nil != e {
			log.Println(e.Error())
			return
		}
	} else {
		return
	}
	user := "c7458969@163.com"
	password := "caiyu123"
	host := "smtp.163.com:25"
	//抄送给自己
	//e = SendToMail(user,password,host,req.From,req.Template,req.Content,"html")
	//发送
	verCode := CreateVerify(6)
	content := "您的验证码是" + verCode
	userKey := fmt.Sprintf("user_%s_verify", req.Email)
	config.RedisOne().Set(userKey, verCode, time.Hour*24)
	e = SendToMailWithUserInfo("后台管理系统验证码", user, password, host, req.Email, content)
	if nil != e {
		log.Println(e.Error())
		resp.Msg = "Error"
		return
	}
	resp.Msg = "OK"
}
