package service

import (
	"encoding/json"
	"fmt"

	"be.ems/src/framework/resp"
	"be.ems/src/modules/ws/model"
)

// 订阅组指定编号为支持服务器向客户端主动推送数据
const (
	// 组号-其他
	GROUP_OTHER = "0"
	// 组号-跟踪任务网元数据变更 2_traceId
	GROUP_TRACE_NE = "2"
	// 组号-信令跟踪Packet 4_taskNo
	GROUP_TRACE_PACKET = "4"
	// 组号-网元状态 8_neType_neId
	GROUP_NE_STATE = "8"
	// 组号-指标通用 10_neType_neId
	GROUP_KPI = "10"
	// 组号-自定义KPI指标 20_neType_neId
	GROUP_KPI_C = "20"
	// 组号-IMS_CDR会话事件 1005_neId
	GROUP_IMS_CDR = "1005"
	// 组号-SMF_CDR会话事件 1006_neId
	GROUP_SMF_CDR = "1006"
	// 组号-SMSC_CDR会话事件 1007_neId
	GROUP_SMSC_CDR = "1007"
	// 组号-SGWC_CDR会话事件 1008_neId
	GROUP_SGWC_CDR = "1008"
	// 组号-AMF_UE会话事件 1010_neId
	GROUP_AMF_UE = "1010"
	// 组号-MME_UE会话事件 1011_neId
	GROUP_MME_UE = "1011"
	// 组号-AMF_NB状态事件 1014_neId
	GROUP_AMF_NB = "1014"
	// 组号-MME_NB状态事件 1015_neId
	GROUP_MME_NB = "1015"
	// 组号-告警 2000_neType_neId
	GROUP_ALARM = "2000"
	// 组号-告警事件 2002_neType_neId
	GROUP_ALARM_EVENT = "2002"
)

// 实例化服务层 WSSend 结构体
var NewWSSend = &WSSend{}

// WSSend WebSocket消息发送处理 服务层处理
type WSSend struct{}

// ByClientID 给已知客户端发消息
func (s *WSSend) ByClientID(clientID string, data any) error {
	v, ok := wsClients.Load(clientID)
	if !ok {
		return fmt.Errorf("no fount client ID: %s", clientID)
	}

	dataByte, err := json.Marshal(resp.OkData(data))
	if err != nil {
		return err
	}

	client := v.(*model.WSClient)
	if len(client.MsgChan) > 90 {
		NewWS.ClientClose(client.ID)
		return fmt.Errorf("msg chan over 90 will close client ID: %s", clientID)
	}
	client.MsgChan <- dataByte
	return nil
}

// ByGroupID 给订阅组的客户端发送消息
func (s *WSSend) ByGroupID(groupID string, data any) error {
	clientIds, ok := wsGroup.Load(groupID)
	if !ok {
		return fmt.Errorf("no fount Group ID: %s", groupID)
	}

	// 检查组内是否有客户端
	ids := clientIds.(*[]string)
	if len(*ids) == 0 {
		return fmt.Errorf("no members in the group")
	}

	// 遍历给客户端发消息
	for _, clientId := range *ids {
		err := s.ByClientID(clientId, map[string]any{
			"groupId": groupID,
			"data":    data,
		})
		if err != nil {
			continue
		}
	}

	return nil
}
