package model

import (
	"active/constant"
	"active/tools"
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"

	"git.jiaxianghudong.com/go/gsdkclient"

	"git.jiaxianghudong.com/webs/pkg/rds"
)

var PiggyBankConf = &PiggyBank{}

var PushChan = make(chan struct{})

type PiggyBank struct {
	ReceiveList []struct {
		Diamond     int64 `json:"diamond" yaml:"diamond"`
		BeanNumber  int64 `json:"bean_number" yaml:"bean_number"`
		RealDiamond int64 `json:"real_diamond" yaml:"real_diamond"`
		Add         int64 `json:"add" yaml:"add"`
		Level       int   `json:"level" yaml:"level"`
	} `json:"receive_list" yaml:"receive_list"`
	ReceiveListV2 []struct {
		Diamond     int64 `json:"diamond" yaml:"diamond"`
		RealDiamond int64 `json:"real_diamond" yaml:"real_diamond"`
		MinBean     int64 `json:"min_bean" yaml:"min_bean"`
		MaxBean     int64 `json:"max_bean" yaml:"max_bean"`
		Add         int64 `json:"add" yaml:"add"` //折扣
		Between     []int `json:"between" yaml:"between"`
		Level       int   `json:"level" yaml:"level"`
	} `json:"receive_list_v2" yaml:"receive_list_v2"`

	StartTime int64 `json:"start_time" yaml:"start_time"`
	EndTime   int64 `json:"end_time" yaml:"end_time"`
	Switch    int64 `json:"switch" yaml:"switch"`
}

type PiggyBankDetail struct {
	Level      int64 `json:"level"`       //档位
	BeanNumber int64 `json:"bean_number"` //豆豆数
}

func GetPiggyBankData(userID int64, tm int64, ishost bool) (*PiggyBankDetail, error) {

	//fmt.Println(fmt.Sprintf(constant.PIGGYBANKDATA, tm))
	userIdStr := strconv.FormatInt(userID, 10)
	piggyBankDetail := &PiggyBankDetail{
		Level:      1,
		BeanNumber: 0,
	}

	useGameRedis := rds.GameRedis0
	//if ishost {
	//	useGameRedis = rds.GameTestRedis0
	//}

	var err error
	data := useGameRedis.HGet(fmt.Sprintf(constant.PIGGYBANKDATA, tm), userIdStr).Val()
	if data == "" {
		return nil, fmt.Errorf("没有存豆记录")
	}
	strList := strings.Split(data, ",")
	if len(strList) != 2 {
		SetPiggyBankData(userID, tm, piggyBankDetail, ishost)
		return nil, err
	}
	piggyBankDetail.Level, err = strconv.ParseInt(strList[0], 10, 64)
	if err != nil {
		log.Printf("redisKey: %v Level转成int64的问题: %v \n", userIdStr, err)
		return nil, err
	}

	piggyBankDetail.BeanNumber, err = strconv.ParseInt(strList[1], 10, 64)
	if err != nil {
		log.Printf("redisKey: %v BeanNumber转成int64的问题: %v \n", userIdStr, err)
		return nil, err
	}
	return piggyBankDetail, nil
}

func SetPiggyBankData(userID int64, tm int64, data *PiggyBankDetail, ishost bool) bool {
	useGameRedis := rds.GameRedis0
	if ishost {
		useGameRedis = rds.GameTestRedis0
	}

	userIdStr := strconv.FormatInt(userID, 10)
	dataStr := fmt.Sprintf("%v,%v", data.Level, data.BeanNumber)
	err := useGameRedis.HSet(fmt.Sprintf(constant.PIGGYBANKDATA, tm), userIdStr, dataStr).Err()
	if err != nil {
		log.Printf("redisKey: %v number: %v redis.HSet-err: %v \n", userID, data, err)
		return false
	}
	return true
}

func GetPiggyBankDataV2(userID int64, tm int64, ishost bool) (*PiggyBankDetail, error) {

	//fmt.Println(fmt.Sprintf(constant.PIGGYBANKDATA, tm))
	userIdStr := strconv.FormatInt(userID, 10)
	piggyBankDetail := &PiggyBankDetail{
		Level:      1,
		BeanNumber: 0,
	}

	useGameRedis := rds.GameRedis0
	//if ishost {
	//	useGameRedis = rds.GameTestRedis0
	//}

	var err error
	data := useGameRedis.HGet(fmt.Sprintf(constant.PIGGYBANKDATAV2, tm), userIdStr).Val()
	if data == "" {
		return nil, nil
	}
	strList := strings.Split(data, ",")
	if len(strList) != 2 {
		SetPiggyBankData(userID, tm, piggyBankDetail, ishost)
		return nil, err
	}
	piggyBankDetail.Level, err = strconv.ParseInt(strList[0], 10, 64)
	if err != nil {
		log.Printf("redisKey: %v Level转成int64的问题: %v \n", userIdStr, err)
		return nil, err
	}

	piggyBankDetail.BeanNumber, err = strconv.ParseInt(strList[1], 10, 64)
	if err != nil {
		log.Printf("redisKey: %v BeanNumber转成int64的问题: %v \n", userIdStr, err)
		return nil, err
	}
	return piggyBankDetail, nil
}

func SetPiggyBankDataV2(userID int64, tm int64, data *PiggyBankDetail, ishost bool) bool {
	useGameRedis := rds.GameRedis0
	if ishost {
		useGameRedis = rds.GameTestRedis0
	}

	userIdStr := strconv.FormatInt(userID, 10)
	dataStr := fmt.Sprintf("%v,%v", data.Level, data.BeanNumber)
	err := useGameRedis.HSet(fmt.Sprintf(constant.PIGGYBANKDATAV2, tm), userIdStr, dataStr).Err()
	if err != nil {
		log.Printf("redisKey: %v number: %v redis.HSet-err: %v \n", userID, data, err)
		return false
	}
	return true
}

func SetPiggyBankExpire() {
	sp := GetAllActiceByType(constant.PiggyBankType)

	o := &OpenTimes{}
	o.GetOpenTime(sp.OpenTimes)
	if sp.Status == "1" {
		end := time.Unix(PiggyBankConf.EndTime, 0).Add(72 * time.Hour)
		rds.GameRedis0.ExpireAt(fmt.Sprintf(constant.PIGGYBANKDATA, PiggyBankConf.StartTime), end)
		rds.GameRedis0.ExpireAt(fmt.Sprintf(constant.PIGGYBANKDATAV2, PiggyBankConf.StartTime), end)
	}
}

func SetPiggyBankSend(room int64, server int64) error {
	return rds.GameRedis0.HSet(constant.PIGGYBANKSEND, fmt.Sprintf("%v;%v", room, server), 1).Err()
}

func InitPubPiggybank() {
	<-PushChan
	go PubPiggyBankConf()
	log.Println("done push ")
}

func PubPiggyBankConf() []string {
	msgList := []string{}
	sp := GetAllActiceByType(constant.PiggyBankType)

	o := &OpenTimes{}
	o.GetOpenTime(sp.OpenTimes)

	if sp.Status == "1" {
		PiggyBankConf.StartTime = tools.TimeParseUnix(o.Start, "")
		PiggyBankConf.EndTime = tools.TimeParseUnix(o.End, "")
		PiggyBankConf.Switch = 1
		end := time.Unix(PiggyBankConf.EndTime, 0).Add(72 * time.Hour)
		rds.GameRedis0.ExpireAt(fmt.Sprintf(constant.PIGGYBANKDATA, PiggyBankConf.StartTime), end)
		rds.GameRedis0.ExpireAt(fmt.Sprintf(constant.PIGGYBANKDATAV2, PiggyBankConf.StartTime), end)
	} else {
		PiggyBankConf.StartTime = 0
		PiggyBankConf.EndTime = 0
		PiggyBankConf.Switch = 0
	}

	str := fmt.Sprintf("%v_%v_%v;", PiggyBankConf.StartTime, PiggyBankConf.EndTime, PiggyBankConf.Switch)
	for _, v := range PiggyBankConf.ReceiveList {
		str += fmt.Sprintf("%v_%v_%v_%v_%v;", v.Diamond, v.BeanNumber, v.RealDiamond, v.Add, v.Level)
	}
	str2 := fmt.Sprintf("%v_%v_%v;", PiggyBankConf.StartTime, PiggyBankConf.EndTime, PiggyBankConf.Switch)
	for _, v := range PiggyBankConf.ReceiveListV2 {
		str2 += fmt.Sprintf("%v_%v_%v_%v_%v_%v;", v.Diamond, v.MinBean, v.MaxBean, v.RealDiamond, v.Add, v.Level)
	}
	result := rds.GameTestRedis0.Set(constant.PIGGYBANK, str, -1).Err()
	result = rds.GameRedis0.Set(constant.PIGGYBANK, str, -1).Err()
	result = rds.GameRedis0.Set(constant.PIGGYBANKSTART, fmt.Sprintf("%v", PiggyBankConf.StartTime), -1).Err()
	rds.GameRedis0.Set(constant.PIGGYBANKV2, str2, -1)
	rds.GameTestRedis0.Set(constant.PIGGYBANKV2, str2, -1)
	if result != nil {
		fmt.Println(result)
		return nil
	}

	log.Printf("%v \n", str)

	//	sendMap := rds.GameRedis0.HGetAll(constant.PIGGYBANKSEND).Val()
	if sp.IsDebug != "1" {
		sendMap := make(map[string]bool)
		var cursor uint64
		for {
			var keys []string
			keys, cursor = rds.GameRedis0.HScan(constant.PIGGYBANKSEND, cursor, "*", 20).Val()
			for _, key := range keys {
				sendMap[key] = true
			}
			fmt.Println("ddd", cursor)
			if cursor == 0 {
				break
			}
		}

		for s := range sendMap {
			list := strings.Split(s, ";")
			if len(list) != 2 {
				continue
			}
			server, _ := strconv.Atoi(list[0])
			room, _ := strconv.Atoi(list[1])
			if _, ok := gsdkclient.Client().RoomShell(room, server, "piggybank"); !ok {
				log.Printf("reidstest 推送失败 %v , %v \n", room, server)
				//msgList = append(msgList,fmt.Sprintf("推送失败 %v , %v \n", server.Room[i], server.Server) )
			} else {
				log.Printf("reidstest 推送成功 %v , %v \n", room, server)
			}
		}

		for _, server := range constant.RoomServerConfs.ServerList {
			for i := range server.Room {
				if _, ok := gsdkclient.Client().RoomShell(server.Room[i], server.Server, "piggybank"); !ok {
					log.Printf("推送失败 %v , %v \n", server.Room[i], server.Server)
					//msgList = append(msgList,fmt.Sprintf("推送失败 %v , %v \n", server.Room[i], server.Server) )
				} else {
					log.Printf("推送成功 %v , %v \n", server.Room[i], server.Server)
				}
			}
		}
	} else {
		rom := []constant.Server{
			{
				Room:   []int{7932, 7574, 6067, 6066, 6065, 6064, 6061},
				Server: 24795,
			},
		}
		for _, server := range rom {
			for i := range server.Room {
				if _, ok := gsdkclient.Client().RoomShell(server.Room[i], server.Server, "piggybank"); !ok {
					log.Printf("测试推送失败 %v , %v \n", server.Room[i], server.Server)
					//msgList = append(msgList,fmt.Sprintf("推送失败 %v , %v \n", server.Room[i], server.Server) )
				} else {
					log.Printf("测试推送成功 %v , %v \n", server.Room[i], server.Server)
				}
			}
		}
	}

	return msgList
}

func SetPiggyBank() {

	sp := GetAllActiceByType(constant.PiggyBankType)

	o := &OpenTimes{}
	o.GetOpenTime(sp.OpenTimes)

	if sp.Status == "1" {
		PiggyBankConf.StartTime = tools.TimeParseUnix(o.Start, "")
		PiggyBankConf.EndTime = tools.TimeParseUnix(o.End, "")
		PiggyBankConf.Switch = 1
		end := time.Unix(PiggyBankConf.EndTime, 0).Add(72 * time.Hour)
		rds.GameRedis0.ExpireAt(fmt.Sprintf(constant.PIGGYBANKDATA, PiggyBankConf.StartTime), end)
		rds.GameRedis0.ExpireAt(fmt.Sprintf(constant.PIGGYBANKDATAV2, PiggyBankConf.StartTime), end)
	} else {
		PiggyBankConf.StartTime = 0
		PiggyBankConf.EndTime = 0
		PiggyBankConf.Switch = 0
	}

	//Diamond     int64 `json:"diamond" yaml:"diamond"`
	//BeanNumber  int64 `json:"bean_number" yaml:"bean_number"`
	//RealDiamond int64 `json:"real_diamond" yaml:"real_diamond"`
	//Add         int64 `json:"add" yaml:"add"`
	//Level       int   `json:"level" yaml:"level"`

	str := fmt.Sprintf("%v_%v_%v;", PiggyBankConf.StartTime, PiggyBankConf.EndTime, PiggyBankConf.Switch)
	for _, v := range PiggyBankConf.ReceiveList {
		str += fmt.Sprintf("%v_%v_%v_%v_%v;", v.Diamond, v.BeanNumber, v.RealDiamond, v.Add, v.Level)
	}

	str2 := fmt.Sprintf("%v_%v_%v;", PiggyBankConf.StartTime, PiggyBankConf.EndTime, PiggyBankConf.Switch)
	for _, v := range PiggyBankConf.ReceiveListV2 {
		str2 += fmt.Sprintf("%v_%v_%v_%v_%v_%v;", v.Diamond, v.MinBean, v.MaxBean, v.RealDiamond, v.Add, v.Level)
	}
	rds.GameTestRedis0.Set(constant.PIGGYBANK, str, -1)
	rds.GameRedis0.Set(constant.PIGGYBANK, str, -1)
	rds.GameRedis0.Set(constant.PIGGYBANKSTART, fmt.Sprintf("%v", PiggyBankConf.StartTime), -1)
	rds.GameRedis0.Set(constant.PIGGYBANKV2, str2, -1)
	rds.GameTestRedis0.Set(constant.PIGGYBANKV2, str2, -1)
}
