package models

import (
	"fmt"
	"math/rand"
	"time"

	mhayaTime "github.com/mhaya/extend/time"
	"github.com/mhaya/game/game_cluster/internal/data"
	"github.com/mhaya/game/game_cluster/internal/guid"
	clog "github.com/mhaya/logger"
)

type PlayerLevelStat struct {
	Platform    string         `bson:"platform"  json:"platform"` // platform: 用户所在的平台，例如“Android”或“IOS”
	Channel     string         `bson:"channel" json:"channel"`    // channel: 用户来源渠道
	ServerLevel map[string]int `json:"serverLevel" bson:"serverLevel"`
	UpdateTime  int64          `bson:"updateTime" json:"updateTime"`
}

type PlayerServerLoadStat struct {
	Name       string            `bson:"name" json:"name"`
	TotalUser  int64             `bson:"totalUser" json:"totalUser"`
	Load       map[string]string `bson:"load" json:"load"`
	UpdateTime int64             `bson:"updateTime" json:"updateTime"`
}

type PlayerCountryStat struct {
	Daily                 int64          `bson:"daily" json:"daily"`                                 // 日期
	Platform              string         `bson:"platform"  json:"platform"`                          // platform: 用户所在的平台，例如“Android”或“IOS”
	Channel               string         `bson:"channel" json:"channel"`                             // channel: 用户来源渠道
	PlayerRegisterCountry map[string]int `bson:"playerRegisterCountry" json:"playerRegisterCountry"` // playerRegisterCountry 玩家注册国家
	UpdateTime            int64          `bson:"updateTime" json:"updateTime"`
}

type Preserve struct {
	ID    int64  `json:"id"`
	Num   int    `json:"num"`
	Ratio string `json:"ratio"`
}

var preserveConfig = []int64{2, 3, 7, 14, 30}

// GetPlayerPreserve 获取用户留存
func GetPlayerPreserve(startTime, EndTime int64) map[int64][]*Preserve {
	if startTime > mhayaTime.Now().Unix() || EndTime > mhayaTime.Now().Unix() {
		return nil
	}
	sTime := mhayaTime.CreateFromTimestamp(startTime).TOTimeStamp()

	if EndTime > mhayaTime.Now().Unix() {
		EndTime = mhayaTime.Now().Unix()
	}
	eTime := mhayaTime.CreateFromTimestamp(EndTime).TOTimeStamp()
	day := mhayaTime.CreateFromTimestamp(sTime).DiffInDays(mhayaTime.CreateFromTimestamp(eTime))
	if day > 7 {
		return nil
	}
	var ret = make(map[int64][]*Preserve, 0)
	for i := 0; i < int(day); i++ {
		curTime := mhayaTime.CreateFromTimestamp(sTime).Add(time.Duration(i) * 24 * time.Hour).Unix()
		ret[curTime] = PlayerPreserve(curTime)
	}
	return ret
}

func PlayerPreserve(startTime int64) []*Preserve {
	var preserve []*Preserve
	cur, curNum := GetNewPlayerMap(startTime, DailyRecordNewRegistered)

	preserve = append(preserve, &Preserve{ID: 1, Num: curNum, Ratio: "100%"})

	for _, v := range preserveConfig {
		nextTime := mhayaTime.CreateFromTimestamp(startTime).Add(time.Duration(v-1) * 24 * time.Hour).Unix()
		next, nextNum := GetNewPlayerMap(nextTime, DailyRecordOldLogin)
		if nextNum == 0 {
			preserve = append(preserve, &Preserve{ID: v, Num: 0, Ratio: ""})
		} else {
			var num int
			for key, _ := range next {
				if _, ok := cur[key]; ok {
					num++
				}
			}
			preserve = append(preserve, &Preserve{ID: v, Num: num, Ratio: fmt.Sprintf("%.2f", float64(num)/float64(curNum)*100)})
		}

	}
	return preserve
}

func GetNewPlayerMap(startTime int64, op int) (map[string]struct{}, int) {
	var user = make(map[string]struct{})

	platformConfig := data.PlatformConfig.GatMap()
	channelConfig := data.ChannelConfig.GatMap()

	for _, v := range platformConfig {
		for _, v2 := range channelConfig {
			ret, err := GetAppointDailyRecordUserHash(v.Name, v2.Name, startTime, op)
			if err != nil {
				continue
			}
			for k, _ := range ret {
				if _, ok := user[k]; !ok {
					user[k] = struct{}{}
				}
			}

		}
	}
	return user, len(user)
}

func TestPreserve(startTime int64, num int) {
	sTime := mhayaTime.CreateFromTimestamp(startTime).TOTimeStamp()
	for i := 0; i < num; i++ {
		userID := guid.Next()
		clog.Debugf("num=%v, user =%v", i, userID)
		SetAppointDailyRecordNewUserRegisterHash("ios", "tg", userID, "1", sTime, DailyRecordNewRegistered)
		for _, v := range preserveConfig {
			r := rand.Intn(100)
			if r < 80 {
				nextTime := mhayaTime.CreateFromTimestamp(sTime).Add(time.Duration(v-1) * 24 * time.Hour).Unix()
				SetAppointDailyRecordNewUserRegisterHash("ios", "tg", userID, "1", nextTime, DailyRecordOldLogin)
			}
		}
	}
}
