package game

import (
	"encoding/gob"
	"fmt"
	"os"
	"server/GoUtil"
	"server/conf"
	cardCfg "server/conf/card"
	chargeCfg "server/conf/charge"
	playroomCfg "server/conf/playroom"
	"server/db"
	"server/game/mod/card"
	"server/game/mod/friend"
	"server/game/mod/item"
	MsgMod "server/game/mod/msg"
	"server/game/mod/playroom"
	"server/msg"
	"server/pkg/github.com/name5566/leaf/log"
	"strconv"
	"strings"

	"google.golang.org/protobuf/proto"
)

func ReqGmCommand(player *Player, buf []byte) error {
	detail := &msg.ReqGmCommand{}
	proto.Unmarshal(buf, detail)
	return ReqGmCommand_(player, detail.Command)
}
func ReqGmCommand_(player *Player, Command string) error {
	arg := strings.Split(Command, " ")
	switch arg[0] {
	case "additem":
		id, _ := strconv.Atoi(arg[1])
		num, _ := strconv.Atoi(arg[2])
		player.HandleItem([]*item.Item{item.NewItem(id, num)}, msg.ITEM_POP_LABEL_GM.String())
	case "subitem":
		id, _ := strconv.Atoi(arg[1])
		num, _ := strconv.Atoi(arg[2])
		player.HandleItem([]*item.Item{item.NewItem(id, -num)}, msg.ITEM_POP_LABEL_GM.String())
	case "reset_order":
		player.PlayMod.mod_list.Order.Step = 0
		player.PlayMod.mod_list.Order.InitData()
		player.PushClientRes(player.PlayMod.mod_list.Order.BackData())
	case "add_card_star":
		num, _ := strconv.Atoi(arg[1])
		player.PlayMod.mod_list.Card.ExchangeStar += num
		player.PushClientRes(player.PlayMod.mod_list.Card.BackData())
	case "add_card":
		Id, _ := strconv.Atoi(arg[1])
		player.PlayMod.mod_list.Card.AddCard(Id)
		player.PushClientRes(player.PlayMod.mod_list.Card.NotifyCard())
	case "reset_card_reward":
		player.PlayMod.mod_list.Card.CollectReward = make(map[int]struct{})
		player.PlayMod.mod_list.Card.AllCollect = 0
		player.PushClientRes(player.PlayMod.mod_list.Card.BackData())
	case "addexp":
		num, _ := strconv.Atoi(arg[1])
		player.GetPlayerBaseMod().AddExp(player, num)
		player.PushClientRes(&player.GetPlayerBaseMod().Data)
	case "addDailyActive":
		num, _ := strconv.Atoi(arg[1])
		DailyMod := player.PlayMod.getDailyTaskMod()
		DailyMod.Active = num
		player.PushClientRes(DailyMod.BackData())
	case "setlv":
		num, _ := strconv.Atoi(arg[1])
		player.PlayMod.getBaseMod().Level = num
		player.PlayMod.getBaseMod().Exp = 0
		player.PushClientRes(player.PlayerBaseMod.BackAsset())
	case "zeroUpdate":
		VarMod := player.PlayMod.getVarMod()
		VarMod.DailyResetTime = 0
		player.ZeroUpdate(nil)
		// G_GameLogicPtr.ZeroFlush()
	case "weekUpdate":
		VarMod := player.PlayMod.getVarMod()
		VarMod.WeeklyResetTime = 0
		player.ZeroUpdate(nil)
		G_GameLogicPtr.ZeroFlush()
	case "setSevenLoginActive":
		num, _ := strconv.Atoi(arg[1])
		player.PlayMod.getSevenLoginMod().Active = num
	case "pay":
		ChargeId, _ := strconv.Atoi(arg[1])
		player.Kafka("pay", map[string]interface{}{
			"ProductId":         ChargeId,
			"AppId":             conf.Server.AppID,
			"Uid":               player.M_DwUin,
			"ServerId":          conf.Server.ServerID,
			"Price":             chargeCfg.GetMoneyCharge(ChargeId),
			"PayType":           3,
			"OrderId":           "gm",
			"PayChannelOrderId": "gm",
			"CreateTime":        GoUtil.Now(),
			"PayTime":           GoUtil.Now(),
		})
		Charge(player, ChargeId)
	case "resetFace":
		FaceMod := player.PlayMod.getFaceMod()
		FaceMod.List = nil
		FaceMod.InitData()

		AvatarMod := player.PlayMod.getAvatarMod()
		AvatarMod.List = nil
		AvatarMod.InitData()
	case "createOrder":
		Lv := player.GetPlayerBaseMod().GetLevel()
		EmitList := player.PlayMod.getChessMod().GetEmitList()
		EnergyMul := player.PlayMod.getBaseMod().GetEnergyMul()
		OrderMod := player.PlayMod.getOrderMod()
		OrderMod.LastOrder.Type = 1
		OrderMod.CreateOrder(Lv, EmitList, EnergyMul)
		player.PushClientRes(player.PlayMod.getOrderMod().BackData())
	case "resetCardReq":
		CardMod := player.PlayMod.getCardMod()
		CardMod.ReqFriend = make(map[int]*card.CardInfo)
		CardMod.ExCard = make(map[int]*card.CardInfo)
		CardMod.ExTimes = 10
		CardMod.ReqTimes = 10
		player.AddCard(1)
		player.AddCard(2)
		player.AddCard(3)
		FriendMod := player.PlayMod.getFriendMod()
		FriendMod.Card = make(map[string]*card.CardInfo)
		player.PushClientRes(CardMod.NotifyCard())
	case "subCard":
		ChargeId, _ := strconv.Atoi(arg[1])
		CardMod := player.PlayMod.getCardMod()
		player.SubCard(ChargeId)
		player.PushClientRes(CardMod.NotifyCard())
	case "setProgress":
		num, _ := strconv.Atoi(arg[1])
		player.PlayMod.getLimitedTimeEventMod().Progress = num
	case "setProgressReward":
		BaseMod := player.PlayMod.getBaseMod()
		LimitedTimeEventMod := player.PlayMod.getLimitedTimeEventMod()
		LimitedTimeEventMod.Progress = 5
		for i := 1; i < 5; i++ {
			LimitedTimeEventMod.AddProgress(BaseMod.GetLevel())
		}
		player.PushClientRes(LimitedTimeEventMod.ProgressBackData())
	case "champshipGroup":
		G_GameLogicPtr.ChampshipMgrSend(&MsgMod.Msg{
			Type: MsgMod.HANDLE_TYPE_CHAMPSHIP_GROUP,
		})
	case "clearRank":
		num, _ := strconv.Atoi(arg[1])
		G_GameLogicPtr.RankMgr.ClearRank(num)
	case "resetUserInfo":
		Rank := G_GameLogicPtr.RankMgr.getRank(RANK_TYPE_USER)
		for _, v := range Rank {
			Idstr := strconv.Itoa(v.Uid)
			db.RedisDelKey(Idstr)
			G_GameLogicPtr.GetResSimplePlayerByUid(v.Uid)
		}

	case "champshipZero":
		G_GameLogicPtr.ChampshipMgrSend(&MsgMod.Msg{
			Type: MsgMod.SERVER_ZERO_UPDATE,
		})
	case "resetEmitOrder":
		OrderMod := player.PlayMod.getOrderMod()
		OrderMod.EimtOrder = make(map[string]struct{})
		HandbookMod := player.PlayMod.getHandbookMod()
		delete(HandbookMod.BookList, 125)
	case "deleteOrder":
		Id, _ := strconv.Atoi(arg[1])
		OrderMod := player.PlayMod.getOrderMod()
		delete(OrderMod.OrderList, Id)
		player.PushClientRes(OrderMod.BackData())
	case "miningReload":
		MiningMod := player.PlayMod.getMiningMod()
		MiningMod.ZeroUpdate(-1)
		ActivityInfo := GetActivityInfo(player, ACT_TYPE_MINING)
		MiningMod.ZeroUpdate(ActivityInfo.Id)
		MiningBackData(player)
	case "guessColorReload":
		GuessColorMod := player.PlayMod.getGuessColorMod()
		GuessColorMod.ZeroUpdate(-1)
		ActivityInfo := GetActivityInfo(player, ACT_TYPE_GUESS_COLOR)
		GuessColorMod.ZeroUpdate(ActivityInfo.Id)
		GuessColorBackData(player)
	case "raceReload":
		RaceMod := player.PlayMod.getRaceMod()
		RaceMod.ZeroUpdate(-1)
		ActivityInfo := GetActivityInfo(player, ACT_TYPE_RACE)
		RaceMod.ZeroUpdate(ActivityInfo.Id)
	case "playroomTrigger":
		PlayroomOrderTrigger(player)
	case "playroomReset":
		PlayroomMod := playroom.PlayroomMod{}
		PlayroomMod.InitData()
		player.PlayMod.mod_list.Playroom = PlayroomMod
	case "playroomCollect":
		CollectList := playroomCfg.GetDecorateList()
		PlayroomMod := player.PlayMod.getPlayroomMod()
		PlayroomMod.Collect = make(map[int]int)
		for _, v := range CollectList {
			PlayroomMod.AddCollect(v)
		}
	case "resetRetire":
		ChessMod := player.PlayMod.getChessMod()
		ChessMod.Retire = make(map[string]int)
		ChessMod.RetireChessMap = make(map[string][]int)
	case "addChip":
		PlayroomMod := player.PlayMod.getPlayroomMod()
		PlayroomMod.AddChip()
		player.PushClientRes(PlayroomMod.NotifyLose())
	case "save":
		player.PlayMod.ClearData(player)
	case "outline":
		a := player.GetAgent()
		a.Close()
		player.ClearData()
	case "addFriend":
		FriendMod := player.PlayMod.getFriendMod()
		Uid, _ := strconv.Atoi(arg[1])
		FriendMod.AddFriend(Uid)
	case "addAddCard":
		CardMod := player.PlayMod.getCardMod()
		CardList := cardCfg.GetAllCardId(CardMod.Round)
		for _, v := range CardList {
			player.AddCard(v)
		}
	case "resetRankUser":
		O := G_GameLogicPtr.RankMgr.getAllRank(RANK_TYPE_USER)
		for _, v := range O {
			Uid := strconv.Itoa(v.Uid)
			TimeSort := fmt.Sprintf("0.%d", RANK_TIME_SORT-GoUtil.Now())
			TimeSortF, _ := strconv.ParseFloat(TimeSort, 64)
			db.RedisZAdd(RANK_USER, Uid, v.Score+TimeSortF)
		}
	case "addFriendStar":
		FriendTreasureMod := player.PlayMod.getFriendTreasureMod()
		FriendTreasureMod.AddStar(200)
	case "comfortOrder":
		BaseMod := player.PlayMod.getBaseMod()
		BaseMod.LogoutTime = GoUtil.Now() - 7*86400
		TriggerComfortOrder(player)
		player.PushClientRes(player.PlayMod.getOrderMod().BackData())
	case "setDecorateArea":
		S, _ := strconv.Atoi(arg[1])
		DecorateMod := player.PlayMod.getDecorateMod()
		DecorateMod.AreaId = S
		DecorateMod.FinishList = make(map[int]struct{})
		DecorateMod.Progress = 0
	case "resetCardSeasonFirst":
		CardMod := player.PlayMod.getCardMod()
		CardMod.SeasonFirst = false
	case "addPhysiology":
		PlayroomMod := player.PlayMod.getPlayroomMod()
		Type, _ := strconv.Atoi(arg[1])
		Num, _ := strconv.Atoi(arg[2])
		PlayroomMod.AddPhysiology(Type, Num)
	case "resetTriggerTime":
		PlayroomMod := player.PlayMod.getPlayroomMod()
		PlayroomMod.TriggerTime = 0
	case "resetTimeline":
		FriendMod := player.PlayMod.getFriendMod()
		FriendMod.Log = make([]*friend.LogInfo, 0)
	case "resetFastCD":
		LimitedTimeEventMod := player.PlayMod.getLimitedTimeEventMod()
		LimitedTimeEventMod.ResetFastProduceCD()
		EndTime, Times := LimitedTimeEventMod.GetFastProduceInfo()
		player.PushClientRes(&msg.ResFastProduceInfo{
			EndTime: int32(EndTime),
			Num:     int32(Times),
		})
	case "recoverUser":
		file, err := os.OpenFile(conf.Server.GameConfPath+"user.info", os.O_RDWR|os.O_CREATE, 0666)
		if err != nil {
			log.Error("Failed to open user.info file: %v", err)
			return err
		}
		// file.Write(buf.Bytes())
		defer file.Close()
		Uid := player.M_DwUin
		file.Seek(0, 0)
		decoder := gob.NewDecoder(file)
		modList := PlayerModList{}
		err = decoder.Decode(&modList)
		player.PlayMod.mod_list = modList
		if err != nil {
			log.Error("Failed to decode user.info file: %v", err)
			return err
		}
		BaseMod := player.PlayMod.getBaseMod()
		BaseMod.Uid = Uid
	case "copyUser":
		p1 := new(Player)
		p1.InitPlayer(arg[1])
		BaseMod := p1.PlayMod.getBaseMod()
		BaseMod.Uid = player.M_DwUin
		BaseMod.NickName = player.PlayMod.getBaseMod().NickName
		BaseMod.LoginTime = GoUtil.Now()
		player.PlayMod.mod_list = p1.PlayMod.mod_list

	default:
		return fmt.Errorf("Player %d ReqGmCommand:%v not found", player.M_DwUin, arg)
	}
	log.Debug("Player %d ReqGmCommand:%v", player.M_DwUin, arg)

	player.PlayMod.save()
	return nil
}
