package main

import (
	"fmt"
	"log"
	"os"
	"time"
)

const idProcEcho = "Echo"

var procEcho = chatProcedure{
	echoInit,
	echoClean,
	echoStart,
	echoServe,
	echoSummary,
	echoInto,
}

func echoInit(ss *openIDSessionData) {
	ss.setProcedure(idProcEcho)
	ss.refreshExpire(600)
}

func echoClean(ss *openIDSessionData) {
	ss.Procedure = ""
	log.Println(*ss)
}

func echoStart(ss *openIDSessionData, in InWechatMsg) {
	ss.setKvPair("started at", time.Now().Format("2006/03:04:05"))
}

func echoServe(ss *openIDSessionData, in InWechatMsg) {
	stopEcho := false
	if in.header.MsgType == "text" {
		if in.body.(TextMsg).Content == "结束Echo" || in.body.(TextMsg).Content == "结束echo" {
			stopEcho = true
			return
		}
	}
	if in.header.MsgType == "voice" {
		if in.body.(VoiceMsg).Recognition == "退出退出。" {
			stopEcho = true
		}
	}

	if stopEcho {
		in.replyText("echo 正式结束")
		echoSummary(ss)
		echoClean(ss)
	} else {
		ss.refreshExpire(600)
		echoCommand(ss, in)
	}

}

func echoSummary(ss *openIDSessionData) {
	msg := ss.getVal("started at")
	msg = msg + "\n" + ss.getVal("msg")
	kfSendTxt(ss.OpenID, msg)
}

func echoInto(ss *openIDSessionData) {
	kfSendTxt(ss.OpenID, "10 分钟没有输入之后 Echo将自动结束，\n输入 [结束Echo] 清除Echo模式")
}

func echoCommand(ss *openIDSessionData, in InWechatMsg) {
	openID := in.header.FromUserName
	str, err := BuildTextMsg(openID, "default")
	log.Println("echoCommand :" + in.header.MsgType)
	switch in.body.(type) {
	case TextMsg:
		m := in.body.(TextMsg)
		str, err = BuildTextMsg(openID, m.Content+"\n\n关键词 [转接] 将后续信息都转接到 客服 测试版")
		msg := ss.getVal("msg")
		msg = msg + m.Content
		ss.setKvPair("msg", msg)
		in.replyXML(str)
	case PicMsg:
		m := in.body.(PicMsg)
		str = buildPicMsg(openID, m.MediaId)
		in.replyXML(str)
	case VoiceMsg:
		m := in.body.(VoiceMsg)
		str = buildVoiceMsg(openID, m.MediaId)
		in.replyXML(str)
		kfSendTxt(openID, "翻译结果:"+m.Recognition)
	case VideoMsg:
		m := in.body.(VideoMsg)
		str = buildVideoMsg(openID, "e2iNEiSxCX5TV1WbFd0TQMn5lilY3bylh1--lDBwi7I", "航拍春日哈工大", m.MediaId)
		in.replyXML(str)
	case ShortVideoMsg:
		m := in.body.(ShortVideoMsg)
		str = buildVideoMsg(openID, "e2iNEiSxCX5TV1WbFd0TQMn5lilY3bylh1--lDBwi7I", "航拍春日哈工大", m.MediaId)
		in.replyXML(str)
	case LocationMsg:
		m := in.body.(LocationMsg)
		mid := location2MediaID(m.Location_X, m.Location_Y)
		str, _ = BuildTextMsg(openID, fmt.Sprintf("long=%f, lat=%f, scale=%d", m.Location_X, m.Location_Y, m.Scale))
		in.replyXML(str)
		str = buildPicMsg(openID, mid)
		url := location2URL(m.Location_X, m.Location_Y)
		kfSendTxt(openID, url)
	case LinkMsg:
		m := in.body.(LinkMsg)
		str, _ = BuildTextMsg(openID, m.Url)
		in.replyXML(str)
		kfSendTxt(openID, m.Title+m.Description)
	case EventMsg:
		echoEvents(in)
	default:
		str, err = BuildTextMsg(openID, "text message")
	}

	if err != nil {
		log.Println("build response failed")
	}
	return
}

func echoEvents(in InWechatMsg) {
	openID := in.header.FromUserName
	str := ""
	m := in.body.(EventMsg)
	log.Println("Event = " + m.Event)
	switch m.Event {
	case "LOCATION":
		mid := location2MediaID(m.Latitude, m.Longitude)
		str = buildPicMsg(openID, mid)
	case "CLICK":
		str, _ = BuildTextMsg(openID, m.EventKey)
	case "subscribe":
		str, _ = BuildTextMsg(openID, m.EventKey)
	case "unsubscribe":
		str, _ = BuildTextMsg(openID, m.EventKey)
	case "SCAN":
		str, _ = BuildTextMsg(openID, m.EventKey)
	case "VIEW":
		str, _ = BuildTextMsg(openID, m.EventKey)
	case "kf_create_session":
		kfSendTxt(openID, m.KfAccount)
		//str, _ = BuildTextMsg(openID, m.KfAccount) // response msg is ignored by wechat
	case "kf_close_session":
		kfSendTxt(openID, m.KfAccount+"\n close type ="+m.CloseType)
		//str, _ = BuildTextMsg(openID, m.KfAccount+"\n close type ="+m.CloseType) //response msg is ignored by wechat
	case "scancode_waitmsg":
		log.Println(m.ScanCodeInfo.ScanResult)
		log.Println(m.ScanCodeInfo.ScanType)
		msg := fmt.Sprintf("ScanResult =%s, ScanType=%s", m.ScanCodeInfo.ScanResult, m.ScanCodeInfo.ScanType)
		kfSendTxt(openID, msg)
	case "pic_photo_or_album":
		msg := fmt.Sprintf("Count = %d ", m.SendPicsInfo.Count)
		log.Println(m.SendPicsInfo.Count)
		for _, v := range m.SendPicsInfo.PicList.Item {
			log.Println(v.PicMd5Sum)
			kfSendTxt(openID, v.PicMd5Sum)
		}
		kfSendTxt(openID, msg)
	default:
		str, _ = BuildTextMsg(openID, " unknown event:"+m.Event)
	}
	in.replyXML(str)
	return
}

func location2MediaID(lat, long float64) (mediaID string) {
	url := fmt.Sprintf("https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&markers=color:red|label:S|%f,%f&zoom=17&size=1280x2014", lat, long, lat, long)
	file, _, _ := saveURL(url)
	mediaID = uploadImage(file)
	os.Remove(file)
	return
}

func location2URL(lat, long float64) (url string) {
	url = fmt.Sprintf("http://maps.google.com/maps?z=12&t=m&q=loc:%f+%f", lat, long)
	log.Println(url)
	return
}
