package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/eatmoreapple/openwechat"
)

func Use(vals ...interface{}) {
	for _, val := range vals {
		_ = val
	}
}
var keyWordMap = map[string]string{
	"生成课程表":  "./examples/classExample.jpg",
	"生成校历": "./examples/SchoolCalendar.png",
}
type SendTextRequest struct {
	InGroup bool   `json:"in_group"` //本来想用于区分在群聊和非群聊时的上下文记忆规则，但是最终没有实现...
	UserID  string `json:"user_id"`
	Text    string `json:"text"`
}

type SendTextResponse struct {
	UserID       string `json:"user_id"`
	Text         string `json:"text"`
	HasError     bool   `json:"error"`
	ErrorMessage string `json:"error_msg"`
}

type SendImageRequest struct {
	UserName     string   `json:"user_name"`
	FileNames    []string `json:"filenames"`
	HasError     bool     `json:"error"`
	ErrorMessage string   `json:"error_msg"`
}

type GenerateImageRequest struct {
	UserName string `json:"user_name"`
	Prompt   string `json:"prompt"`
}

func HttpPost(url string, data interface{}, timelim int) []byte {
	// 超时时间
	timeout, _ := time.ParseDuration(fmt.Sprintf("%ss", timelim)) //是的，这里有个bug，但是这里就是靠这个bug正常运行的！！！？？？

	client := &http.Client{Timeout: timeout}
	jsonStr, _ := json.Marshal(data)
	resp, err := client.Post(url, "application/json", bytes.NewBuffer(jsonStr))
	if err != nil {
		return []byte("")
	}
	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)
	return result

	// ———————————————
	// 版权声明：本文为CSDN博主「gaoluhua」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
	// 原文链接：https://blog.csdn.net/gaoluhua/article/details/124855716
}

func main() {

	bot := openwechat.DefaultBot(openwechat.Desktop) // 桌面模式

	// 注册登陆二维码回调
	bot.UUIDCallback = openwechat.PrintlnQrcodeUrl
	if err := bot.Login(); err != nil {
		fmt.Println(err)
		return
	}

	// 获取登陆的用户
	self, err := bot.GetCurrentUser()
	if err != nil {
		fmt.Println(err)
		return
	}

	Use(self)

	// 注册消息处理函数
	bot.MessageHandler = func(msg *openwechat.Message) {
		go sendMessage(msg, self)
	}

	bot.Block()
}

func sendMessage(msg *openwechat.Message, self *openwechat.Self) {
	if msg.IsTickledMe() {
		msg.ReplyText("你好。我是大数据分析与知识处理课程的AI助手，专门为学习相关课程的学生提供帮助，包括解答疑问、提供学习资料、辅助分析和理解复杂概念等。如果您有任何与大数据分析、知识处理相关的问题，欢迎随时向我提问。")
		return
	}

	if !msg.IsText() {
		return
	}

	//	fmt.Println(msg.Content)

	content := msg.Content
	if msg.IsSendByGroup() && !msg.IsAt() {
		return
	}

	if msg.IsSendByGroup() && msg.IsAt() {
		atheader := fmt.Sprintf("@%s", self.NickName)
		//fmt.Println(atheader)
		if strings.HasPrefix(content, atheader) {
			content = strings.TrimLeft(content[len(atheader):], "  \t\n")
		}
	}
	//fmt.Println(content)
	content = strings.TrimRight(content, "  \t\n")
	if content == "查看机器人信息" {
		info := HttpPost("http://localhost:11111/info", nil, 20)
		msg.ReplyText(string(info))

	} else if strings.HasPrefix(content, "生成图片") {
		// 调用Stable Diffusion
		// msg.ReplyText("这个功能还没有实现，可以先期待一下~")
		sender, _ := msg.Sender()
		content = strings.TrimLeft(content[len("生成图片"):], " \t\n")

		resp_raw := HttpPost("http://localhost:11111/draw", GenerateImageRequest{UserName: sender.ID(), Prompt: content}, 120)
		if len(resp_raw) == 0 {
			msg.ReplyText("生成图片出错啦QwQ，或许可以再试一次")
			return
		}

		resp := SendImageRequest{}
		json.Unmarshal(resp_raw, &resp)
		//fmt.Println(resp.FileName)
		if resp.HasError {
			msg.ReplyText(fmt.Sprintf("生成图片出错啦QwQ，错误信息是：%s", resp.ErrorMessage))
		} else {
			for i := 0; i < len(resp.FileNames); i++ {
				img, _ := os.Open(resp.FileNames[i])
				defer img.Close()
				msg.ReplyImage(img)
			}
		}

	}else {
    // 遍历 map
    for keyword, value := range keyWordMap {
			if strings.Contains(msg.Content, keyword) {
				img, _ := os.Open(value)
				defer img.Close()
				msg.ReplyImage(img)
				return
			}
	}
		// 调用GPT

		sender, _ := msg.Sender()
		//var group openwechat.Group{} = nil
		var group *openwechat.Group = nil

		if msg.IsSendByGroup() {
			group = &openwechat.Group{User: sender}
		}

		if content == "重置上下文" {
			if !msg.IsSendByGroup() {
				HttpPost("http://localhost:11111/chat_clear", SendTextRequest{InGroup: msg.IsSendByGroup(), UserID: sender.ID(), Text: ""}, 60)
			} else {
				HttpPost("http://localhost:11111/chat_clear", SendTextRequest{InGroup: msg.IsSendByGroup(), UserID: group.ID(), Text: ""}, 60)
			}
			msg.ReplyText("OK，我忘掉了之前的上下文。")
			return
		}

		resp := SendTextResponse{}
		resp_raw := []byte("")

		if !msg.IsSendByGroup() {
			resp_raw = HttpPost("http://localhost:11111/chat", SendTextRequest{InGroup: false, UserID: sender.ID(), Text: msg.Content}, 60)
		} else {
			resp_raw = HttpPost("http://localhost:11111/chat", SendTextRequest{InGroup: false, UserID: group.ID(), Text: msg.Content}, 60)
		}
		if len(resp_raw) == 0 {
			msg.ReplyText("运算超时了QAQ，或许可以再试一次。")
			return
		}

		json.Unmarshal(resp_raw, &resp)

		if len(resp.Text) == 0 {
			msg.ReplyText("GPT对此没有什么想说的，换个话题吧。")
		} else {
			if resp.HasError {
				if msg.IsSendByGroup() {
					sender_in_group, _ := msg.SenderInGroup()
					nickname := sender_in_group.NickName
					msg.ReplyText(fmt.Sprintf("@%s\n%s\n-------------------\n%s", nickname, content, resp.ErrorMessage))
				} else {
					msg.ReplyText(resp.ErrorMessage)
				}
			} else {
				if msg.IsSendByGroup() {
					sender_in_group, _ := msg.SenderInGroup()
					nickname := sender_in_group.NickName
					msg.ReplyText(fmt.Sprintf("@%s\n%s\n-------------------\n%s", nickname, content, resp.Text))
				} else {
					msg.ReplyText(resp.Text)
				}
			}
		}

	}
}
