package wevent

import (
	"fmt"
	"time"

	"github.com/474420502/requests"
)

// 和前端交流的事件机制
type EventType string

const (
	UserEmailRegister EventType = "E_USER_EMAIL_REGISTER" // 用户注册
	UserResetToken    EventType = "E_USER_RESET_TOKEN"    // 用户重置密码成功通知
)

// WebsocketEvent 所有事件都必须继承这个结构体
type WebsocketEvent struct {
	Type       EventType `json:"event_type"`  // 事件
	SenderTime time.Time `json:"sender_time"` // 发送的时间, 可能用来统计时间
	TraceId    string    `json:"trace_id"`    // 链路ID
	Code       int       `json:"code"`        // 状态码
	Message    string    `json:"msg"`         // 描述
	Data       any       `json:"data"`        // 关注的数据
}

func CommonNotify(WebsocketAddr, wid string, event *WebsocketEvent) error {

	reqWebsocketAddr := fmt.Sprintf("%s/api/websocket/common_notify", WebsocketAddr)
	tp := requests.Post(reqWebsocketAddr)
	tp.SetBodyJson(requests.M{
		"wid":  wid,
		"data": event,
	})

	wresp, err := tp.Execute()
	if err != nil {
		// logx.Error(err, token.TraceId)
		return err
	}

	result := wresp.Json()

	if !result.Get("code").Exists() {
		return fmt.Errorf("send %s is error", reqWebsocketAddr)
	}

	if result.Get("code").Int() != 200 {
		return fmt.Errorf("%s", result.String())
	}

	return nil
}

// NewWebsocketEvent 创建一个Websocket事件
func NewWebsocketEvent(etype EventType, TraceId string) *WebsocketEvent {
	return &WebsocketEvent{
		Type:       etype,
		SenderTime: time.Now().UTC(),
		TraceId:    TraceId,
	}
}

// NewWebsocketEventSuccess 创建一个Websocket事件伴随Code(200)
func NewWebsocketEventSuccess(etype EventType, TraceId string) *WebsocketEvent {
	return &WebsocketEvent{
		Type:       etype,
		SenderTime: time.Now().UTC(),
		TraceId:    TraceId,
		Code:       200,
		Message:    "success",
	}
}

func (event *WebsocketEvent) WithData(data any) *WebsocketEvent {
	event.Data = data
	return event
}

func (event *WebsocketEvent) WithMessgae(msg string) *WebsocketEvent {
	event.Message = msg
	return event
}

func (event *WebsocketEvent) WithCode(code int) *WebsocketEvent {
	event.Code = code
	return event
}

func (event *WebsocketEvent) WithTraceId(traceId string) *WebsocketEvent {
	event.TraceId = traceId
	return event
}

func (event *WebsocketEvent) WithSenderTime(senderTime time.Time) *WebsocketEvent {
	event.SenderTime = senderTime
	return event
}