package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
)

func getKfSendURL() (url string) {
	atk, _ := GetAccessToken()
	url = fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", atk)
	return
}

type sendTxtMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	Text    struct {
		Content string `json:"content"`
	} `json:"text"`
	CustomerService struct {
		KfAccount string `json:"kf_account"`
	} `json:"customservice"`
}

func kfSendTxt(user, txt string) {
	u := getKfSendURL()

	s := sendTxtMsg{}
	s.MsgType = "text"
	s.Text.Content = txt
	s.ToUser = user

	//j, _ := json.Marshal(s) // it will escape html < > and & to \u0006
	j, _ := myJSONMarshal(s) // this reserves < > and &
	log.Println(string(j))
	postJSON(j, u)
}

func kfSendTxtAs(user, txt, KF string) {
	u := getKfSendURL()

	s := sendTxtMsg{}
	s.MsgType = "text"
	s.Text.Content = txt
	s.ToUser = user
	s.CustomerService.KfAccount = KFUsers.kfAcc(KF)
	//j, _ := json.Marshal(s) // it will escape html < > and & to \u0006
	j, _ := myJSONMarshal(s) // this reserves < > and &
	log.Println(string(j))
	postJSON(j, u)
}

func myJSONMarshal(t interface{}) ([]byte, error) {
	buffer := &bytes.Buffer{}
	encoder := json.NewEncoder(buffer)
	encoder.SetEscapeHTML(false)
	err := encoder.Encode(t)
	return buffer.Bytes(), err
}

type sendPicMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	Image   struct {
		MediaID string `json:"media_id"`
	} `json:"image"`
}

func kfSendPic(user, pic string) {
	mID := uploadImage(pic)
	kfSendPicByMediaID(user, mID)
}

func kfSendPicByMediaID(user, mediaID string) {
	u := getKfSendURL()
	s := sendPicMsg{}
	s.ToUser = user
	s.MsgType = "image"
	s.Image.MediaID = mediaID

	j, _ := json.Marshal(s)
	postJSON(j, u)
}

type sendVoiceMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	Voice   struct {
		MediaID string `json:"media_id"`
	} `json:"voice"`
}

func kfSendVoice(user, path string) {
	mID := uploadVoice(path)
	kfSendVoiceByMediaID(user, mID)
}

func kfSendVoiceByMediaID(user, mediaID string) {
	u := getKfSendURL()
	s := sendVoiceMsg{}
	s.ToUser = user
	s.MsgType = "voice"
	s.Voice.MediaID = mediaID

	j, _ := json.Marshal(s)
	postJSON(j, u)
}

type sendVideoMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	Video   struct {
		MediaID      string `json:"media_id"`
		ThumbMediaID string `json:"thumb_media_id"`
		Title        string `json:"title"`
		Description  string `json:"description"`
	} `json:"video"`
}

func kfSendVideo(user, path, title, description, thumb string) {
	mID := uploadVideo(path)
	tID := uploadThumb(thumb)
	kfSendVideoByMediaID(user, mID, title, description, tID)
}

func kfSendVideoByMediaID(user, mediaID, title, description, tID string) {
	u := getKfSendURL()
	s := sendVideoMsg{}
	s.ToUser = user
	s.MsgType = "video"
	s.Video.MediaID = mediaID
	s.Video.Description = description
	s.Video.Title = title
	s.Video.ThumbMediaID = tID

	j, _ := json.Marshal(s)
	postJSON(j, u)
}

type sendMusicMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	Music   struct {
		MediaID      string `json:"media_id"`
		ThumbMediaID string `json:"thumb_media_id"`
		Title        string `json:"title"`
		Description  string `json:"description"`
		URL          string `json:"musicurl"`
		HqURL        string `json:"hqmusicurl"`
	} `json:"music"`
}

func kfSendMusic(user, title, description, thumbID, url, hqurl string) {
	u := getKfSendURL()
	s := sendMusicMsg{}
	s.ToUser = user
	s.MsgType = "music"
	s.Music.Title = title
	s.Music.Description = description
	s.Music.ThumbMediaID = thumbID
	s.Music.URL = url
	s.Music.HqURL = hqurl
	j, _ := json.Marshal(s)
	log.Println(string(j))
	postJSON(j, u)

}

type sendNewsArticle struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	URL         string `json:"url"`
	PicURL      string `json:"picurl"`
}

type sendNewsMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	News    struct {
		Articles []sendNewsArticle `json:"articles"`
	} `json:"news"`
}

func kfSendNews(toUser, title, description string, articles []sendNewsArticle) {
	count := 0
	s := sendNewsMsg{}
	s.ToUser = toUser
	s.MsgType = "news"

	//build article
	a := []sendNewsArticle{}
	for _, v := range articles {
		a = append(a, v)
		count++
		if count >= 10 {
			log.Printf("too many article, only take 10")
			break
		}
	}
	s.News.Articles = a

	//marshal
	j, _ := json.Marshal(s)
	log.Println(string(j))
	//send
	u := getKfSendURL()
	postJSON(j, u)
}

type sendMPNewsMsg struct {
	ToUser  string `json:"touser"`
	MsgType string `json:"msgtype"`
	MpNews  struct {
		MediaID string `json:"media_id"`
	} `json:"mpnews"`
}

func kfSendMPNews(toUser, mediaID string) {
	s := sendMPNewsMsg{}
	s.ToUser = toUser
	s.MsgType = "mpnews"
	s.MpNews.MediaID = mediaID
	mashalAndSend(s)
}

func mashalAndSend(v interface{}) (resp string, err error) {
	//marshal
	j, _ := json.Marshal(v)
	log.Println(string(j))
	//send
	u := getKfSendURL()
	return postJSON(j, u)
}
