package wechat

import (
	"encoding/json"
	"eta/eta_mini_api/models"
	"eta/eta_mini_api/services/alarm_msg"
	"eta/eta_mini_api/utils"
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	"github.com/silenceper/wechat/v2/credential"
	"github.com/silenceper/wechat/v2/officialaccount"
	"github.com/silenceper/wechat/v2/officialaccount/config"
	"github.com/silenceper/wechat/v2/officialaccount/js"
	"github.com/silenceper/wechat/v2/officialaccount/user"
)

var (
	WxAppId     string
	WxAppSecret string
)

type WechatAccessToken struct {
}

func GetWxChat() (officialAccount *officialaccount.OfficialAccount) {
	wc := wechat.NewWechat()
	memory := cache.NewMemory()
	conf := &config.Config{
		AppID:          utils.DW_WX_APPID,
		AppSecret:      utils.DW_WX_APP_SECRET,
		Token:          "",
		EncodingAESKey: "",
		Cache:          memory,
	}
	officialAccount = wc.GetOfficialAccount(conf)
	wechatAccessToken := &WechatAccessToken{}
	officialAccount.SetAccessTokenHandle(wechatAccessToken)
	return
}

var DefaultKey = "zcmRedis"

// GetAccessToken 获取accessToken
func (wechat WechatAccessToken) GetAccessToken() (accessToken string, err error) {
	wxToken, err := models.GetWxTokenById()
	if err != nil && err.Error() != utils.ErrNoRow() {
		return
	}
	//如果300s就要过期了,那么就去刷新accessToken
	if wxToken.ExpiresIn < time.Now().Unix()+300 {
		tmpAccessToken, expires, tmpErr := getTokenFromServer(utils.DW_WX_APPID, utils.DW_WX_APP_SECRET)
		if tmpErr != nil {
			err = tmpErr
			return
		}

		var updateCols = []string{"access_token", "expires_in"}
		wxToken.AccessToken = tmpAccessToken
		wxToken.ExpiresIn = time.Now().Unix() + expires - 600 //快过期前10分钟就刷新掉
		wxToken.Update(updateCols)
	}
	accessToken = wxToken.AccessToken
	return
}

// accessToken, err = utils.Redis.Get(context.TODO(), utils.CACHE_WX_ACCESS_TOKEN_DW).Result()
// // wxToken, err := models.GetWxTokenById()
// if err != nil && err != redis.Nil {
// 	return
// }

// models.GetWxTokenById()
// minConf, _ := models.GetMiniConf()
// // 缓存中没有取到数据,那么就需要强制刷新的accessToken
// tmpAccessToken, expires, tmpErr := getTokenFromServer(minConf["WxAppId"], minConf["WxAppSecret"])
//
//	if tmpAccessToken == "" {
//		err = errors.New("获取微信token失败,Err:" + tmpErr.Error())
//		return
//	}
//
// redisTimeExpire := time.Duration(expires-600) * time.Second
// err = utils.Redis.SetEX(context.TODO(), utils.CACHE_WX_ACCESS_TOKEN_DW, tmpAccessToken, redisTimeExpire).Err()
//
//	if err != nil {
//		return
//	}
//
// err = utils.Redis.HSet(context.TODO(), DefaultKey, utils.CACHE_WX_ACCESS_TOKEN_DW, true).Err()
// // err = utils.Redis.Put(utils.CACHE_WX_ACCESS_TOKEN_HZ, tmpAccessToken, redisTimeExpire)
//
//	if err != nil {
//		err = errors.New("更新微信token失败")
//		return
//	}
//
// return
// getTokenFromServer 服务端获取accessToken
func getTokenFromServer(appid, wxSecret string) (accessToken string, expires int64, err error) {
	apiUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
	resAccessToken, err := credential.GetTokenFromServer(fmt.Sprintf(apiUrl, appid, wxSecret))
	if err != nil {
		return
	}

	expires = resAccessToken.ExpiresIn
	accessToken = resAccessToken.AccessToken
	return
}

// GetUserInfo 获取微信用户详情
func GetUserInfo(openid string) (userInfo *user.Info, err error) {
	wechatClient := GetWxChat()
	userClient := wechatClient.GetUser()
	userInfo, err = userClient.GetUserInfo(openid)
	return
}

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

// GetJsConfig 获取公众号jsConfig
func GetJsConfig(signUrl string) (jsConf *js.Config, err error) {
	wechatClient := GetWxChat()
	j := wechatClient.GetJs()
	jsConf, err = j.GetConfig(signUrl)
	return
}

type WxUserInfo struct {
	OpenId       string `json:"openid"`
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	Scope        string `json:"scope"`
	ErrCode      int
	ErrMsg       string
}

func GetWxUserInfo(code string) (info *WxUserInfo, err error) {
	httpUrl := `https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code`

	httpUrl = fmt.Sprintf(httpUrl, utils.DW_WX_APPID, utils.DW_WX_APP_SECRET, code)

	client := http.Client{}
	wxReq, err := http.NewRequest("GET", httpUrl, nil)
	if err != nil {
		return
	}
	response, err := client.Do(wxReq)
	if err != nil {
		return
	}
	defer response.Body.Close()
	body, err := io.ReadAll(response.Body)
	if err != nil {
		return
	}
	alarm_msg.SendAlarmMsg(string(body), 1)
	if err = json.Unmarshal(body, &info); err != nil {
		return
	}
	return
}