package entities

import (
	"time"

	"github.com/google/uuid"
)

// MPCMessage represents an MPC protocol message
type MPCMessage struct {
	ID          uuid.UUID
	SessionID   uuid.UUID
	FromParty   string
	ToParties   []string // nil means broadcast
	RoundNumber int
	MessageType string
	Payload     []byte // Encrypted MPC message (router does not decrypt)
	CreatedAt   time.Time
	DeliveredAt *time.Time
}

// NewMPCMessage creates a new MPC message
func NewMPCMessage(
	sessionID uuid.UUID,
	fromParty string,
	toParties []string,
	roundNumber int,
	messageType string,
	payload []byte,
) *MPCMessage {
	return &MPCMessage{
		ID:          uuid.New(),
		SessionID:   sessionID,
		FromParty:   fromParty,
		ToParties:   toParties,
		RoundNumber: roundNumber,
		MessageType: messageType,
		Payload:     payload,
		CreatedAt:   time.Now().UTC(),
	}
}

// IsBroadcast checks if the message is a broadcast
func (m *MPCMessage) IsBroadcast() bool {
	return len(m.ToParties) == 0
}

// IsFor checks if the message is for a specific party
func (m *MPCMessage) IsFor(partyID string) bool {
	if m.IsBroadcast() {
		// Broadcast is for everyone except sender
		return m.FromParty != partyID
	}

	for _, to := range m.ToParties {
		if to == partyID {
			return true
		}
	}
	return false
}

// MarkDelivered marks the message as delivered
func (m *MPCMessage) MarkDelivered() {
	now := time.Now().UTC()
	m.DeliveredAt = &now
}

// IsDelivered checks if the message has been delivered
func (m *MPCMessage) IsDelivered() bool {
	return m.DeliveredAt != nil
}

// ToDTO converts to DTO
func (m *MPCMessage) ToDTO() MessageDTO {
	return MessageDTO{
		ID:          m.ID.String(),
		SessionID:   m.SessionID.String(),
		FromParty:   m.FromParty,
		ToParties:   m.ToParties,
		IsBroadcast: m.IsBroadcast(),
		RoundNumber: m.RoundNumber,
		MessageType: m.MessageType,
		Payload:     m.Payload,
		CreatedAt:   m.CreatedAt.UnixMilli(),
	}
}

// MessageDTO is a data transfer object for messages
type MessageDTO struct {
	ID          string   `json:"id"`
	SessionID   string   `json:"session_id"`
	FromParty   string   `json:"from_party"`
	ToParties   []string `json:"to_parties,omitempty"`
	IsBroadcast bool     `json:"is_broadcast"`
	RoundNumber int      `json:"round_number"`
	MessageType string   `json:"message_type"`
	Payload     []byte   `json:"payload"`
	CreatedAt   int64    `json:"created_at"`
}
