package agentmanager

import (
	"time"

	"github.com/name5566/leaf/gate"
	"github.com/name5566/leaf/log"
)

var (
	// 未认证连接池
	pendingConns = make(map[gate.Agent]*PendingConn)
	// 已认证用户
	authedUsers = make(map[string]gate.Agent) // key: userID
)

const (
	ConnStatusUnauth = iota // 未认证
	ConnStatusAuthed        // 已认证
)

// 未认证连接管理
type PendingConn struct {
	Agent      gate.Agent
	CreateTime int64
	Status     int
}

func NewAgent(args []interface{}) {
	agent := args[0].(gate.Agent)
	//将新连接放入未认证池
	pendingConns[agent] = &PendingConn{
		Agent:      agent,
		CreateTime: time.Now().Unix(),
		Status:     ConnStatusUnauth,
	}
	go checkTimeout(agent)
}

func CloseAgent(args []interface{}) {
	agent := args[0].(gate.Agent)
	// 清理未认证连接
	_, exists := pendingConns[agent]
	if exists {
		delete(pendingConns, agent)
	}
	// 清理已认证连接
	for userID, a := range authedUsers {
		if a == agent {
			// a.SetUserData(&common.UserData{
			// 	Id:       userID,
			// 	Nickname: userID,
			// 	Status:   0,
			// })
			delete(authedUsers, userID)
			break
		}
	}
}

// 定时检查超时连接
func checkTimeout(agent gate.Agent) {
	timeout := 30 * time.Second
	timer := time.NewTimer(timeout)
	defer timer.Stop()

	select {
	case <-timer.C:
		// 检查是否仍在未认证池中
		if conn, exists := pendingConns[agent]; exists {
			if conn.Status == ConnStatusUnauth {
				// 超时未认证，关闭连接
				log.Debug("Connection timeout without auth, closing...")
				agent.Close()
				delete(pendingConns, agent)
			}
		}
	}
}

// 是否有账号登陆
func IsAuthedUsers(userID string, agent gate.Agent) (bool, gate.Agent) {
	// 处理可能的重复登录
	if oldAgent, exists := authedUsers[userID]; exists && oldAgent != agent {
		return true, oldAgent
	}
	return false, nil
}

// 踢出玩家
func KickAgent(userID string) {
	// 处理可能的重复登录
	if oldAgent, exists := authedUsers[userID]; exists {
		oldAgent.Close()
		delete(authedUsers, userID)
	}
}

// 设置认证状态
func AgentConnStatusAuthed(agent gate.Agent) {
	pendingConns[agent].Status = ConnStatusAuthed
}

// 添加到用户列表
func AddAuthedUsers(userID string, agent gate.Agent) {
	authedUsers[userID] = agent
}

func GetAgentByUserID(userID string) gate.Agent {
	return authedUsers[userID]
}

func GetUserIDByAgent(agent gate.Agent) string {
	for k, v := range authedUsers {
		if v == agent {
			return k
		}
	}
	return ""
}
