package qq_message

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

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

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

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

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) (QQMessage, error) {
	factoryMutex.RLock()
	factory, exists := messageFactories[messageType]
	factoryMutex.RUnlock()

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

	return factory(), nil
}

// [map[data:map[chainCount:<nil> id:267 raw:map[chainCount:<nil> doubleHit:<nil> faceBubbleCount:<nil> faceIndex:267 faceText:/头秃 faceType:2 imageType:<nil> msgType:<nil> oldVersionStr:<nil> packId:<nil> pokeFlag:<nil> pokeStrength:<nil> pokeType:<nil> randomType:<nil> resultId:<nil> sourceType:<nil> spokeSummary:<nil> stickerId:<nil> stickerType:<nil> surpriseId:<nil> vaspokeId:<nil> vaspokeMinver:<nil> vaspokeName:<nil>] resultId:<nil>] type:face]]

// ParseStructMessages 解析消息数组
func ParseStructMessages(msgData any) []QQMessage {
	log.Println("解析消息数组:", msgData)
	switch msgData := msgData.(type) {
	case []map[string]any:
		msgArray := msgData
		messages := make([]QQMessage, 0, len(msgArray))
		for _, raw := range msgArray {
			msg, err := CreateMessage(raw["type"].(string))
			if err != nil {
				log.Println("创建消息失败:", err)
				continue
			}
			dataByte, _ := json.Marshal(raw["data"])
			// 使用类型断言获取具体类型的Data字段
			if v, ok := msg.(interface{ SetData(json.RawMessage) error }); ok {
				if err := v.SetData(dataByte); err != nil {
					// return nil, fmt.Errorf("解析消息数据失败: %v", err)
					log.Println("解析消息数据失败:", err)
					continue
				}
			} else {
				log.Printf("消息类型 %s 未实现 SetData 方法\n", raw["type"])
				continue
			}

			messages = append(messages, msg)
		}
		log.Println("解析出的QQ消息数组:", messages)
		return messages
	case string:
		return []QQMessage{NewTextMessage().ParseMessage(msgData)}
	}
	return nil
}
