package rpc

import (
	"encoding/json"
	"errors"
	"fmt"
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/mylogrus"
	"git.hilo.cn/hilo-common/resource/consul"
	"git.hilo.cn/hilo-common/resource/mysql"
	"math/rand"
)

const (
	defaultUserConsulName   = "hiloUser"
	defaultUserServerScheme = "http"
	defaultUserServerAddr   = "127.0.0.1:9040" // 默认内网转发,本地回环
)

var UserServerHost = []string{defaultUserServerAddr}

func init() {
	go func() {
		consul.RegisterWatcher(defaultUserConsulName, func(addr []string) {
			if len(addr) > 0 {
				UserServerHost = addr
			}
		})
	}()
}

type CvUserLevel struct {
	UserId          mysql.ID `json:"userId"`          // 用户id
	WealthUserGrade uint32   `json:"wealthUserGrade"` //财富等级
	CharmUserGrade  uint32   `json:"charmUserGrade"`  //魅力等级
	ActiveUserGrade uint32   `json:"activeUserGrade"` // 活跃等级
	NobleLevel      uint16   `json:"nobleLevel"`      // 贵族等级
}

// 获取用户等级
func GetUserLevel(model *domain.Model, userId mysql.ID) (CvUserLevel, error) {
	level, err := MGetUserLevel(model, []mysql.ID{userId})
	if err != nil {
		return CvUserLevel{}, nil
	}
	return level[userId], nil
}

// 批量获取用户等级
func MGetUserLevel(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]CvUserLevel, error) {
	type Response struct {
		Code    int                      `json:"code"`
		Message string                   `json:"message"`
		Data    map[mysql.ID]CvUserLevel `json:"data"`
	}
	var res = make(map[mysql.ID]CvUserLevel)
	if len(userIds) <= 0 {
		return res, nil
	}
	var userIdsStr []string
	for _, userId := range userIds {
		userIdsStr = append(userIdsStr, fmt.Sprintf("%d", userId))
	}
	_url := fmt.Sprintf("%v://%v/inner/user/levels", defaultUserServerScheme, getUserHost())
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"ids": userIdsStr,
	})
	if err != nil {
		model.Log.Errorf("MGetUserLevel fail:%v", err)
		return res, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("MGetUserLevel json fail:%v", err)
		return res, err
	}
	for userId, level := range response.Data {
		res[userId] = CvUserLevel{
			UserId:          level.UserId,
			WealthUserGrade: level.WealthUserGrade,
			CharmUserGrade:  level.CharmUserGrade,
			ActiveUserGrade: level.ActiveUserGrade,
			NobleLevel:      level.NobleLevel,
		}
	}
	return res, nil
}

type CvUserBag struct {
	BagId      mysql.ID   `json:"bagId"`      // 背包id
	ResType    mysql.Type `json:"resType"`    // 道具类型 1:礼物道具
	ResId      mysql.ID   `json:"resId"`      // 道具资源id
	Name       string     `json:"name"`       // 资源名称
	DiamondNum mysql.Num  `json:"diamondNum"` // 钻石数量
	IconUrl    string     `json:"iconUrl"`    // icon url
	SvgaUrl    string     `json:"svgaUrl"`    // svga url
	Count      mysql.Num  `json:"count"`      // 拥有数量
	RemainDays int        `json:"remainDays"` // 有效天数
}

// 根据bagId获取用户背包
func GetUserBagId(model *domain.Model, bagId mysql.ID) (CvUserBag, error) {
	type Response struct {
		Code    int       `json:"code"`
		Message string    `json:"message"`
		Data    CvUserBag `json:"data"`
	}
	_url := fmt.Sprintf("%v://%v/inner/user/bag/id", defaultUserServerScheme, getUserHost())
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"bagId": {fmt.Sprintf("%d", bagId)},
	})
	if err != nil {
		model.Log.Errorf("GetUserBag fail:%v", err)
		return CvUserBag{}, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("GetUserBag json fail:%v", err)
		return CvUserBag{}, err
	}
	return response.Data, nil
}

// 发送用户背包
// param resType 1:礼物
// param resId 礼物id
// param count 数量
// param day 天数
// param reason 原因
func SendUserBag(model *domain.Model, userId mysql.ID, resType, resId mysql.ID, count, day mysql.Num, reason string) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/bag/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId":  fmt.Sprintf("%d", userId),
		"resType": fmt.Sprintf("%d", resType),
		"resId":   fmt.Sprintf("%d", resId),
		"count":   fmt.Sprintf("%d", count),
		"day":     fmt.Sprintf("%d", day),
		"reason":  reason,
	})
	if err != nil {
		model.Log.Errorf("SendUserBag fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserBag json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserBag fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

// 发送用户贵族
func SendUserNoble(model *domain.Model, userId mysql.ID, level int, day mysql.Num) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/noble/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId": fmt.Sprintf("%d", userId),
		"level":  fmt.Sprintf("%d", level),
		"day":    fmt.Sprintf("%d", day),
	})
	if err != nil {
		model.Log.Errorf("SendUserNoble fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserNoble json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserNoble fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

// 发送用户头饰
func SendUserHeadwear(model *domain.Model, userId mysql.ID, headwearId mysql.ID, day mysql.Num) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/headwear/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId":     fmt.Sprintf("%d", userId),
		"headwearId": fmt.Sprintf("%d", headwearId),
		"day":        fmt.Sprintf("%d", day),
	})
	if err != nil {
		model.Log.Errorf("SendUserHeadwear fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserHeadwear json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserHeadwear fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

// 发送用户座驾
func SendUserRide(model *domain.Model, userId mysql.ID, rideId mysql.ID, day mysql.Num) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/ride/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId": fmt.Sprintf("%d", userId),
		"rideId": fmt.Sprintf("%d", rideId),
		"day":    fmt.Sprintf("%d", day),
	})
	if err != nil {
		model.Log.Errorf("SendUserRide fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserRide json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserRide fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

func getUserHost() string {
	l := len(UserServerHost)
	r := rand.Intn(l) // 随机一个
	mylogrus.MyLog.Infof("getHostUser:%v---%v", r, UserServerHost[r])
	return UserServerHost[r]
}