package steamplaying

import (
	"fmt"
	"log"
	"regexp"
	"strings"
	"time"

	"git.lxtend.com/lixiangwuxian/qqbot/action"
	"git.lxtend.com/lixiangwuxian/qqbot/config"
	"git.lxtend.com/lixiangwuxian/qqbot/constants"
	"git.lxtend.com/lixiangwuxian/qqbot/handler"
	"git.lxtend.com/lixiangwuxian/qqbot/model"
	"git.lxtend.com/lixiangwuxian/qqbot/util"
)

// 用于记录玩家退出游戏的信息
type GameExitInfo struct {
	GameID   string    // 游戏ID
	ExitTime time.Time // 退出时间
}

func init() {
	// Register the handler with the server
	handler.RegisterHandler("绑steam", bindSteam, constants.LEVEL_USER)
	handler.RegisterHelpInform("绑steam", "steam", "输入steamID，绑定您的steam账号。可以通过客户端右上角-账户明细 https://store.steampowered.com/account/ 查看，steamID位于页面左上角")
	handler.RegisterHandler("启用上号通知", bindSteamInGroup, constants.LEVEL_USER)
	handler.RegisterHelpInform("启用上号通知", "steam", "在群内启用您的steam上号通知")
	handler.RegisterHandler("解绑steam", unbindSteam, constants.LEVEL_USER)
	handler.RegisterHelpInform("解绑steam", "steam", "解绑您的steam账号，并解绑所有群监听")
	handler.RegisterHandler("禁用上号通知", unbindSteamInGroup, constants.LEVEL_USER)
	handler.RegisterHelpInform("禁用上号通知", "steam", "禁用您在本群的steam上号通知")
	handler.RegisterHandler("查房", checkSteamPlaying, constants.LEVEL_USER)
	handler.RegisterHelpInform("查房", "steam", "查看群内成员的steam游戏状态")
	go RoundCheckSteamPlaying()
}

func bindSteam(msg model.Message) *model.Reply {
	token := util.SplitN(msg.RawMsg, 2)
	if len(token) < 2 {
		return &model.Reply{
			ReplyMsg:       "请输入steamID",
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	} else {
		re := regexp.MustCompile(`https://steamcommunity\.com/profiles/([0-9]+)`)
		steamIdInUrl := re.FindStringSubmatch(token[1])
		if steamIdInUrl != nil {
			token[1] = steamIdInUrl[1]
		}
		if valid, err := checkSteamIDValid(token[1]); !valid {
			return &model.Reply{
				ReplyMsg:       fmt.Sprintf("steamID无效: %v", err),
				ReferOriginMsg: true,
				FromMsg:        msg,
			}
		} else if err != nil {
			return &model.Reply{
				ReplyMsg:       fmt.Sprintf("steamID验证失败: %v", err),
				ReferOriginMsg: true,
				FromMsg:        msg,
			}
		}
		if err := bindSteamUser(msg.UserId, token[1]); err != nil {
			return &model.Reply{
				ReplyMsg:       fmt.Sprintf("绑定失败: %v", err),
				ReferOriginMsg: true,
				FromMsg:        msg,
			}
		}
	}
	return &model.Reply{
		ReplyMsg:       fmt.Sprintf("绑定steam用户%s成功，如果需要开启群内上号通知，请输入 启用上号通知", token[1]),
		ReferOriginMsg: true,
		FromMsg:        msg,
	}
}

func bindSteamInGroup(msg model.Message) *model.Reply {
	if user, err := getSteamUser(msg.UserId); err != nil {
		return &model.Reply{
			ReplyMsg:       fmt.Sprintf("查询steam绑定失败: %v", err),
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	} else if err := bindUserInGroup(msg.GroupInfo.GroupId, user.SteamID); err != nil {
		return &model.Reply{
			ReplyMsg:       fmt.Sprintf("绑定至群监听列表失败: %v", err),
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	}
	return &model.Reply{
		ReplyMsg:       "绑定至群监听列表成功",
		ReferOriginMsg: true,
		FromMsg:        msg,
	}
}

func unbindSteam(msg model.Message) *model.Reply {
	if user, err := getSteamUser(msg.UserId); err != nil {
		return &model.Reply{
			ReplyMsg:       fmt.Sprintf("解绑失败: %v", err),
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	} else {
		if err := unbindUserInAllGroup(user.SteamID); err != nil {
			return &model.Reply{
				ReplyMsg:       fmt.Sprintf("解绑所有群监听列表失败: %v", err),
				ReferOriginMsg: true,
				FromMsg:        msg,
			}
		}
		if err := unbindSteamUser(msg.UserId); err != nil {
			return &model.Reply{
				ReplyMsg:       fmt.Sprintf("解绑失败: %v", err),
				ReferOriginMsg: true,
				FromMsg:        msg,
			}
		}
	}
	return &model.Reply{
		ReplyMsg:       "解绑成功",
		ReferOriginMsg: true,
		FromMsg:        msg,
	}
}

func unbindSteamInGroup(msg model.Message) *model.Reply {
	if user, err := getSteamUser(msg.UserId); err != nil {
		return &model.Reply{
			ReplyMsg:       fmt.Sprintf("群监听解绑失败: %v", err),
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	} else {
		if err := unbindUserInGroup(msg.GroupInfo.GroupId, user.SteamID); err != nil {
			return &model.Reply{
				ReplyMsg:       fmt.Sprintf("群监听解绑失败: %v", err),
				ReferOriginMsg: true,
				FromMsg:        msg,
			}
		}
	}
	return &model.Reply{
		ReplyMsg:       "群监听解绑成功，本群内将不再查询你的steam游戏状态",
		ReferOriginMsg: true,
		FromMsg:        msg,
	}
}

func checkSteamPlaying(msg model.Message) *model.Reply {
	users, err := getSteamUsersInGroup(msg.GroupInfo.GroupId)
	if err != nil {
		return &model.Reply{
			ReplyMsg:       fmt.Sprintf("获取群成员steam列表失败: %v", err),
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	}
	var steamIds []string
	for _, user := range users {
		steamIds = append(steamIds, user.SteamID)
	}
	gameList, err := checkSteamGameStatus(steamIds)
	if err != nil {
		return &model.Reply{
			ReplyMsg:       fmt.Sprintf("获取游戏列表失败: %v", err),
			ReferOriginMsg: true,
			FromMsg:        msg,
		}
	}
	return &model.Reply{
		ReplyMsg:       gameList,
		ReferOriginMsg: true,
		FromMsg:        msg,
	}
}

func RoundCheckSteamPlaying() {
	once := true
	playingMap := map[string]string{}
	// 记录玩家退出游戏的信息
	exitInfoMap := map[string]GameExitInfo{}

	util.AddCycleTask("checkSteamPlaying", 30*time.Second, 30*time.Second, func() {
		// 检查当前时间是否在凌晨1点至早上8点之间
		now := time.Now()
		hour := now.Hour()
		if hour >= 1 && hour < 8 {
			return
		}

		allSteamIDs, err := getAllSteamID()
		if err != nil {
			log.Printf("获取所有steamID失败: %v\n", err)
			return
		}
		groups, err := getAllGroupID()
		if err != nil {
			log.Printf("获取群列表失败: %v\n", err)
			return
		}
		gamePlayingMap, players, err := checkDiffSteamGameStatus(allSteamIDs, playingMap)
		if err != nil {
			// log.Printf("获取游戏列表失败: %v\n", err)
			return
		}

		// 更新退出游戏信息
		for steamId := range playingMap {
			var currentGameID string
			for _, player := range players {
				if player.SteamID == steamId {
					currentGameID = player.GameID
					break
				}
			}

			if currentGameID == "" { // 玩家退出游戏
				// 从API响应中获取玩家之前的游戏信息
				for _, player := range players {
					if player.SteamID == steamId {
						exitInfoMap[steamId] = GameExitInfo{
							GameID:   player.GameID,
							ExitTime: time.Now(),
						}
						break
					}
				}
			} else { // 玩家在玩游戏
				if oldStatus, exists := playingMap[steamId]; exists && oldStatus != currentGameID {
					// 玩家切换了游戏，清除退出记录
					delete(exitInfoMap, steamId)
				}
			}
		}

		for _, group := range groups {
			time.Sleep(15 * time.Second)
			users, err := getSteamUsersInGroup(group)
			if err != nil {
				log.Println("获取群成员steam列表失败: ", err)
				continue
			}
			var steamIds []string
			for _, user := range users {
				steamIds = append(steamIds, user.SteamID)
			}

			var gameList []string
			for _, steamId := range steamIds {
				if gameStatus, ok := gamePlayingMap[steamId]; ok {
					// 检查是否是30分钟内重新登录同一游戏
					if exitInfo, exists := exitInfoMap[steamId]; exists {
						// 从API响应中获取当前游戏ID
						var currentGameID string
						for _, player := range players {
							if player.SteamID == steamId {
								currentGameID = player.GameID
								break
							}
						}
						if exitInfo.GameID == currentGameID && time.Since(exitInfo.ExitTime) <= 30*time.Minute {
							// 30分钟内重新登录同一游戏，更新退出时间并跳过通知
							exitInfoMap[steamId] = GameExitInfo{
								GameID:   currentGameID,
								ExitTime: time.Now(),
							}
							continue
						}
						// 清除退出记录
						delete(exitInfoMap, steamId)
					}
					gameList = append(gameList, gameStatus)
				}
			}

			if len(gameList) > 0 && !once {
				msg := model.Reply{
					ReplyMsg:       "速报：\n" + strings.Join(gameList, "\n"),
					ReferOriginMsg: false,
					// FromMsg:        model.Message{GroupInfo: model.GroupInfo{GroupId: group}},
					FromMsg: model.Message{GroupInfo: model.GroupInfo{GroupId: config.ConfigManager.GetConfig().Management.ReportGroup}},
				}
				action.ActionManager.SendMsg(&msg)
			}
		}

		// 更新playingMap
		playingMap = make(map[string]string)
		for _, player := range players {
			if player.GameID != "" {
				playingMap[player.SteamID] = player.GameID
			}
		}

		once = false
	})
}
