package internal

import (
	"server/common"
	"server/msg"
	"server/user"
	"time"

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

func init() {
	skeleton.RegisterChanRPC("NewAgent", rpcNewAgent)
	skeleton.RegisterChanRPC("CloseAgent", rpcCloseAgent)
	skeleton.RegisterChanRPC("handleAuth", handleAuth)
}

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

func rpcCloseAgent(args []interface{}) {
	log.Debug("rpcCloseAgent")

	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 handleAuth(args []interface{}) {
	// 收到的登录消息
	m := args[0].(*msg.ResLogin)
	// 消息的发送者
	a := args[1].(gate.Agent)

	log.Debug("handleAuth: nikeName=%v, userId=%v", m.NikeName, m.UserId)

	// 找到未认证连接
	if pending, exists := pendingConns[a]; exists {
		// 认证成功，移动到已认证池
		delete(pendingConns, a)
		authedUsers[m.UserId] = a
		pending.Status = ConnStatusAuthed

		// 处理可能的重复登录
		if oldAgent, exists := authedUsers[m.UserId]; exists && oldAgent != a {
			oldAgent.Close()
			delete(authedUsers, m.UserId)
		}
		// 获取用户信息 ,如果新用户则创建一个
		userData := user.GetUserInfoById(m.UserId)
		a.SetUserData(&common.UserData{
			Id:       m.UserId,
			Nickname: m.UserId,
			Status:   1,
		})

		// 发送登录成功响应
		a.WriteMsg(&msg.ReqLogin{
			NikeName:   m.UserId,
			UserId:     m.UserId,
			Points:     int32(userData.Points),
			GameStatus: "online",
		})
	}
}

// 定时检查超时连接
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)
			}
		}
	}
}
