package utils

import (
	"applet/app/cfg"
	"applet/app/utils/logx"
	"fmt"
	"github.com/forgoer/openssl"
	"github.com/gin-gonic/gin"
	"github.com/syyongx/php2go"
	"strings"
	"time"
)

var publicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFQD7RL2tDNuwdg0jTfV0zjAzh
WoCWfGrcNiucy2XUHZZU2oGhHv1N10qu3XayTDD4pu4sJ73biKwqR6ZN7IS4Sfon
vrzaXGvrTG4kmdo3XrbrkzmyBHDLTsJvv6pyS2HPl9QPSvKDN0iJ66+KN8QjBpw1
FNIGe7xbDaJPY733/QIDAQAB
-----END PUBLIC KEY-----`)

var privateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCFQD7RL2tDNuwdg0jTfV0zjAzhWoCWfGrcNiucy2XUHZZU2oGh
Hv1N10qu3XayTDD4pu4sJ73biKwqR6ZN7IS4SfonvrzaXGvrTG4kmdo3Xrbrkzmy
BHDLTsJvv6pyS2HPl9QPSvKDN0iJ66+KN8QjBpw1FNIGe7xbDaJPY733/QIDAQAB
AoGADi14wY8XDY7Bbp5yWDZFfV+QW0Xi2qAgSo/k8gjeK8R+I0cgdcEzWF3oz1Q2
9d+PclVokAAmfj47e0AmXLImqMCSEzi1jDBUFIRoJk9WE1YstE94mrCgV0FW+N/u
+L6OgZcjmF+9dHKprnpaUGQuUV5fF8j0qp8S2Jfs3Sw+dOECQQCQnHALzFjmXXIR
Ez3VSK4ZoYgDIrrpzNst5Hh6AMDNZcG3CrCxlQrgqjgTzBSr3ZSavvkfYRj42STk
TqyX1tQFAkEA6+O6UENoUTk2lG7iO/ta7cdIULnkTGwQqvkgLIUjk6w8E3sBTIfw
rerTEmquw5F42HHE+FMrRat06ZN57lENmQJAYgUHlZevcoZIePZ35Qfcqpbo4Gc8
Fpm6vwKr/tZf2Vlt0qo2VkhWFS6L0C92m4AX6EQmDHT+Pj7BWNdS+aCuGQJBAOkq
NKPZvWdr8jNOV3mKvxqB/U0uMigIOYGGtvLKt5vkh42J7ILFbHW8w95UbWMKjDUG
X/hF3WQEUo//Imsa2yECQHSZIpJxiTRueoDiyRt0LH+jdbYFUu/6D0UIYXhFvP/p
EZX+hfCfUnNYX59UVpRjSZ66g0CbCjuBPOhmOD+hDeQ=
-----END RSA PRIVATE KEY-----`)

func GetApiVersion(c *gin.Context) int {
	var apiVersion = c.GetHeader("apiVersion")
	if StrToInt(apiVersion) == 0 { //没有版本号先不校验
		apiVersion = c.GetHeader("Apiversion")
	}
	if StrToInt(apiVersion) == 0 { //没有版本号先不校验
		apiVersion = c.GetHeader("api_version")
	}
	if StrToInt(apiVersion) == 0 { //没有版本号先不校验
		apiVersion = c.GetString("apiVersion")
	}
	if StrToInt(apiVersion) == 0 {
		platform := c.GetHeader("platform")
		if InArr(platform, []string{"ios", "android"}) == false && c.GetString("h5_applet_must_sign") == "1" {
			apiVersion = "1"
		}
		if InArr(platform, []string{"android"}) && c.GetString("android_must_sign") == "1" {
			apiVersion = "1"
		}
		if InArr(platform, []string{"ios"}) && c.GetString("ios_must_sign") == "1" {
			apiVersion = "1"
		}
	}
	if c.GetString("api_version") == "1" && cfg.Prd {
		apiVersion = "1"
	}
	if (strings.Contains(c.Request.Host, "zhios-app") || strings.Contains(c.Request.Host, "api.zhios.cn")) && apiVersion == "1" {
		apiVersion = "0"
		c.Set("api_version", "0")
	}

	//if InArr(c.GetHeader("platform"), []string{"ios", "android"}) {
	//	apiVersion = "0"
	//}
	var uri = c.Request.RequestURI
	if InArr(c.GetHeader("platform"), []string{"ios", "android", "pc"}) { //不用签名的接口
		var filterList = []string{
			"/api/v1/appcheck",
			"/api/v1/app/guide",
			"/api/v1/new/config.json",
			"pub.flutter.web_download_page",
		}
		for _, v := range filterList {
			if strings.Contains(uri, v) {
				apiVersion = "0"
			}
		}
	}
	return StrToInt(apiVersion)
}
func CheckUri(c *gin.Context) int {
	apiVersion := "1"
	//var uri = c.Request.RequestURI
	if InArr(c.GetHeader("platform"), []string{"ios", "android"}) { //不用签名的接口
		//var filterList = []string{
		//	"/api/v1/appcheck",
		//	"/api/v1/app/guide",
		//	"/api/v1/new/config.json",
		//	"api/v1/rec",
		//	"api/v1/custom/mod/",
		//	"api/v1/mod/",
		//	"api/v1/s/",
		//}
		//for _, v := range filterList {
		//	if strings.Contains(uri, v) {
		//		apiVersion = "0"
		//	}
		//}
		apiVersion = "0"
	}
	if c.GetHeader("mp") == "jd" {
		apiVersion = "0"
	}
	return StrToInt(apiVersion)
}

// 签名校验
func SignCheck(c *gin.Context) bool {
	var apiVersion = GetApiVersion(c)
	if apiVersion == 0 { //没有版本号先不校验
		return true
	}
	//1.通过rsa 解析出 aes
	var key = c.GetHeader("key")

	//拼接对应参数
	var uri = c.Request.RequestURI
	var query = GetQueryParam(uri)
	fmt.Println(query)
	query["timestamp"] = c.GetHeader("timestamp")
	query["nonce"] = c.GetHeader("nonce")
	query["key"] = key
	token := c.GetHeader("Authorization")
	if token != "" {
		// 按空格分割
		parts := strings.SplitN(token, " ", 2)
		if len(parts) == 2 && parts[0] == "Bearer" {
			token = parts[1]
		}
	}
	query["token"] = token
	//2.query参数按照 ASCII 码从小到大排序
	str := JoinStringsInASCII(query, "&", false, false, "")
	//3.拼上密钥
	secret := ""
	if InArr(c.GetHeader("platform"), []string{"android", "ios"}) {
		secret = c.GetString("app_api_secret_key")
	} else if c.GetHeader("platform") == "wap" {
		secret = c.GetString("h5_api_secret_key")
	} else {
		secret = c.GetString("applet_api_secret_key")
	}

	str = fmt.Sprintf("%s&secret=%s", str, secret)
	fmt.Println(str)
	//4.md5加密 转小写
	sign := strings.ToLower(Md5(str))
	//5.判断跟前端传来的sign是否一致
	if sign != c.GetHeader("sign") {
		return false
	}

	if StrToInt64(query["timestamp"])/1000 < time.Now().Unix()-300 {
		fmt.Println("============" + query["timestamp"])
		return false
	}
	//if query["nonce"] != "" {
	//	//TODO s
	//	getString, err := cache.GetString(query["nonce"])
	//	if err != nil {
	//		fmt.Println("nonce", err)
	//	}
	//	if getString != "" {
	//		fmt.Println("nonce", "============"+getString)
	//		return false
	//	} else {
	//		cache.SetEx(query["nonce"], "1", 300)
	//	}
	//}
	return true
}

func ResultAes(c *gin.Context, raw []byte) string {
	var key = c.GetHeader("key")
	base, _ := php2go.Base64Decode(key)
	aes, err := RsaDecrypt([]byte(base), privateKey)
	if err != nil {
		logx.Info(err)
		return ""
	}
	fmt.Println("============aes============")
	fmt.Println(string(aes))
	fmt.Println(string(raw))
	str, _ := openssl.AesECBEncrypt(raw, aes, openssl.PKCS7_PADDING)
	value := php2go.Base64Encode(string(str))
	fmt.Println(value)

	return value
}

func ResultAesDecrypt(c *gin.Context, raw string) string {
	var key = c.GetHeader("key")
	if key == "" {
		key = c.GetHeader("Key")
	}
	fmt.Println("验签", key)
	base, _ := php2go.Base64Decode(key)
	aes, err := RsaDecrypt([]byte(base), privateKey)
	if err != nil {
		logx.Info(err)
		return ""
	}
	raw = strings.ReplaceAll(raw, "\"", "")
	fmt.Println(raw)
	value1, _ := php2go.Base64Decode(raw)
	if value1 == "" {
		return ""
	}
	str1, _ := openssl.AesECBDecrypt([]byte(value1), aes, openssl.PKCS7_PADDING)
	fmt.Println("==========解码=========")
	fmt.Println(string(str1))
	return string(str1)
}
