package wx_app

import (
	"errors"
	"fmt"
	wechat "github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	"github.com/silenceper/wechat/v2/miniprogram"
	"github.com/silenceper/wechat/v2/miniprogram/auth"
	"github.com/silenceper/wechat/v2/miniprogram/config"
	"github.com/silenceper/wechat/v2/miniprogram/encryptor"
	"github.com/silenceper/wechat/v2/miniprogram/qrcode"
	"github.com/silenceper/wechat/v2/util"
	"hongze/hongze_yb/global"
	"hongze/hongze_yb/models/tables/yb_config"
	"hongze/hongze_yb/services/wx_app/security"
	"hongze/hongze_yb/utils"
)

// 微信小程序配置信息
var (
	WxId                 string //微信原始ID
	WxAppId              string
	WxAppSecret          string
	WxPlatform           int    //用户来源,需要入库,用来保存该用户来自哪个平台,默认是:1
	EnvVersion           string // 小程序版本, release-正式版; trial-体验版; develop-开发版
	SendWxTemplateMsgUrl string
)

func init() {
	WxAppId = `wxb059c872d79b9967`
	WxId = `gh_75abb562a946`
	WxAppSecret = `1737c73e9f69a21de1a345b8f0800258`
	WxPlatform = 6 //弘则研报来源
	if global.CONFIG.Serve.RunMode == "release" {
		EnvVersion = "release"
		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
	} else {
		EnvVersion = "trial"
		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
	}
}

// 注: 研报小程序及备用小程序在同时运行, 基础微信API通过前端请求Header判断来源
// 模板消息等API则用配置控制具体使用哪一个小程序, 同一时间仅一个小程序可推消息
func GetWxApp(copyYb string) (mp *miniprogram.MiniProgram) {
	wc := wechat.NewWechat()
	memory := cache.NewMemory()
	//memory := cache.NewRedis(global.Redis)

	mp = new(miniprogram.MiniProgram)

	appConf := getWxAppConfByRequest(copyYb)

	cfg := &config.Config{
		AppID:     appConf.WxAppId,
		AppSecret: appConf.WxAppSecret,
		Cache:     memory,
	}

	mp = wc.GetMiniProgram(cfg)
	return
}

// GetSession 获取用户详情
func GetSession(code, copyYb string) (userInfo auth.ResCode2Session, err error) {
	wechatClient := GetWxApp(copyYb)
	authClient := wechatClient.GetAuth()
	userInfo, err = authClient.Code2Session(code)
	return
}

// 获取解密信息 GetDecryptInfo
func GetDecryptInfo(sessionKey, encryptedData, iv, copyYb string) (decryptData *encryptor.PlainData, err error) {
	wechatClient := GetWxApp(copyYb)
	encryptorClient := wechatClient.GetEncryptor()
	decryptData, err = encryptorClient.Decrypt(sessionKey, encryptedData, iv)
	return
}

// 微信小程序新版code获取手机号
const (
	getPhoneNumberURL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s"
)

type GetPhoneNumberResponse struct {
	util.CommonError
	PhoneInfo PhoneInfo `json:"phone_info"`
}

type PhoneInfo struct {
	PhoneNumber     string `json:"phoneNumber"`     // 用户绑定的手机号
	PurePhoneNumber string `json:"purePhoneNumber"` // 没有区号的手机号
	CountryCode     string `json:"countryCode"`     // 区号
	WaterMark       struct {
		Timestamp int64  `json:"timestamp"`
		AppID     string `json:"appid"`
	} `json:"watermark"` // 数据水印
}

func GetPhoneNumber(code, copyYb string) (result GetPhoneNumberResponse, err error) {
	var response []byte
	var (
		at string
	)
	wechatClient := GetWxApp(copyYb)
	authClient := wechatClient.GetAuth()
	if at, err = authClient.GetAccessToken(); err != nil {
		return
	}
	body := map[string]interface{}{
		"code": code,
	}
	if response, err = util.PostJSON(fmt.Sprintf(getPhoneNumberURL, at), body); err != nil {
		return
	}
	if err = util.DecodeWithError(response, &result, "phonenumber.getPhoneNumber"); err != nil {
		return
	}
	return
}

// GetSunCode 获取太阳码
func GetSunCode(page, scene, copyYb string) (resp []byte, err error) {
	codePars := qrcode.QRCoder{
		Page:       page,
		Scene:      scene,
		EnvVersion: EnvVersion,
	}
	wechatClient := GetWxApp(copyYb)
	qr := wechatClient.GetQRCode()
	return qr.GetWXACodeUnlimit(codePars)
}

// MsgSecCheck 检查一段文本是否含有违法违规内容。
func MsgSecCheck(openid, content, copyYb string) (result security.Result, err error) {
	wechatClient := GetWxApp(copyYb)
	myMiniprogram := security.NewMyMiniprogram(wechatClient)
	bodyContent := &security.BodyContent{
		Version: 2,
		Content: content,
		Openid:  openid,
		Scene:   2,
	}
	return myMiniprogram.MsgSecCheckWithResult(bodyContent)
}

type WxAppConf struct {
	WxId              string `description:"微信原始ID"`
	WxAppId           string
	WxAppSecret       string
	WxPlatform        int `description:"app来源: 6-研报小程序; 9-研报备用小程序"`
	MsgRedirectTarget int `description:"公共模板消息跳转类型:1-研报小程序; 4-备用研报小程序"`
}

// GetWxAppConf 获取小程序配置
func GetWxAppConf() (appConf *WxAppConf, err error) {
	// 根据配置选择小程序
	conf, e := yb_config.GetConfigByCode(yb_config.KeyUseCopyYb)
	if e != nil {
		err = errors.New("获取小程序配置失败, Err: " + e.Error())
		return
	}
	appConf = getWxAppConfByRequest(conf.ConfigValue)
	return
}

func getWxAppConfByRequest(copyYb string) *WxAppConf {
	appConf := &WxAppConf{
		WxId:              `gh_75abb562a946`,
		WxAppId:           `wxb059c872d79b9967`,
		WxAppSecret:       `1737c73e9f69a21de1a345b8f0800258`,
		WxPlatform:        utils.USER_RECORD_PLATFORM_YB,
		MsgRedirectTarget: 1,
	}
	// 备用小程序
	if copyYb == "true" {
		appConf.WxAppId = `wx9a2a9b49a00513a0`
		appConf.WxAppSecret = `4dea76ad9482bdd4e71cf305f669d09f`
		appConf.WxPlatform = utils.USER_RECORD_PLATFORM_COPY_YB
		appConf.MsgRedirectTarget = 4
	}
	return appConf
}

// GetSunCode 获取太阳码
func GetSunCodeV2(page string) (resp []byte, err error) {
	codePars := qrcode.QRCoder{
		Path:       page,
		EnvVersion: EnvVersion,
		Width:      256,
	}
	wechatClient := GetWxApp("false")
	qr := wechatClient.GetQRCode()
	return qr.GetWXACode(codePars)
}