package handler

import (
	"errors"
	"fmt"
	"git.links123.net/Slate/CorpusAI/config"
	"git.links123.net/Slate/CorpusAI/service"
	"git.links123.net/Slate/CorpusAI/service/store/cache"
	"git.links123.net/Slate/CorpusAI/service/store/mysql"
	"git.links123.net/links123.com/pkg/request"
	"github.com/gin-gonic/gin"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// TextToSpeech godoc
// @Tags 语料库
// @Summary 文本转语音
// @Description Text to speech
// @Accept  json
// @Produce  json
// @Param text query string false "单词/短语/句子"
// @Param languageCode query string false "en-US(美音)/en-GB(英音)" Enums(en-US, en-GB)
// @Param gender query string false "MALE(男音)/FEMALE(女音)" Enums(MALE, FEMALE)
// @Success 302 {string} json "https://lnks123-campus-tts-hk.oss-cn-hongkong.aliyuncs.com/xxxx.mp3"
// @Failure 400 {string} json "{"msg": "error info"}"
// @Failure 500 {string} json "{"msg": "error info"}"
// @Router /en/tts [get]
func TextToSpeechMain(ctx *gin.Context) {

	//Text string, LanguageCode, Gender string
	//voiceName := ctx.Query("voiceName")
	speed, err := strconv.ParseFloat(ctx.DefaultQuery("speed", "1.00"), 64)
	pitch, err := strconv.ParseFloat(ctx.DefaultQuery("pitch", "0.00"), 64)
	// 获取参数内容,没有则返回空字符串
	text, err := url.QueryUnescape(ctx.Query("text"))
	languageCode, err := url.QueryUnescape(ctx.Query("languageCode"))
	gender, err := url.QueryUnescape(ctx.Query("gender"))
	voiceName := GetDefaultVoiceName(languageCode, gender)

	if err != nil || voiceName == "" || text == "" {
		request.Fail(ctx, 400, errors.New("text or  voiceName error"))
		return
	}

	text = strings.Trim(text , "")

	ossObjectKey := service.GetTtsOssKey(text, voiceName, languageCode, speed, pitch)

	textKey := cache.GetTextKey(ossObjectKey)

	textKeyExists := cache.TextKeyExists(textKey)

	//fmt.Println("TextToSpeechMain %s%s%s%s", text,ossObjectKey,textKey,textKeyExists)

	if textKeyExists == true {

		//get url
		mp3Url := service.GetUrl(ossObjectKey)

		ctx.Redirect(302, mp3Url)
		return
	} else {
		appConfig := config.C.App
		if appConfig.InChina == true {

			text = url.QueryEscape(text)
			resp, err := http.Get(appConfig.ApiHost + "/v1/en/tts?text="+text+"&languageCode="+languageCode+"&gender="+gender)

			if err != nil || (resp.StatusCode != http.StatusFound && resp.StatusCode != http.StatusOK) {

				fmt.Println("service.Get Api", err , appConfig.ApiHost + "/v1/en/tts?text="+text+"&languageCode="+languageCode+"&gender="+gender)
				fmt.Println("service.Get Api resp", resp, err)
				request.Fail(ctx, 400, errors.New("Get Api error"))
				return
			}

			mp3Url := service.GetUrl(ossObjectKey)

			//set cache
			cache.SetOssObject(textKey, ossObjectKey)

			ctx.Redirect(302, mp3Url)
			return
		} else {

			//todo 先从db查一下缓存, 线上数据尽量走其它方式缓存到DB

			AudioContent, err := service.TextToSpeech(text, voiceName, languageCode, speed, pitch)
			if err != nil {
				fmt.Println("service.TextToSpeech Error", err)
				request.Fail(ctx, 400, errors.New("Error: service.TextToSpeech"))
				return
			}

			// todo 因hk地区和国内oss不通
			service.UploadHkOss(ossObjectKey, AudioContent)
			uploadResult, err := service.UploadOss(ossObjectKey, AudioContent)

			if err != nil {
				fmt.Println("service.UploadHkOss Error", err)
				request.Fail(ctx, 400, errors.New("Error: service.UploadOss"))
				return
			}
			if uploadResult == true {

				//get url
				mp3Url := service.GetUrl(ossObjectKey)
				//set cache
				cache.SetOssObject(textKey, ossObjectKey)
				//set db
				mysql.CreateCorpusTts(text, textKey, languageCode, voiceName, ossObjectKey, speed, pitch)

				ctx.Redirect(302, mp3Url)
				return
			}

			//set cache
		}

	}
}


func GetDefaultVoiceName(LanguageCode, Gender string) string {

	//todo
	switch LanguageCode {

	case "en-GB":
		if Gender == "FEMALE" {

			return "en-GB-Wavenet-C"
		} else {

			return "en-GB-Wavenet-B"
		}
	case "en-US":
		if Gender == "FEMALE" {

			return "en-US-Wavenet-C"
		} else {

			return "en-US-Wavenet-B"
		}
	}

	return ""

	//en-GB	en-GB-Wavenet-B	MALE
	//en-GB	en-GB-Wavenet-C	FEMALE

	//en-US	en-US-Wavenet-B	MALE
	//en-US	en-US-Wavenet-C	FEMALE

	//通过键值获取默认配置: languageCode + gender

}