package message

import (
	"encoding/json"
	"fmt"
	"sync"
)

// CQMessage 接口定义了所有 CQ 消息必须实现的方法
type CQMessage interface {
	ToCQString() string
	// ParseMessage(data string) error
}

// RawMessage 用于初始解析 JSON 的通用结构
type RawMessage struct {
	Type string          `json:"type"`
	Data json.RawMessage `json:"data"`
}

// messageFactory 用于创建具体的消息实例
type messageFactory func() CQMessage

var (
	messageFactories = make(map[string]messageFactory)
	factoryMutex     sync.RWMutex
)

// RegisterMessageType 注册消息类型和对应的工厂函数
func RegisterMessageType(messageType string, factory messageFactory) {
	factoryMutex.Lock()
	defer factoryMutex.Unlock()
	messageFactories[messageType] = factory
}

// CreateMessage 根据类型创建具体的消息实例
func CreateMessage(messageType string) (CQMessage, error) {
	factoryMutex.RLock()
	factory, exists := messageFactories[messageType]
	factoryMutex.RUnlock()

	if !exists {
		return nil, fmt.Errorf("未知的消息类型: %s", messageType)
	}

	return factory(), nil
}

// ParseCQMessages 解析消息数组
func ParseCQMessages(jsonData []byte) ([]CQMessage, error) {
	var rawMessages []RawMessage
	if err := json.Unmarshal(jsonData, &rawMessages); err != nil {
		return nil, fmt.Errorf("解析 JSON 数组失败: %v", err)
	}

	messages := make([]CQMessage, 0, len(rawMessages))
	for _, raw := range rawMessages {
		msg, err := CreateMessage(raw.Type)
		if err != nil {
			return nil, err
		}

		// 使用类型断言获取具体类型的Data字段
		if v, ok := msg.(interface{ SetData(json.RawMessage) error }); ok {
			if err := v.SetData(raw.Data); err != nil {
				return nil, fmt.Errorf("解析消息数据失败: %v", err)
			}
		} else {
			return nil, fmt.Errorf("消息类型 %s 未实现 SetData 方法", raw.Type)
		}

		messages = append(messages, msg)
	}

	return messages, nil
}
