package models

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/rdlucklib/rdluck_tools/http"
	"hongze/hz_crm_api/utils"
	"strings"
	"time"
)

type WxToken struct {
	AccessToken string
	ExpiresIn   int64
	Id          int64
}

func GetWxAccessToken() (accessTokenStr string, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM wx_token LIMIT 1`
	wxToken := new(WxToken)
	err = o.Raw(sql).QueryRow(&wxToken)
	if err != nil && err.Error() != utils.ErrNoRow() {
		utils.FileLog.Info("Get wxToken Err:", err.Error())
		return
	}
	//Token不存在
	if wxToken == nil {
		fmt.Println("wxToken is empty")
		accessToken, err := GetWxToken(utils.WxAppId, utils.WxAppSecret)
		if err != nil {
			return "", err
		}
		if accessToken.AccessToken != "" {
			expiresIn := time.Now().Add(time.Duration(accessToken.ExpiresIn) * time.Second).Unix()
			addSql := "insert into wx_token (access_token,expires_in) values (?,?)"
			_, err = o.Raw(addSql, accessToken.AccessToken, expiresIn).Exec()
			accessTokenStr = accessToken.AccessToken
		}
		return accessTokenStr, err
	} else {
		//判断token是否过期
		if time.Now().Unix() > wxToken.ExpiresIn {
			accessToken, err := GetWxToken(utils.WxAppId, utils.WxAppSecret)
			if err != nil {
				return "", err
			}
			if accessToken.AccessToken != "" {
				expiresIn := time.Now().Add(time.Duration(accessToken.ExpiresIn) * time.Second).Unix()
				updateSql := "update wx_token set access_token = ?,expires_in = ? "
				_, err = o.Raw(updateSql, accessToken.AccessToken, expiresIn).Exec()
				accessTokenStr = accessToken.AccessToken
				fmt.Println("更新 TOKEN:", err)
			}
			return accessTokenStr, err
		} else {
			return wxToken.AccessToken, nil
		}
	}
	return
}

type WxAccessToken struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
	Errcode     int    `json:"errcode"`
	Errmsg      string `json:"errmsg"`
}

func GetWxToken(wxAppId, wxAppSecret string) (item *WxAccessToken, err error) {
	getUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxAppId + "&secret=" + wxAppSecret
	result, err := http.Get(getUrl)
	if err != nil {
		utils.FileLog.Info("GetWxToken Err:", err.Error())
		return
	}
	err = json.Unmarshal(result, &item)
	if err != nil {
		fmt.Println(fmt.Sprintf("GetWxToken Unmarshal Err:%s", err.Error()))
		return
	}
	if item.Errmsg != "" {
		utils.FileLog.Info(fmt.Sprintf("GetWxToken fail result:%s", string(result)))
	}
	return
}

type WxUsers struct {
	WxBase
	Total int
	Count int
	Data  struct {
		Openid []string
	}
	NextOpenid string `json:"next_openid"`
}

// 微信接口基础返回数据
type WxBase struct {
	Errcode int
	Errmsg  string
}

func WxUsersGet() (openIdStr string) {
	accessToken, err := GetWxAccessToken()
	if err != nil {
		utils.FileLog.Info("GetWxAccessToken Err:%s", err.Error())
		return
	}

	//关注的openid切片
	openIdList := make([]string, 0)
	//下一个openid
	nextOpenid := ""

QUERY_WX:
	url := "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken + "&next_openid=" + nextOpenid
	result, err := http.Get(url)
	if err != nil {
		utils.FileLog.Info("GetUser Err:", err.Error())
		return
	}
	item := new(WxUsers)
	err = json.Unmarshal(result, &item)
	if err != nil {
		fmt.Println("Unmarshal Err:", err.Error())
		return
	}
	if item.Errcode != 0 {
		utils.FileLog.Info("微信接口返回异常 Err：", item.Errmsg)
		return
	}
	err = errors.New(item.Errmsg)

	openIdList = append(openIdList, item.Data.Openid...)

	//如果数量大于10000条，同时下个openid不为空，那么继续查询
	if item.Count >= 10000 && item.NextOpenid != "" {
		nextOpenid = item.NextOpenid
		goto QUERY_WX
	}

	openIdStr = strings.Join(openIdList, "','")
	openIdStr = "'" + openIdStr + "'"
	return
}

func GetWxAccessTokenByXzs() (accessTokenStr string, err error) {
	if utils.RunMode == "release" {
		cacheKey := "xygxxzs_wxtoken"
		accessTokenStr, _ = utils.Rc.RedisString(cacheKey)
		if accessTokenStr != "" {
			return
		} else {
			WxAccessToken, errWx := GetWxTokenByXzs()
			if errWx != nil {
				err = errWx
				return
			}
			accessTokenStr = WxAccessToken.AccessToken
			utils.Rc.Put(cacheKey, WxAccessToken.AccessToken, time.Second*7000)
		}
	} else {
		accessTokenStr, err = GetWxAccessToken()
		if err != nil {
			return
		}
	}
	return
}

// 获取小助手的微信Token
func GetWxTokenByXzs() (item *WxAccessToken, err error) {
	getUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + utils.WxPublicIdXzs + "&secret=" + utils.WxPublicSecretXzs
	result, err := http.Get(getUrl)
	if err != nil {
		return
	}
	err = json.Unmarshal(result, &item)
	if err != nil {
		fmt.Println("GetWxToken Unmarshal Err:%s", err.Error())
		return
	}
	if item.Errmsg != "" {
		utils.FileLog.Info("GetWxToken fail result:%s", string(result))
		err = fmt.Errorf(item.Errmsg)
	}
	return
}

func WxUsersGetV1() (openIdList []string) {
	accessToken, err := GetWxAccessToken()
	if err != nil {
		utils.FileLog.Info("GetWxAccessToken Err:%s", err.Error())
		return nil
	}

	//关注的openid切片
	openIdList = make([]string, 0)
	//下一个openid
	nextOpenid := ""

QUERY_WX:
	url := "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken + "&next_openid=" + nextOpenid
	result, err := http.Get(url)
	if err != nil {
		utils.FileLog.Info("GetUser Err:", err.Error())
		return
	}
	item := new(WxUsers)
	err = json.Unmarshal(result, &item)
	if err != nil {
		fmt.Println("Unmarshal Err:", err.Error())
		return
	}
	if item.Errcode != 0 {
		utils.FileLog.Info("微信接口返回异常 Err：", item.Errmsg)
		return
	}
	err = errors.New(item.Errmsg)

	openIdList = append(openIdList, item.Data.Openid...)

	//如果数量大于10000条，同时下个openid不为空，那么继续查询
	if item.Count >= 10000 && item.NextOpenid != "" {
		nextOpenid = item.NextOpenid
		goto QUERY_WX
	}
	return openIdList
}
