package zhimeng

import (
	"applet/app/utils/logx"
	"encoding/json"
	"errors"
	"fmt"
	"strings"

	"github.com/shopspring/decimal"
	"github.com/tidwall/gjson"
)

// SDK is zm sdk
type SDK struct {
	Action    string
	operation string
	response  []byte
	SmsKey    string
	SmsSecret string
	data      interface{}
	err       error
}

// Init is init action
// In some condition, such as send Sms, need pass sms key and secret after 'action'
func (sdk *SDK) Init(action string, keys ...string) {
	sdk.Action = action
	//if keys[0] == "" || keys[1] == "" {
	//	sdk.err = errors.New("智盟短信未配置")
	//}
	if len(keys) > 1 {
		sdk.SmsKey = keys[0]
		sdk.SmsSecret = keys[1]
	}

}

// SelectFunction is select api with operation
func (sdk *SDK) SelectFunction(operation string) *SDK {
	sdk.operation = operation
	return sdk
}

// WithSMSArgs is SMS
func (sdk *SDK) WithSMSArgs(args map[string]interface{}) *SDK {
	res, err := SMSend(sdk.Action, sdk.operation, sdk.SmsKey, sdk.SmsSecret, args)
	if err != nil {
		logx.Error(err)
	}
	sdk.response = res
	return sdk
}

// WithArgs is post data to api
func (sdk *SDK) WithArgs(args map[string]interface{}) *SDK {
	// args["appkey"] = svc.SysCfgGet(c, md.KEY_CFG_ZM_AK)
	// args["secret_key"] = svc.SysCfgGet(c, md.KEY_CFG_ZM_SK)

	res, err := Send(sdk.Action, sdk.operation, args)
	if err != nil {
		logx.Error(err)
	}
	// for k, v := range args {
	// 	fmt.Printf("%s:%v \n", k, v)
	// }
	fmt.Println("唯品会请求", args, string(res))
	sdk.response = res
	return sdk
}

// Result is response data from api , return interface{}
func (sdk *SDK) Result() (*SDK, error) {
	if sdk.err != nil {
		return nil, sdk.err
	}
	tmp := struct {
		Msg     string      `json:"msg"`
		Success int         `json:"success"`
		Data    interface{} `json:"data"`
	}{}
	if err := json.Unmarshal(sdk.response, &tmp); err != nil {
		return nil, logx.Error("【Resp】" + string(sdk.response) + ", 【Error】" + err.Error())
	}
	if tmp.Success != StatusSuc {
		return nil, logx.Error(string(sdk.response))
	}

	if gjson.GetBytes(sdk.response, "data").String() == "[]" {
		return nil, errors.New("no result")
	}

	sdk.data = tmp.Data
	return sdk, nil
}

// ToInterface  is data  to Interface
func (sdk *SDK) ToInterface() interface{} {
	return sdk.data
}

// ToMapStringInterface is data to map[string]string
func (sdk *SDK) ToMapStringInterface(item interface{}) map[string]interface{} {
	data, err := json.Marshal(item)
	if err != nil {
		logx.Error("ToMapStringString marshal error : " + err.Error())

	}
	m := make(map[string]interface{})
	if err = json.Unmarshal(data, &m); err != nil {
		logx.Error("ToMapStringString unmarshal error : " + err.Error())

	}
	for key, v := range m {
		switch v.(type) {
		case int:
			t, ok := v.(string)
			if !ok {
				logx.Warn("int convert error")
			}
			m[key] = t
		case int32:
			t, ok := v.(string)
			if !ok {
				logx.Warn("int32 convert error")
			}
			m[key] = t
		case int64:
			t, ok := v.(string)
			if !ok {
				logx.Warn("int64 convert error")
			}
			m[key] = t
		case float64:
			vstr := fmt.Sprintf("%v", v)
			if strings.Contains(vstr, "e+") {
				decimalNum, err := decimal.NewFromString(vstr)
				if err != nil {
					panic(logx.Errorf("decimal.NewFromString error, vstr:%s, err:%v", vstr, err))
				}
				vstr = decimalNum.String()
			}
			m[key] = vstr
		case nil:
			m[key] = v
		default:
			m[key] = v
		}
	}
	return m
}
