package service

import (
	"WorldEpcho/src/config"
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"

	"io/ioutil"
	"log"
	"net/http"
)

// 获取声音克隆请求参数体
type VoiceCloneRequestParams struct {
	ReferWavPath   string `json:"refer_wav_path"`
	PromptText     string `json:"prompt_text"`
	PromptLanguage string `json:"prompt_language"`
	Text           string `json:"text"`
	TextLanguage   string `json:"text_language"`
}

// 设置音色模型的函数
func VoiceSetModel(name string) (string, error) {

	// 设置请求的URL
	url := config.Conf.VoiceSetModelUrl + "/set_model"

	// 从配置文件获取请求体
	//name := c.PostForm("name")
	model := config.Conf.VoiceModelSets[name]

	// 将结构体转换为JSON格式的字节切片
	requestBody, err := json.Marshal(model)
	if err != nil {
		fmt.Println("Error marshalling JSON: ", err)
		return "", err
	}
	fmt.Println("voiceModel:", model)
	// 创建POST请求
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println("Error sending request: ", err)
		//c.JSON(http.StatusInternalServerError, gin.H{"code": 0, "message": "发送请求失败"})
		return "", err
	}
	defer resp.Body.Close()

	// 读取并打印响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response body: ", err)
		//c.JSON(http.StatusInternalServerError, gin.H{"code": 0, "message": "响应体解析失败"})
		return "", err
	}

	fmt.Println("Response: ", string(body))

	return string(body), nil

}

// 获取克隆后的声音
func GetVoiceCloneInfer(name, text, textLanguage string) ([]byte, error) {
	// 构建请求的URL
	url := config.Conf.VoiceSetModelUrl
	//url := "http://58.34.54.45:17666"
	// 使用结构体填充请求的参数
	WavPath := config.Conf.VoiceModelSets[name].ReferWavPath
	PromptText := config.Conf.VoiceModelSets[name].PromptText
	PromptLanguage := config.Conf.VoiceModelSets[name].PromptLanguage
	requestBody := VoiceCloneRequestParams{
		ReferWavPath:   WavPath,
		PromptText:     PromptText,
		PromptLanguage: PromptLanguage,
		Text:           text,
		TextLanguage:   textLanguage,
	}

	// 将结构体序列化为JSON
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return nil, err
	}

	// 构建HTTP请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return body, nil
}

//获取声音克隆后的接口
func GetVoiceEcho(ctx *gin.Context) {
	/*
	   判断用户是否登录
	*/
	_, isLogin := IsUserLoggedIn(ctx)
	if !isLogin {
		log.Println("用户未登录")
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户未登录"})
		return
	}
	name := ctx.PostForm("name")
	voice_text := ctx.PostForm("voice_text")
	text_language := ctx.PostForm("text_language")
	res, err := VoiceSetModel(name)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "message": "设置模型出错"})
		fmt.Println("设置模型出错,err: ", err)
		return
	}

	if res == "true" {
		// 调用函数以获取音频数据
		// 将音频数据发送给客户端
		// 注意："audio/wav"是音频文件的MIME类型
		fmt.Println("声音模型设置成功")
		audioData, err := GetVoiceCloneInfer(name, voice_text, text_language)
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "message": "获取克隆后的音频出错!"})
			fmt.Println("获取克隆后的音频出错,err: ", err)
			return
		}
		ctx.Data(http.StatusOK, "audio/wav", audioData)
		/*	ctx.JSON(http.StatusOK, gin.H{
			"code":       1,
			"message":    "生成声音文件成功",
			"voiceInfer": voiceInfer,
		})*/
	}

}

//获取所有声音模型的人物
func QueryAllModelPeopleNames(ctx *gin.Context) {
	/*
	   判断用户是否登录
	*/
	_, isLogin := IsUserLoggedIn(ctx)
	if !isLogin {
		log.Println("用户未登录")
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户未登录"})
		return
	}
	// 获取所有模型的名称（key）
	var Cn_name map[string]string
	Cn_name = make(map[string]string) // 初始化map
	vms := config.Conf.VoiceModelSets
	for name, model := range vms {
		//fmt.Println("name:", name, "==> 中文", model.CnName)
		Cn_name[name] = model.CnName
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code":    1,
		"message": "查询所有声音模型人物名称成功",
		"names":   Cn_name,
	})

}
