package message

import (
	"errors"
	"gitee.ltd/lxh/xybot/base"
	"strings"
)

// RevokeMsg
// @description: 撤回消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param clientMsgId int 返回消息的MsgId字段
// @param createTime int 返回消息的CreateTime字段
// @param newMsgId int 返回消息的NewMsgId字段
// @return err
func (s service) RevokeMsg(toWxId string, clientMsgId, createTime, newMsgId int) (err error) {
	var result base.Response[base.EmptyResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":        s.robotInfo.GetId(),
			"ToWxid":      toWxId,
			"ClientMsgId": clientMsgId,
			"CreateTime":  createTime,
			"NewMsgId":    newMsgId,
		}).Post("/RevokeMsg")
	err = result.CheckError(err)
	return
}

// SendAppMsg
// @description: 发送App消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param xml string 消息XML
// @param appMsgType int APP消息类型
// @return clientMsgId int 返回消息的MsgId字段
// @return createTime int 返回消息的CreateTime字段
// @return newMsgId int 返回消息的NewMsgId字段
// @return err
func (s service) SendAppMsg(toWxId, xml string, appMsgType int) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":   s.robotInfo.GetId(),
			"ToWxid": toWxId,
			"Xml":    xml,
			"Type":   appMsgType,
		}).Post("/SendAppMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendCDNFileMsg
// @description: 发送CDN文件消息
// @receiver s
// @param toWxId
// @param xml
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendCDNFileMsg(toWxId, xml string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":    s.robotInfo.GetId(),
			"ToWxid":  toWxId,
			"Content": xml,
		}).Post("/SendCDNFileMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendCDNImgMsg
// @description: 发送CDN图片消息(转发图片消息)
// @receiver s
// @param toWxId
// @param xml
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendCDNImgMsg(toWxId, xml string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":    s.robotInfo.GetId(),
			"ToWxid":  toWxId,
			"Content": xml,
		}).Post("/SendCDNImgMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendCDNVideoMsg
// @description: 发送CDN视频消息(转发视频消息)
// @receiver s
// @param toWxId
// @param xml
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendCDNVideoMsg(toWxId, xml string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":    s.robotInfo.GetId(),
			"ToWxid":  toWxId,
			"Content": xml,
		}).Post("/SendCDNVideoMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendCardMsg
// @description: 发送名片消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param cardWxId string 名片微信ID
// @param cardNickname string 名片昵称
// @param cardAlias string 名片备注
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendCardMsg(toWxId, cardWxId, cardNickname, cardAlias string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":         s.robotInfo.GetId(),
			"ToWxid":       toWxId,
			"CardWxid":     cardWxId,
			"CardNickname": cardNickname,
			"CardAlias":    cardAlias,
		}).Post("/SendCardMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendEmojiMsg
// @description: 发送表情消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param md5 string 表情MD5
// @param length int 表情总长度
// @return resp
// @return err
func (s service) SendEmojiMsg(toWxId, md5 string, length int) (resp any, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":     s.robotInfo.GetId(),
			"ToWxid":   toWxId,
			"Md5":      md5,
			"TotalLen": length,
		}).Post("/SendEmojiMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	resp = result.Data
	return
}

// SendImageMsg
// @description: 发送图片消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param imgBase64Str string 图片Base64字符串
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendImageMsg(toWxId, imgBase64Str string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":   s.robotInfo.GetId(),
			"ToWxid": toWxId,
			"Base64": imgBase64Str,
		}).Post("/SendImageMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendShareLink
// @description: 发送分享链接消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param url string 跳转链接
// @param title string 标题
// @param description string 描述
// @param thumbUrl string 缩略图链接
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendShareLink(toWxId, url, title, description, thumbUrl string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":     s.robotInfo.GetId(),
			"ToWxid":   toWxId,
			"Url":      url,
			"Title":    title,
			"Desc":     description,
			"ThumbUrl": thumbUrl,
		}).Post("/SendShareLink")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendTextMsg
// @description: 发送文本消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param content string 消息内容,如果有@人,必须在消息内容显式输入,否则无效,@所有人传 @所有人
// @param atUser []string 被@的用户列表,toWxId为群聊的时候用,@所有人传`notify@all`
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendTextMsg(toWxId, content string, atUser []string) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":    s.robotInfo.GetId(),
			"ToWxid":  toWxId,
			"Content": content,
			"Type":    1,
			"At":      strings.Join(atUser, ","),
		}).Post("/SendTextMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendVideoMsg
// @description: 发送视频消息 不推荐使用,上传速度很慢300KB/s。如要使用,可压缩视频,或者发送链接卡片而不是视频。
// @receiver s
// @param toWxId string 接收者微信ID
// @param video string 视频base64字符串
// @param cover string 封面base64字符串
// @param duration int 视频时长,单位毫秒
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendVideoMsg(toWxId, video, cover string, duration int) (clientMsgId, createTime, newMsgId int, err error) {
	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":        s.robotInfo.GetId(),
			"ToWxid":      toWxId,
			"Base64":      video,
			"ImageBase64": cover,
			"PlayLength":  duration,
		}).Post("/SendVideoMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// SendVoiceMsg
// @description: 发送语音消息
// @receiver s
// @param toWxId string 接收者微信ID
// @param voice string 语音base64字符串
// @param format string 语音格式,支持amr/wav/mp3
// @param duration int 语音时长,单位毫秒
// @return clientMsgId
// @return createTime
// @return newMsgId
// @return err
func (s service) SendVoiceMsg(toWxId, voice, format string, duration int) (clientMsgId, createTime, newMsgId int, err error) {
	formatMap := map[string]int{"amr": 0, "wav": 4, "mp3": 4}
	if _, ok := formatMap[format]; !ok {
		err = errors.New("不支持的语音格式")
		return
	}

	var result base.Response[SendMessageResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":      s.robotInfo.GetId(),
			"ToWxid":    toWxId,
			"Base64":    voice,
			"VoiceTime": duration,
			"Type":      formatMap[format],
		}).Post("/SendVoiceMsg")
	if err = result.CheckError(err); err != nil {
		return
	}
	clientMsgId = result.Data.MsgId
	createTime = result.Data.CreateTime
	newMsgId = result.Data.NewMsgId
	return
}

// Sync
// @description: 同步消息
// @receiver s
// @return msg
// @return err
func (s service) Sync() (msg []SyncMessage, err error) {
	var result base.Response[SyncResponse]
	_, err = s.client.R().
		SetHeader("WeChatId", s.robotInfo.GetId()).
		SetResult(&result).
		SetBody(map[string]any{
			"Wxid":    s.robotInfo.GetId(),
			"Scene":   0,
			"Synckey": "",
		}).Post("/Sync")
	if err = result.CheckError(err); err != nil {
		return
	}

	msg = result.Data.AddMsgs
	return
}