package websocket

import (
	"time"

	"github.com/google/uuid"
)

// MessageType mendefinisikan tipe-tipe pesan yang valid
type MessageType string

const (
	// Pesan koneksi
	WelcomeMessage    MessageType = "welcome"
	ErrorMessage      MessageType = "error"
	DisconnectMessage MessageType = "disconnect"

	// Pesan kontrol
	PingMessage           MessageType = "ping"
	PongMessage           MessageType = "pong"
	HeartbeatMessage      MessageType = "heartbeat"
	ConnectionTestMessage MessageType = "connection_test"

	// Pesan informasi
	ServerInfoMessage  MessageType = "server_info"
	ClientInfoMessage  MessageType = "client_info"
	OnlineUsersMessage MessageType = "online_users"

	// Pesan komunikasi
	DirectMessage    MessageType = "direct_message"
	RoomMessage      MessageType = "room_message"
	BroadcastMessage MessageType = "broadcast"

	// Pesan database
	DatabaseQueryMessage       MessageType = "database_query"
	DatabaseChangeMessage      MessageType = "database_change"
	DatabaseInsertMessage      MessageType = "db_insert"
	DatabaseCustomQueryMessage MessageType = "db_custom_query"

	// Pesan monitoring
	SystemStatusMessage MessageType = "system_status"
	DataStreamMessage   MessageType = "data_stream"

	// Pesan room management
	JoinRoomMessage    MessageType = "join_room"
	LeaveRoomMessage   MessageType = "leave_room"
	GetRoomInfoMessage MessageType = "get_room_info"

	// Pesan admin
	AdminKickClientMessage MessageType = "admin_kick_client"
	AdminKillServerMessage MessageType = "admin_kill_server"
	GetServerStatsMessage  MessageType = "get_server_stats"
	GetSystemHealthMessage MessageType = "get_system_health"
	AdminClearLogsMessage  MessageType = "admin_clear_logs"

	// Pesan utility
	GetStatsMessage MessageType = "get_stats"
)

// WebSocketMessage menyimpan struktur pesan WebSocket
type WebSocketMessage struct {
	Type      MessageType `json:"type"`
	Data      interface{} `json:"data"`
	Timestamp time.Time   `json:"timestamp"`
	ClientID  string      `json:"client_id,omitempty"`
	MessageID string      `json:"message_id,omitempty"`
	Room      string      `json:"room,omitempty"`
}

// NewWebSocketMessage membuat pesan WebSocket baru
func NewWebSocketMessage(msgType MessageType, data interface{}, clientID, room string) WebSocketMessage {
	return WebSocketMessage{
		Type:      msgType,
		Data:      data,
		Timestamp: time.Now(),
		ClientID:  clientID,
		MessageID: uuid.New().String(),
		Room:      room,
	}
}

// MessageHandler mendefinisikan interface untuk handler pesan
type MessageHandler interface {
	HandleMessage(client *Client, message WebSocketMessage) error
	MessageType() MessageType
}

// MessageRegistry menyimpan registry untuk handler pesan
type MessageRegistry struct {
	handlers map[MessageType]MessageHandler
}

// NewMessageRegistry membuat registry pesan baru
func NewMessageRegistry() *MessageRegistry {
	return &MessageRegistry{
		handlers: make(map[MessageType]MessageHandler),
	}
}

// RegisterHandler mendaftarkan handler untuk tipe pesan tertentu
func (r *MessageRegistry) RegisterHandler(handler MessageHandler) {
	r.handlers[handler.MessageType()] = handler
}

// GetHandler mendapatkan handler untuk tipe pesan tertentu
func (r *MessageRegistry) GetHandler(msgType MessageType) (MessageHandler, bool) {
	handler, exists := r.handlers[msgType]
	return handler, exists
}
