package controller

import (
	"strings"

	"be.ems/src/framework/i18n"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/reqctx"
	"be.ems/src/framework/resp"
	"be.ems/src/framework/utils/parse"
	"be.ems/src/modules/ws/service"

	"github.com/gin-gonic/gin"
)

// NewWSController 实例化控制层 WSController 结构体
var NewWSController = &WSController{
	wsService:        service.NewWS,
	wsSendService:    service.NewWSSend,
	wsReceiveService: service.NewWSReceive,
}

// WSController WebSocket通信
//
// PATH /ws
type WSController struct {
	wsService        *service.WS        // WebSocket 服务
	wsSendService    *service.WSSend    // WebSocket消息发送 服务
	wsReceiveService *service.WSReceive // WebSocket消息接收 服务
}

// WS 通用
//
// GET /?subGroupIDs=0
//
//	@Tags			ws
//	@Accept			json
//	@Produce		json
//	@Param			subGroupID		query		string	false	"Subscribe to message groups, multiple separated by commas"
//	@Param			access_token	query		string	false	"Authorization tokens are used when it is inconvenient to pass parameters through the header."
//	@Success		200				{object}	object	"Response Results"
//	@Summary		(ws://) Generic
//	@Description	(ws://) Generic
//	@Router			/ws [get]
func (s *WSController) WS(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)

	// 登录用户信息
	loginUser, err := reqctx.LoginUser(c)
	if err != nil {
		c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, i18n.TKey(language, err.Error())))
		return
	}

	// 订阅消息组
	var subGroupIDs []string
	subGroupIDStr := c.Query("subGroupID")
	if subGroupIDStr != "" {
		// 处理字符转id数组后去重
		ids := strings.Split(subGroupIDStr, ",")
		uniqueIDs := parse.RemoveDuplicates(ids)
		if len(uniqueIDs) > 0 {
			subGroupIDs = uniqueIDs
		}
	}

	// 将 HTTP 连接升级为 WebSocket 连接
	conn := s.wsService.UpgraderWs(c.Writer, c.Request)
	if conn == nil {
		return
	}
	defer conn.Close()

	wsClient := s.wsService.ClientCreate(loginUser.UserId, subGroupIDs, conn, nil)
	go s.wsService.ClientWriteListen(wsClient)
	go s.wsService.ClientReadListen(wsClient, s.wsReceiveService.Commont)

	// 等待停止信号
	for value := range wsClient.StopChan {
		s.wsService.ClientClose(wsClient.ID)
		logger.Infof("ws Stop Client UID %d %s", wsClient.BindUid, value)
		return
	}
}

// Test 测试
//
// GET /test?clientId=xxx&groupID=xxx
func (s *WSController) Test(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)

	// 登录用户信息
	loginUser, err := reqctx.LoginUser(c)
	if err != nil {
		c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, i18n.TKey(language, err.Error())))
		return
	}

	errMsgArr := []string{}

	clientId := c.Query("clientId")
	if clientId != "" {
		err := s.wsSendService.ByClientID(c.Query("clientId"), loginUser)
		if err != nil {
			errMsgArr = append(errMsgArr, "clientId: "+err.Error())
		}
	}

	groupID := c.Query("groupID")
	if groupID != "" {
		err := s.wsSendService.ByGroupID(c.Query("groupID"), loginUser)
		if err != nil {
			errMsgArr = append(errMsgArr, "groupID: "+err.Error())
		}
	}

	c.JSON(200, resp.OkData(errMsgArr))
}
