package model

import (
	"fmt"
	"mongo.games.com/game/protocol/server"
	"time"

	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"mongo.games.com/goserver/core/logger"
)

var (
	CoinPoolSettingDBName      = "user"
	CoinPoolSettingCollName    = "user_coinpoolsetting"
	CoinPoolSettingHisDBName   = "log"
	CoinPoolSettingHisCollName = "log_coinpoolsetting"
)

var CoinPoolSettingDatas = make(map[string]*CoinPoolSetting)

type CoinPoolSetting struct {
	Id           bson.ObjectId `bson:"_id"`
	Platform     string        // 平台id
	GameFreeId   int32         // 游戏id
	GroupId      int32         // 组id
	ServerId     int32         // 服务器id
	InitValue    int64         // 初始库存值
	LowerLimit   int64         // 库存下限
	UpperLimit   int64         // 库存上限
	QuDu         int64         // 曲度值
	UpperOdds    int32         // 上线初始概率
	UpperOddsMax int32         // 上线最大概率
	LowerOdds    int32         // 下线初始概率
	LowerOddsMax int32         // 下线最大概率
	ProfitRate   int32         // 收益抽取比例
	// 扩展参数
	ResetTime int64     // 重置时间
	UptTime   time.Time // 更新时间
	Switch    int32     // 开关 0开启 1关闭
}

func NewCoinPoolSetting(platform string, groupId, gamefreeid, srverId int32, db *server.DB_GameCoinPool) *CoinPoolSetting {
	cl := &CoinPoolSetting{Id: bson.NewObjectId()}
	cl.Platform = platform
	cl.GroupId = groupId
	cl.GameFreeId = gamefreeid
	cl.ServerId = srverId
	cl.InitValue = db.InitValue
	cl.LowerLimit = db.LowerLimit
	cl.UpperLimit = db.UpperLimit
	cl.QuDu = db.QuDu
	cl.UpperOdds = db.UpperOdds
	cl.UpperOddsMax = db.UpperOddsMax
	cl.LowerOdds = db.LowerOdds
	cl.LowerOddsMax = db.LowerOddsMax
	cl.ProfitRate = db.ProfitRate
	cl.ResetTime = time.Now().Unix()
	cl.UptTime = time.Now()
	return cl
}

func GetAllCoinPoolSettingData() error {
	if rpcCli == nil {
		return ErrRPClientNoConn
	}
	var datas []CoinPoolSetting
	err := rpcCli.CallWithTimeout("CoinPoolSettingSvc.GetAllCoinPoolSettingData", struct{}{}, &datas, time.Second*30)
	if err != nil {
		logger.Logger.Warn("GetAllCoinPoolSettingData error:", err)
		return err
	}
	for i := 0; i < len(datas); i++ {
		dbSetting := &datas[i]
		ManageCoinPoolSetting(dbSetting)
	}
	return nil
}

type UpsertCoinPoolSettingArgs struct {
	Cps *CoinPoolSetting
	Old *CoinPoolSetting
}

func UpsertCoinPoolSetting(cps, old *CoinPoolSetting) (err error) {
	if rpcCli == nil {
		return ErrRPClientNoConn
	}
	var ret bool
	args := &UpsertCoinPoolSettingArgs{
		Cps: cps,
		Old: old,
	}
	err = rpcCli.CallWithTimeout("CoinPoolSettingSvc.UpsertCoinPoolSetting", args, &ret, time.Second*30)
	if err != nil {
		logger.Logger.Warn("UpsertCoinPoolSetting error:", err)
		return err
	}
	return
}

func GetCoinPoolSetting(gameFreeId, serverId, groupId int32, platform string) *CoinPoolSetting {
	var key string
	if groupId != 0 {
		key = fmt.Sprintf("%v+%v_%v", gameFreeId, groupId, serverId)
	} else {
		key = fmt.Sprintf("%v_%v_%v", gameFreeId, platform, serverId)
	}
	if data, exist := CoinPoolSettingDatas[key]; exist {
		return data
	}
	return nil
}

func ManageCoinPoolSetting(dbSetting *CoinPoolSetting) {
	var key string
	if dbSetting.GroupId != 0 {
		key = fmt.Sprintf("%v+%v_%v", dbSetting.GameFreeId, dbSetting.GroupId, dbSetting.ServerId)
	} else {
		key = fmt.Sprintf("%v_%v_%v", dbSetting.GameFreeId, dbSetting.Platform, dbSetting.ServerId)
	}
	CoinPoolSettingDatas[key] = dbSetting
}

// 删除水池历史调控记录
func RemoveCoinPoolSettingHis(ts time.Time) (*mgo.ChangeInfo, error) {
	if rpcCli == nil {
		return nil, ErrRPClientNoConn
	}
	var ret mgo.ChangeInfo
	err := rpcCli.CallWithTimeout("CoinPoolSettingSvc.RemoveCoinPoolSettingHis", ts, &ret, time.Second*30)
	if err != nil {
		logger.Logger.Warn("RemoveCoinPoolSettingHis error:", err)
		return &ret, err
	}
	return &ret, err
}
