package arkid

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

type SDK struct {
	response []byte
	fmap     map[string]func(RequestBody)
	fname    string
	err      error
}

//Init is init sdk
func (s *SDK) Init() {
	s.fmap = make(map[string]func(RequestBody))
}

//SelectFunction is choose func
func (s *SDK) SelectFunction(fname string) *SDK {
	s.fname = fname
	return s
}

//WithArgs is request args
func (s *SDK) WithArgs(r RequestBody) *SDK {
	f := s.fmap[s.fname]
	f(r)
	return s
}

//Result is result to p
func (s *SDK) Result(p interface{}) error {
	if s.err != nil {
		return s.err
	}
	if string(s.response) == "" {
		return nil
	}
	if err := json.Unmarshal(s.response, p); err != nil {
		return logx.Error(string(s.response), err)
	}
	return nil
}

// Register is register func
func (s *SDK) Register(name string, f func(RequestBody)) {
	s.fmap[name] = f
}

//getAdmin arkid 用户的信息 ，主要是token
func (s *SDK) arkidLogin(r RequestBody) {
	postData := map[string]interface{}{
		"username": r.Username,
		"password": r.Password,
	}
	s.response, s.err = arkidLogin(postData)
}

func (s *SDK) arkidRegister(r RequestBody) {
	postData := map[string]interface{}{}
	b, err := json.Marshal(r)
	if err != nil {
		s.err = err
	}
	if err := json.Unmarshal(b, &postData); err != nil {
		s.err = err
	}
	s.response, s.err = arkidRegister(postData)
}

func (s *SDK) arkidAppAccessWhiteList(r RequestBody) {
	postData := map[string]interface{}{}
	b, err := json.Marshal(r)
	if err != nil {
		s.err = err
	}
	if err := json.Unmarshal(b, &postData); err != nil {
		s.err = err
	}
	s.response, s.err = arkidAppAccessWhiteList(postData, r.PermName)
}

func (s *SDK) arkidUserInfo(r RequestBody) {
	s.response, s.err = arkidUserInfo(r.Token)
}

func (s *SDK) arkidUserDelete(r RequestBody) {
	s.response, s.err = arkidUserDelete(r.Username)
}

func (s *SDK) arkidUserUpdate(r RequestBody) {
	postData := map[string]interface{}{}
	b, err := json.Marshal(r.User)
	if err != nil {
		s.err = err
	}
	if err := json.Unmarshal(b, &postData); err != nil {
		s.err = err
	}
	s.response, s.err = arkidUserUpdate(r.Username, postData)
}

func (s *SDK) arkidLogout(r RequestBody) {
	s.response, s.err = arkidLogout(r.Token)
}

// NewArkID is con
func NewArkID() *SDK {
	sdk := new(SDK)
	sdk.Init()
	sdk.Register("arkid_login", sdk.arkidLogin)
	sdk.Register("arkid_register", sdk.arkidRegister)
	sdk.Register("arkid_app_access_white_list", sdk.arkidAppAccessWhiteList)
	sdk.Register("arkid_delete_user", sdk.arkidUserDelete)
	sdk.Register("arkid_user_info", sdk.arkidUserInfo)
	sdk.Register("arkid_user_update", sdk.arkidUserUpdate)
	sdk.Register("arkid_logout", sdk.arkidLogout)
	return sdk
}

// GetArkIDUser is get arkid token if redis is existed unless send request to arkid
func GetArkIDUser(username string, MD5passowrd string) (*ArkIDUser, error) {
	key := fmt.Sprintf("arkid_user_%s", username)
	arkidUser := new(ArkIDUser)
	c, err := cache.GetBytes(key)
	if c != nil && err == nil {
		if err := json.Unmarshal(c, arkidUser); err != nil {
			return arkidUser, err
		}
		if arkidUser.Token == "" {

			return arkidUser, errors.New("Get Arkid User error, Token missing")
		}

		return arkidUser, err
	}
	arkidSdk := NewArkID()
	err = arkidSdk.SelectFunction("arkid_login").WithArgs(RequestBody{
		Username: username,
		Password: MD5passowrd,
	}).Result(arkidUser)
	if arkidUser.Token == "" {
		return arkidUser, errors.New("Get Arkid User error, Token missing")
	}
	// 缓存30天
	// cache.SetEx(key, utils.Serialize(arkidUser), 2592000)
	return arkidUser, err
}

// RegisterRollback is 注册时的错误回滚
func RegisterRollback(username string) error {
	sdk := NewArkID()
	err := sdk.SelectFunction("arkid_delete_user").WithArgs(RequestBody{
		Username: username,
	}).Result(nil)
	if err != nil {
		return err
	}
	return nil
}
