package utils

import (
	"applet/app/cfg"
	"encoding/json"
	"errors"
	"fmt"
	"sort"
	"time"
)

// 调用开放平台的封装
type OpenPlatformReqClient struct {
	AppKey     string
	AppSecret  string
	Method     string
	Version    string
	Timestamp  string
	Nonce      string
	Sign       string
	BizData    map[string]interface{}
	params     map[string]string
	ReturnData ReturnDataResp
}

type ReturnDataResp struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

func NewOpenPlatformReqClient(appKey, method, version, appSecret string, bizData map[string]interface{}) (*OpenPlatformReqClient, error) {
	if appKey == "" || appSecret == "" || method == "" || version == "" {
		return nil, errors.New("appKey,method,version not allow empty")
	}
	nowStr := AnyToString(time.Now().Unix())
	nonce := UUIDString()
	return &OpenPlatformReqClient{
		AppKey:    appKey,
		AppSecret: appSecret,
		Method:    method,
		Version:   version,
		Nonce:     nonce,
		Timestamp: nowStr,
		params:    map[string]string{"app_key": appKey, "method": method, "version": version, "timestamp": nowStr, "nonce": nonce},
		BizData:   bizData,
	}, nil
}

func (client *OpenPlatformReqClient) CurlOpen() error {
	if client.params == nil {
		return errors.New("params not allow empty")
	}
	url := cfg.ZhiosOpen.URL + "/api/open/gw"
	fmt.Printf("%#v\n", string(Serialize(client.params)))
	resp, err := CurlPost(url, Serialize(client.params), nil)
	if err != nil {
		return err
	}
	err = json.Unmarshal(resp, &client.ReturnData)
	if err != nil {
		return err
	}
	return nil
}

/*func (client *OpenPlatformReqClient) CreateParams() *OpenPlatformReqClient {
	client.params["timestamp"] = client.Timestamp
	client.params["nonce"] = client.Nonce
	//client.params["biz_data"] = SerializeStr(client.BizData)
	return client
}*/

func (client *OpenPlatformReqClient) SetBizDataToParams() *OpenPlatformReqClient {
	client.params["biz_data"] = SerializeStr(client.BizData)
	return client
}

func (client *OpenPlatformReqClient) SetParams(key, value string) *OpenPlatformReqClient {
	client.params[key] = value
	return client
}

func (client *OpenPlatformReqClient) GetParams(key string) string {
	return client.params[key]
}

func (client *OpenPlatformReqClient) CreateSign() *OpenPlatformReqClient {
	/*if client.BizData != nil {
		for key := range client.BizData {
			client.params[key] = AnyToString2(client.BizData[key])
		}
	}*/
	var keys []string
	for key := range client.params {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	str := ""
	for _, key := range keys {
		str += fmt.Sprintf("%v=%v&", key, client.params[key])
	}
	str = client.AppSecret + str[:len(str)-1] + client.AppSecret
	fmt.Printf("sign: %s\n", str)
	client.Sign = Md5(str)
	client.params["sign"] = client.Sign
	if client.BizData != nil {
		for key := range client.BizData {
			if _, ok := client.params[key]; ok {
				delete(client.params, key)
			}
		}
	}
	return client
}

func (client *OpenPlatformReqClient) VerifySign(sign string) bool {
	if sign == "" || client.Sign == "" {
		return false
	}
	if client.Sign == sign {
		return true
	}
	return false
}

func (client *OpenPlatformReqClient) ResetNonce() *OpenPlatformReqClient {
	client.Nonce = UUIDString()
	return client
}

func (client *OpenPlatformReqClient) ResetTimestamp() *OpenPlatformReqClient {
	client.Timestamp = AnyToString(time.Now().Unix())
	return client
}