package redisdata

import (
	"encoding/json"
	"errors"
	"oppmg/common/log"
	"oppmg/common/redis"
	"oppmg/protocol"
	"oppmg/services/rbac"
	"strings"
	"time"
)

func SetLoginToken(param protocol.LoginAuthToken, userid int64, companyid int64) error {
	client := redis.GetRedis()
	var (
		key   string
		value []byte
		err   error
	)
	data := RedisLoginToken{
		AccessToken:    param.AccessToken,
		CurrentCompany: companyid,
	}
	value, _ = json.Marshal(data)

	key = GetKeyLoginToken(userid, companyid)
	client.Del(key)
	err = client.Set(key, string(value), LOGIN_TOKEN_EXP).Err()
	return err
}

func GetLoginToken(userid int64, companyid int64) (RedisLoginToken, error) {
	client := redis.GetRedis()
	var (
		key    string
		value  string
		err    error
		result RedisLoginToken
	)
	key = GetKeyLoginToken(userid, companyid)
	value, err = client.Get(key).Result()
	if err != nil {
		return result, err
	}
	value = strings.TrimSpace(value)
	err = json.Unmarshal([]byte(value), &result)
	if err != nil {
		log.Error("Unmarshal redis value:%s err:%s", value, err)
		return result, err
	}
	return result, nil
}

func ExistLoginToken(userid int64, companyid int64) bool {
	client := redis.GetRedis()
	key := GetKeyLoginToken(userid, companyid)
	value := client.Exists(key).Val()
	if value > 0 {
		return true
	}
	return false
}

func DeleteLoginToken(userid int64, companyid int64) error {
	client := redis.GetRedis()
	key := GetKeyLoginToken(userid, companyid)
	err := client.Del(key).Err()
	return err
}

//   刷新token 的有效期
func RefreshLoginTokenExpires(userid int64, companyid int64) error {
	client := redis.GetRedis()
	key := GetKeyLoginToken(userid, companyid)
	result, err := client.Exists(key).Result()
	if err != nil {
		return err
	}
	if result == 0 {
		return nil
	}
	_, err = client.Expire(key, LOGIN_TOKEN_EXP).Result()
	if err != nil {
		return err
	}
	return nil
}

func SetCaptchAuth(phone string, captchAuth string) error {
	key := GetKeyCaptchAuth(phone)
	client := redis.GetRedis()
	client.Del(key)
	err := client.Set(key, captchAuth, CAPTCHA_AUTH_EXP).Err()
	return err
}

func GetCaptchAuth(phone string) (string, error) {
	key := GetKeyCaptchAuth(phone)
	client := redis.GetRedis()
	r, err := client.Get(key).Result()
	return r, err
}

func SetUserPermission(objMap map[string]rbac.PermissionOptionObject, userid int64) error {
	key := GetKeyUserPermission(userid)
	client := redis.GetRedis()
	client.Del(key)
	for k := range objMap {
		s, err := json.Marshal(objMap[k])
		if err != nil {
			log.Error("解析错误:%s", err)
			continue
		}
		err = client.HSet(key, k, s).Err()
		if err != nil {
			log.Error("设置权限缓存失败:%s", err)
		}
	}
	client.Expire(key, 60*60*6*time.Second)
	return nil
}

func GetUserPermission(userid int64, field string) (rbac.PermissionOptionObject, error) {
	key := GetKeyUserPermission(userid)
	client := redis.GetRedis()
	str, err := client.HGet(key, field).Result()
	if err != nil {
		return nil, err
	}
	var permissionObj rbac.PermissionOptionObject
	fn, ok := rbac.CodePermissionObject[field]
	if !ok {
		return nil, errors.New("cannot get object")
	}
	permissionObj = fn()
	err = json.Unmarshal([]byte(str), &permissionObj)
	return permissionObj, err
}

func ExistUserPermission(userid int64) bool {
	key := GetKeyUserPermission(userid)
	client := redis.GetRedis()
	value := client.Exists(key).Val()
	if value > 0 {
		return true
	}
	return false
}

func GetUserPermissionAll(userid int64) (map[string]rbac.PermissionOptionObject, error) {
	key := GetKeyUserPermission(userid)
	client := redis.GetRedis()
	strMap, err := client.HGetAll(key).Result()
	if err != nil {
		return nil, err
	}
	permissionObj := make(map[string]rbac.PermissionOptionObject)
	for k, v := range strMap {
		fn, ok := rbac.CodePermissionObject[k]
		if !ok {
			continue
		}
		obj := fn()
		if err := obj.StringUnmarshal(v); err == nil {
			permissionObj[k] = obj
		}

	}
	return permissionObj, err
}