package q_bida

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi"
	"git.rosy.net.cn/baseapi/utils"
	"net/http"
	"sync"
	"time"
)

type Api struct {
	token          string // 登录凭证
	expirationTime int64  // 过期时间
	account        string // 账号
	password       string // 密码
	locker         sync.RWMutex
	client         *http.Client
	config         *platformapi.APIConfig
}

// SetToken 设置token
func (a *Api) SetToken(token string) {
	a.locker.Lock()
	defer a.locker.Unlock()
	a.token = token
}

// SetExpirationTime 设置过期时间
func (a *Api) SetExpirationTime(expiration int64) {
	a.locker.Lock()
	defer a.locker.Unlock()
	a.expirationTime = expiration
}

// NewQBiDa 初始化token
func NewQBiDa(account, password string, config ...*platformapi.APIConfig) *Api {
	if account == "" || password == "" {
		account = "18048531223"
		password = "18080188338"
		//panic("账号密码不能为空")
	}
	// 获取token，设置token和过期时间
	curConfig := platformapi.DefAPIConfig
	if len(config) > 0 {
		curConfig = *config[0]
	}
	api := &Api{
		token:          "",
		expirationTime: 0,
		account:        account,
		password:       password,
		locker:         sync.RWMutex{},
		client:         &http.Client{Timeout: curConfig.ClientTimeout},
		config:         &curConfig,
	}
	if err := api.CheckTokenExpiration(); err != nil {
		fmt.Println(err)
	}

	return api
}

// CheckTokenExpiration 检查token是否存在，或者是否过期
func (a *Api) CheckTokenExpiration() error {
	if a.account == "" || a.password == "" {
		return errors.New("账号或者密码为空")
	}

	// 获取token NewQBiDa
	if a.token == "" || a.expirationTime < time.Now().Unix() {
		return a.GetToken()
	}

	return nil
}

// AccessInfo 发送请求
func (a *Api) AccessInfo(baseUrl, url, requestMethods string, param map[string]interface{}) (retVal map[string]interface{}, err error) {
	err = platformapi.AccessPlatformAPIWithRetry(a.client,
		func() *http.Request {
			var request *http.Request
			if requestMethods == http.MethodPost {
				fullURL := utils.GenerateGetURL(baseUrl, url, nil)
				// 获取json结构体的参数体
				requestBody := new(bytes.Buffer)
				json.NewEncoder(requestBody).Encode(param)
				// 发送请求
				request, _ = http.NewRequest(http.MethodPost, fullURL, requestBody)
				request.Header.Set("Content-Type", "application/json")
			} else {
				request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, url, param), nil)
			}
			if url != LogInUrl {
				request.Header.Set("token", a.token)
			}
			return request
		},
		a.config,
		func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
			if jsonResult1 == nil {
				return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
			}
			retVal = jsonResult1
			if jsonResult1["code"] == nil {
				return platformapi.ErrLevelGeneralFail, fmt.Errorf("返回结果格式不正常")
			}
			code := int(utils.MustInterface2Int64(jsonResult1["code"]))
			if code == ResponseCodeSuccess {
				retVal, _ = jsonResult1["data"].(map[string]interface{})
				return platformapi.ErrLevelSuccess, nil
			}
			newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code)
			return platformapi.ErrLevelCodeIsNotOK, newErr
		})
	return retVal, err
}
