package tiktok_api

import (
	"encoding/json"
	"errors"
	doudian_sdk "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/core"
	"git.rosy.net.cn/jx-callback/globals"
	"sync"
	"time"
)

type API struct {
	appKey         string
	appSecret      string
	accessToken    string
	refreshToken   string
	expiresIn      int64 // 当前时间的七天内为有效期
	locker         sync.RWMutex
	accessTokenObj *doudian_sdk.AccessToken // 存储数据库
}

func New(appKey, appSecret, accessToken string) *API {
	var access *doudian_sdk.AccessToken
	doudian_sdk.GlobalConfig.AppKey = appKey
	doudian_sdk.GlobalConfig.AppSecret = appSecret
	if accessToken != "" {
		if err := json.Unmarshal([]byte(accessToken), &access); err != nil {
			globals.SugarLogger.Debug("accessToken init err :", err)
			return nil
		}

		api := &API{
			appKey:         appKey,
			appSecret:      appSecret,
			accessToken:    access.AccessToken,
			refreshToken:   access.RefreshToken,
			expiresIn:      access.ExpiresIn,
			accessTokenObj: access,
		}
		if access.ExpiresIn < time.Now().Unix() {
			api.RefreshToken()
		}
		return api
	}
	return &API{
		appKey:    appKey,
		appSecret: appSecret,
	}
}

func (a *API) GetToken() string {
	if a.expiresIn != 0 && a.expiresIn > time.Now().Unix() && a.accessToken != "" {
		return a.accessToken
	} else {
		if _, err := a.RefreshToken(); err != nil {
			globals.SugarLogger.Debug("Tiktok RefreshToken Err : ", err)
			return ""
		}
		return a.accessToken
	}
}

// CreateToken 创建token只有第一次授权或者更新授权才需要,其他时候直接刷新就可以啦
func (a *API) CreateToken(code string) (*doudian_sdk.CreateTokenData, error) {
	doudian_sdk.GlobalConfig.AppKey = a.appKey
	doudian_sdk.GlobalConfig.AppSecret = a.appSecret
	buildParam := &doudian_sdk.BuildAccessTokenParam{
		Code:   code,
		ShopId: 0,
		Config: nil,
	}
	access, err := doudian_sdk.BuildAccessToken(buildParam)
	if err != nil {
		return nil, err
	}

	a.accessToken = access.AccessToken
	a.refreshToken = access.RefreshToken
	a.expiresIn = time.Now().Unix() + access.ExpiresIn
	a.accessTokenObj = access
	access.CreateTokenData.ExpiresIn = a.expiresIn
	return &access.CreateTokenData, nil
}

// RefreshToken 刷新token
func (a *API) RefreshToken() (*doudian_sdk.CreateTokenData, error) {
	doudian_sdk.GlobalConfig.AppKey = a.appKey
	doudian_sdk.GlobalConfig.AppSecret = a.appSecret
	refresh := doudian_sdk.NewRefreshTokenRequest()
	refresh.GetParam().RefreshToken = a.refreshToken
	refresh.GetParam().GrantType = "refresh_token"

	createToken, err := refresh.Execute(a.accessTokenObj)
	if err != nil {
		return nil, err
	}
	if createToken.Code != RequestSuccessCode {
		return nil, errors.New(createToken.SubMsg + ":" + createToken.LogId)
	}
	a.accessToken = createToken.Data.AccessToken
	a.refreshToken = createToken.Data.RefreshToken
	a.expiresIn = time.Now().Unix() + createToken.Data.ExpiresIn
	a.accessTokenObj.CreateTokenData = createToken.Data

	// 不要
	createToken.Data.ExpiresIn = a.expiresIn
	return &createToken.Data, nil
}

func (a *API) SetToken(token string) {
	a.locker.Lock()
	defer a.locker.Unlock()
	a.accessToken = token
}

func (a *API) SetRefreshToken(token string) {
	a.locker.Lock()
	defer a.locker.Unlock()
	a.refreshToken = token
}

func (a *API) SetExpiresIn(expiresIn int64) {
	a.locker.Lock()
	defer a.locker.Unlock()
	a.expiresIn = expiresIn
}

func (a *API) SetAcctokenObj(acctokenObj *doudian_sdk.AccessToken) {
	a.locker.Lock()
	defer a.locker.Unlock()
	a.accessTokenObj = acctokenObj
}

// GetAppId 获取appid
func (a *API) GetAppId() string {
	a.locker.Lock()
	defer a.locker.Unlock()
	return a.appKey
}

func (a *API) SetAccessToken(token string) {
	a.locker.Lock()
	defer a.locker.Unlock()
	var access *doudian_sdk.AccessToken
	if err := json.Unmarshal([]byte(token), &access); err != nil {
		return
	}

	a.accessToken = access.AccessToken
	a.refreshToken = access.RefreshToken
	a.expiresIn = access.ExpiresIn
	a.accessTokenObj = access
	return
}
