package syseventhub

import (
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxutils/eventhub"
	"git.rosy.net.cn/jx-callback/globals/api"
)

const (
	EventCategory = "sys"

	EventTypeWXToken     = "wxToken"
	EventTypeWX2Token    = "wx2Token"
	EventTypeWX3Token    = "wx3Token"
	EventTypePushToken   = "pushToken"
	EventTypeYLYToken    = "ylyToken"
	EventTypeWeimobToken = "weimobToken"
)

type Hub struct {
	eventHub *eventhub.EventHub
}

type Criteria struct {
}

type TokenInfo struct {
	IsNew bool   `json:"isNew"`
	Token string `json:"token"`
}

var (
	SysEventHub *Hub
)

func init() {
	SysEventHub = New()
}

func New() (hub *Hub) {
	hub = &Hub{
		eventHub: eventhub.New(),
	}
	hub.eventHub.RegisterProducer(EventCategory, hub)
	return hub
}

func (h *Hub) IsCriteriaMatch(eventInfo *eventhub.EventInfo, criteria interface{}) bool {
	return true
}

func (h *Hub) OnNewWXToken(token string) {
	h.eventHub.PostNewEvent(EventCategory, &eventhub.EventInfo{
		Type: EventTypeWXToken,
		Data: token,
	})
}

func (h *Hub) OnNewWX2Token(token string) {
	h.eventHub.PostNewEvent(EventCategory, &eventhub.EventInfo{
		Type: EventTypeWX2Token,
		Data: token,
	})
}

func (h *Hub) OnNewPushToken(token string) {
	h.eventHub.PostNewEvent(EventCategory, &eventhub.EventInfo{
		Type: EventTypePushToken,
		Data: token,
	})
}

func (h *Hub) OnNewWX3Token(token string) {
	h.eventHub.PostNewEvent(EventCategory, &eventhub.EventInfo{
		Type: EventTypeWX3Token,
		Data: token,
	})
}

func (h *Hub) OnNewYLYToken(token string) {
	h.eventHub.PostNewEvent(EventCategory, &eventhub.EventInfo{
		Type: EventTypeYLYToken,
		Data: token,
	})
}

func (h *Hub) OnNewWeimobToken(token string) {
	h.eventHub.PostNewEvent(EventCategory, &eventhub.EventInfo{
		Type: EventTypeWeimobToken,
		Data: token,
	})
}

func (h *Hub) GetToken(tokenType, oldToken string, waitTime time.Duration) (tokenInfo *TokenInfo) {
	var token string
	switch tokenType {
	case EventTypeWXToken:
		token = api.WeixinAPI.CBGetToken()
	case EventTypeYLYToken:
		token = api.YilianyunAPI.GetToken()
	case EventTypeWeimobToken:
		if weimobToken := api.WeimobAPI.GetToken(); weimobToken != nil {
			token = string(utils.MustMarshal(weimobToken))
		}
	case EventTypePushToken:
		token, _ = api.UniAppApi.CheckTokenIsExpire()
	case EventTypeWX2Token:
		token = api.WeixinMiniAPI2.CBGetToken()
	}

	if token != oldToken {
		tokenInfo = &TokenInfo{
			IsNew: false,
			Token: token,
		}
	} else {
		eventInfo, err := h.eventHub.GetEvent(EventCategory, []string{tokenType}, nil, waitTime)
		if err == nil && eventInfo != nil {
			tokenInfo = &TokenInfo{
				IsNew: true,
				Token: eventInfo.Data.(string),
			}
		}
	}
	return tokenInfo
}

func (h *Hub) GetWXToken(oldToken string, waitTime time.Duration) (tokenInfo *TokenInfo) {
	return h.GetToken(EventTypeWXToken, oldToken, waitTime)
}

func (h *Hub) GetWX2Token(oldToken string, waitTime time.Duration) (tokenInfo *TokenInfo) {
	return h.GetToken(EventTypeWX2Token, oldToken, waitTime)
}

func (h *Hub) GetYLYToken(oldToken string, waitTime time.Duration) (tokenInfo *TokenInfo) {
	return h.GetToken(EventTypeYLYToken, oldToken, waitTime)
}

func (h *Hub) GetWeimobToken(oldToken string, waitTime time.Duration) (tokenInfo *TokenInfo) {
	return h.GetToken(EventTypeWeimobToken, oldToken, waitTime)
}

func (h *Hub) GetPushToken(oldToken string, waitTime time.Duration) (tokenInfo *TokenInfo) {
	return h.GetToken(EventTypePushToken, oldToken, waitTime)
}
