package models

import (
	"encoding/json"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/rdlucklib/rdluck_tools/http"
	"hongze/hongze_cygx/utils"
	"io/ioutil"
	netHttp "net/http"
	"strconv"
	"strings"
	"time"
)

type WxLoginReq struct {
	Code string `description:"微信code"`
}

type WxToken struct {
	AccessToken string
	ExpiresIn   int64
	Id          int64
}

type SenceRule struct {
	Scene     string `json:"scene"`
	Page      string `json:"page,omitempty"`
	Width     int    `json:"width,omitempty"`
	AutoColor bool   `json:"auto_color,omitempty"`
	LineColor string `json:"line_color,omitempty"`
	IsHyaline bool   `json:"is_hyaline,omitempty"`
}

// BufferRule 图片buffer
type BufferRule struct {
	Buffer []byte `json:"Buffer"`
}

// ReturnBodyRule 微信返回通过结果集
type ReturnBodyRule struct {
	ErrorCode    int    `json:"errcode,omitempty"`
	ErrorMessage string `json:"errmsg,omitempty"`
}

func GetWxAccessToken() (accessTokenStr string, err error) {
	o := orm.NewOrmUsingDB("weekly_report")
	sql := `SELECT * FROM wx_token LIMIT 1`
	wxToken := new(WxToken)
	err = o.Raw(sql).QueryRow(&wxToken)
	if err != nil && err.Error() != utils.ErrNoRow() {
		return
	}
	//Token不存在
	if wxToken == nil {
		fmt.Println("wxToken is empty")
		accessToken, err := GetWxToken()
		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()
			fmt.Println(accessToken)
			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
}

func GetWxToken() (item *WxAccessToken, err error) {
	getUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + utils.WxPublicAppId + "&secret=" + utils.WxPublicAppSecret
	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 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
}

type WxAccessToken struct {
	AccessToken  string `json:"access_token"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	Openid       string `json:"openid"`
	Unionid      string `json:"unionid"`
	Scope        string `json:"scope"`
	Errcode      int    `json:"errcode"`
	Errmsg       string `json:"errmsg"`
}

type WxUsers struct {
	Total int
	Count int
	Data  struct {
		Openid []string
	}
	NextOpenid string
}

func WxUsersGet() (openIdStr string) {
	accessToken, err := GetWxAccessToken()
	if err != nil {
		utils.FileLog.Info("GetWxAccessToken Err:%s", err.Error())
		return
	}
	url := "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken
	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
	}
	openIdStr = strings.Join(item.Data.Openid, "','")
	openIdStr = "'" + openIdStr + "'"
	utils.FileLog.Info("openIdStr:%s", openIdStr)
	return
}

type WxCheckContentJson struct {
	Detail  []WxCheckContentJsonDetail `json:"detail"`
	Errcode int                        `json:"errcode"`
	Errmsg  string                     `json:"errmsg"`
	Result  WxCheckContentJsonResult   `json:"result"`
}

type WxCheckContentJsonDetail struct {
	Label    int
	KeyWord  string
	Prob     int
	Strategy string
	Errcode  int
}
type WxCheckContentJsonResult struct {
	Suggest string
	Label   int
}

func WxCheckContent(token, openId, content string) (suggest string) {
	url := "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + token
	fmt.Println(url)
	//result, err := http.Post(url, content)
	//if err != nil {
	//	utils.FileLog.Info("GetUser Err:", err.Error())
	//	return
	//}
	method := "POST"
	payload := strings.NewReader(`{
		"openid":"` + openId + `",
		"scene":` + strconv.Itoa(2) + `,
		"version":` + strconv.Itoa(2) + `,
		"content":"` + content + `"
				}`)
	client := &netHttp.Client{}
	req, err := netHttp.NewRequest(method, url, payload)
	if err != nil {
		return
	}
	req.Header.Add("Content-Type", "application/json")
	postBody, err := client.Do(req)
	if err != nil {
		return
	}
	defer postBody.Body.Close()
	body, err := ioutil.ReadAll(postBody.Body)
	if err != nil {
		fmt.Println(err)
		utils.FileLog.Info(err.Error())
		return
	}
	item := new(WxCheckContentJson)
	err = json.Unmarshal(body, &item)
	if err != nil {
		fmt.Println("Unmarshal Err:", err.Error())
		return
	}
	fmt.Println(item.Result.Label)
	fmt.Println(item.Result.Suggest)
	suggest = item.Result.Suggest
	return
}
