package hook

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/gorilla/websocket"
	"path/filepath"
	"strings"
	"wechat-api/workphone"
)

// 开启/关闭实时消息接收功能
func (h *Hook) ConfigureMsgRecive(isEnable string, url string) (err error) {
	resp, err := h.Client.R().SetBody(&ConfigureMsgReciveReq{
		IsEnable: isEnable,
		URL:      url,
	}).Post("http://" + h.ServerIp + ":" + h.WxPort + "/ConfigureMsgRecive")
	if err != nil {
		return
	}
	if !resp.IsSuccessState() {
		err = fmt.Errorf("ConfigureMsgRecive failed with status code %d", resp.StatusCode)
		return
	}
	return
}

// SendTextMsg 发送微信文本消息
func (h *Hook) SendTextMsg(wxid, msg, wxWxid string) error {
	if h.ServerIp == "" {
		conn, err := h.connWorkPhone()
		if err != nil {
			err = fmt.Errorf("SendTextMsg failed")
			return err
		}
		defer func(conn *websocket.Conn) {
			err = conn.Close()
			if err != nil {
				err = fmt.Errorf("SendTextMsg failed")
			}
		}(conn)
		encodedString := base64.StdEncoding.EncodeToString([]byte(msg))

		//sendMsg := &workphone.TalkToFriendTaskMessage{
		//	WeChatId:    wxWxid,
		//	FriendId:    wxid,
		//	ContentType: workphone.EnumContentType_Text,
		//	Content:     []byte(encodedString),
		//}
		//content, err := anypb.New(sendMsg) <-- 这里有坑，会增加字段 "@type": "type.googleapis.com/Jubo.JuLiao.IM.Wx.Proto.TalkToFriendTaskMessage",
		//if err != nil {
		//	return fmt.Errorf("failed to pack message: %v", err)
		//}
		//transportMessage := &workphone.TransportMessage{
		//	MsgType: workphone.EnumMsgType_TalkToFriendTask,
		//	Content: content,
		//}

		// 将 TransportMessage 转换为 JSON
		//transportMessageJSON, err := protojson.MarshalOptions{
		//	UseProtoNames: true,
		//}.Marshal(transportMessage)
		//if err != nil {
		//	return fmt.Errorf("failed to marshal transport message: %v", err)
		//}
		var message map[string]interface{}
		if h.Ctype == uint64(3) {
			message = map[string]interface{}{
				"MsgType": "TalkToFriendTask",
				"Content": map[string]interface{}{
					"WxId":        wxWxid,
					"ConvId":      wxid,
					"ContentType": "Text",
					"Content":     encodedString,
				},
			}
		} else {
			message = map[string]interface{}{
				"MsgType": "TalkToFriendTask",
				"Content": map[string]interface{}{
					"WeChatId":    wxWxid,
					"FriendId":    wxid,
					"ContentType": "Text",
					"Content":     encodedString,
				},
			}
		}
		transportMessageJSON, err := json.Marshal(message)
		if err != nil {
			return err
		}
		// 发送 JSON 消息
		err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
		if err != nil {
			return fmt.Errorf("failed to send message: %v", err)
		}
		// 读取回复消息
		_, replyMessage, err := conn.ReadMessage()
		if err != nil {
			return fmt.Errorf("failed to read message: %v", err)
		}
		var replyMessageData map[string]interface{}
		err = json.Unmarshal([]byte(replyMessage), &replyMessageData)
		if err != nil {
			return fmt.Errorf("failed to send message: %v", err)
		}

		if replyMessageData["msgType"] == nil || replyMessageData["msgType"] != "MsgReceivedAck" {
			return fmt.Errorf("failed to send message: %v")
		}

		return nil

	} else {
		resp, err := h.Client.R().SetBody(&SendTextMsgReq{
			Wxid: wxid,
			Msg:  msg,
		}).Post("http://" + h.ServerIp + ":" + h.WxPort + "/SendTextMsg")
		if err != nil {
			return err
		}
		if !resp.IsSuccessState() {
			err = fmt.Errorf("SendTextMsg failed with status code %d", resp.StatusCode)
			return err
		}
		return nil
	}
}

// SendPicMsg 发送微信图片
func (h *Hook) SendPicMsg(wxid, picpath, diyfilename, wxWxid string) (err error) {
	if h.ServerIp == "" {
		conn, err := h.connWorkPhone()
		if err != nil {
			err = fmt.Errorf("SendPicMsg failed")
			return err
		}
		defer func(conn *websocket.Conn) {
			err = conn.Close()
			if err != nil {
				err = fmt.Errorf("SendPicMsg failed")
			}
		}(conn)
		encodedString := base64.StdEncoding.EncodeToString([]byte(picpath))
		contentType := "File"
		if isImageFile(diyfilename) {
			contentType = "Picture"
		}

		var message map[string]interface{}
		if h.Ctype == uint64(3) {
			message = map[string]interface{}{
				"MsgType": "TalkToFriendTask",
				"Content": map[string]interface{}{
					"WxId":        wxWxid,
					"ConvId":      wxid,
					"ContentType": contentType,
					"Content":     encodedString,
				},
			}
		} else {
			message = map[string]interface{}{
				"MsgType": "TalkToFriendTask",
				"Content": map[string]interface{}{
					"WeChatId":    wxWxid,
					"FriendId":    wxid,
					"ContentType": contentType,
					"Content":     encodedString,
				},
			}
		}

		transportMessageJSON, err := json.Marshal(message)
		if err != nil {
			return err
		}
		// 发送 JSON 消息
		err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
		if err != nil {
			return fmt.Errorf("failed to send message: %v", err)
		}
		// 读取回复消息
		_, replyMessage, err := conn.ReadMessage()
		if err != nil {
			return fmt.Errorf("failed to read message: %v", err)
		}
		var replyMessageData map[string]interface{}
		err = json.Unmarshal([]byte(replyMessage), &replyMessageData)
		if err != nil {
			return fmt.Errorf("failed to send message: %v", err)
		}
		if replyMessageData["msgType"] == nil || replyMessageData["msgType"] != workphone.EnumMsgType_name[int32(workphone.EnumMsgType_MsgReceivedAck)] {
			return fmt.Errorf("failed to send message: %v")
		}

		return nil
	} else {
		resp, err := h.Client.R().SetBody(&SendPicMsgReq{
			Wxid:        wxid,
			Picpath:     picpath,
			Diyfilename: diyfilename,
		}).Post("http://" + h.ServerIp + ":" + h.WxPort + "/SendPicMsg")
		if err != nil {
			return err
		}
		if !resp.IsSuccessState() {
			err = fmt.Errorf("SendPicMsg failed with status code %d", resp.StatusCode)
			return err
		}
		return nil
	}
}

// 发送微信图片（本地测试）
func (h *Hook) SendPicMsgLocal(wxid, picpath string) (err error) {
	resp, err := h.Client.R().SetBody(&SendPicMsgLocalReq{
		Wxid:    wxid,
		Picpath: picpath,
	}).Post("http://" + h.ServerIp + ":" + h.WxPort + "/SendPicMsg")
	if err != nil {
		return
	}
	if !resp.IsSuccessState() {
		err = fmt.Errorf("SendPicMsgLocal failed with status code %d", resp.StatusCode)
		return
	}
	return
}

func isImageFile(filename string) bool {
	ext := strings.ToLower(filepath.Ext(filename))
	imageExtensions := []string{".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp"}

	for _, extToCheck := range imageExtensions {
		if ext == extToCheck {
			return true
		}
	}
	return false
}
