package MessageHandlers

import (
	"context"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
	"wechat-api/internal/pkg/wechat_ws"
	"wechat-api/internal/svc"
)

// MessageHandlerStrategy 消息处理策略接口
type MessageHandlerStrategy interface {
	Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject, svcCtx *svc.ServiceContext) error
}

type MessageHandler struct {
	strategies map[string]MessageHandlerStrategy
	svcCtx     *svc.ServiceContext
}

// NewMessageHandler 创建新的消息调度器
func NewMessageHandler(svcCtx *svc.ServiceContext) *MessageHandler {
	return &MessageHandler{
		strategies: make(map[string]MessageHandlerStrategy),
		svcCtx:     svcCtx,
	}
}

// GetWrappedHandler 返回适配后的 handler，可直接用于 ws.RegisterMessageHandler
func (h *MessageHandler) GetWrappedHandler() func(msg *wechat_ws.MsgJsonObject) error {
	return WrapToSimpleHandler(h.Handle)
}

// RegisterStrategy 注册单个消息处理策略
func (h *MessageHandler) RegisterStrategy(msgType string, strategy MessageHandlerStrategy) {
	h.strategies[msgType] = strategy
}

// RegisterStrategies 批量注册消息处理策略
func (h *MessageHandler) RegisterStrategies() {
	strategyMap := map[string]func(*svc.ServiceContext) MessageHandlerStrategy{
		"FriendPushNotice": toStrategy(NewFriendPushNoticeTypeHandler),
		//"ChatroomPushNotice":     toStrategy(NewChatroomPushNoticeTypeHandler),
		"ContactLabelInfoNotice": toStrategy(NewContactLabelInfoNotice),
	}
	for msgType, strategyFunc := range strategyMap {
		h.RegisterStrategy(msgType, strategyFunc(h.svcCtx))
		logx.Infof("已注册消息处理策略: %s", msgType)
	}
}

// Handle 消息分发逻辑，带 recover 容错
func (h *MessageHandler) Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject) (err error) {
	defer func() {
		if r := recover(); r != nil {
			logx.Errorf("处理消息 msgType=%s 时 panic: %v", msg.MsgType, r)
			err = nil // 防止 panic 向上冒泡
		}
	}()

	strategy, exists := h.strategies[msg.MsgType]
	if !exists {
		logx.Infof("未注册处理器的消息类型: %s，跳过处理", msg.MsgType)
		return nil
	}
	return strategy.Handle(ctx, msg, h.svcCtx)
}

// toStrategy 泛型辅助转换
func toStrategy[T MessageHandlerStrategy](fn func(*svc.ServiceContext) T) func(*svc.ServiceContext) MessageHandlerStrategy {
	return func(svcCtx *svc.ServiceContext) MessageHandlerStrategy {
		return fn(svcCtx)
	}
}

// WrapToSimpleHandler 将带 context 的 handler 包装成简洁 MessageHandler 函数
func WrapToSimpleHandler(handler func(ctx context.Context, msg *wechat_ws.MsgJsonObject) error) func(msg *wechat_ws.MsgJsonObject) error {
	return func(msg *wechat_ws.MsgJsonObject) error {
		// 创建默认上下文（支持自定义扩展）
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()

		return handler(ctx, msg)
	}
}
