package output

import (
	"context"
)

// MessageBrokerPort defines the output port for message broker operations
type MessageBrokerPort interface {
	// PublishEvent publishes an event to a topic
	PublishEvent(ctx context.Context, topic string, event interface{}) error

	// PublishMessage publishes a message to a specific party's queue
	PublishMessage(ctx context.Context, partyID string, message interface{}) error

	// Subscribe subscribes to a topic and returns a channel of messages
	Subscribe(ctx context.Context, topic string) (<-chan []byte, error)

	// Close closes the connection
	Close() error
}

// Event types
const (
	TopicSessionCreated       = "mpc.session.created"
	TopicSessionStarted       = "mpc.session.started"
	TopicSessionCompleted     = "mpc.session.completed"
	TopicSessionFailed        = "mpc.session.failed"
	TopicSessionExpired       = "mpc.session.expired"
	TopicParticipantJoined    = "mpc.participant.joined"
	TopicParticipantReady     = "mpc.participant.ready"
	TopicParticipantCompleted = "mpc.participant.completed"
	TopicParticipantFailed    = "mpc.participant.failed"
	TopicParticipantTimedOut  = "mpc.participant.timed_out"
	TopicMPCMessage           = "mpc.message"
)

// SessionCreatedEvent is published when a session is created
type SessionCreatedEvent struct {
	SessionID    string   `json:"session_id"`
	SessionType  string   `json:"session_type"`
	ThresholdN   int      `json:"threshold_n"`
	ThresholdT   int      `json:"threshold_t"`
	Participants []string `json:"participants"`
	CreatedBy    string   `json:"created_by"`
	CreatedAt    int64    `json:"created_at"`
	ExpiresAt    int64    `json:"expires_at"`
}

// SessionStartedEvent is published when a session starts
type SessionStartedEvent struct {
	SessionID string `json:"session_id"`
	StartedAt int64  `json:"started_at"`
}

// SessionCompletedEvent is published when a session completes
type SessionCompletedEvent struct {
	SessionID   string `json:"session_id"`
	PublicKey   []byte `json:"public_key,omitempty"`
	CompletedAt int64  `json:"completed_at"`
}

// SessionFailedEvent is published when a session fails
type SessionFailedEvent struct {
	SessionID string `json:"session_id"`
	Reason    string `json:"reason"`
	FailedAt  int64  `json:"failed_at"`
}

// SessionExpiredEvent is published when a session expires
type SessionExpiredEvent struct {
	SessionID string `json:"session_id"`
	ExpiredAt int64  `json:"expired_at"`
}

// ParticipantJoinedEvent is published when a participant joins
type ParticipantJoinedEvent struct {
	SessionID string `json:"session_id"`
	PartyID   string `json:"party_id"`
	JoinedAt  int64  `json:"joined_at"`
}

// ParticipantReadyEvent is published when a participant is ready
type ParticipantReadyEvent struct {
	SessionID string `json:"session_id"`
	PartyID   string `json:"party_id"`
	ReadyAt   int64  `json:"ready_at"`
}

// ParticipantCompletedEvent is published when a participant completes
type ParticipantCompletedEvent struct {
	SessionID   string `json:"session_id"`
	PartyID     string `json:"party_id"`
	CompletedAt int64  `json:"completed_at"`
}

// ParticipantFailedEvent is published when a participant fails
type ParticipantFailedEvent struct {
	SessionID string `json:"session_id"`
	PartyID   string `json:"party_id"`
	Reason    string `json:"reason"`
	FailedAt  int64  `json:"failed_at"`
}

// ParticipantTimedOutEvent is published when a participant times out due to inactivity
type ParticipantTimedOutEvent struct {
	SessionID         string `json:"session_id"`
	PartyID           string `json:"party_id"`
	InactivitySeconds int64  `json:"inactivity_seconds"`
	TimedOutAt        int64  `json:"timed_out_at"`
}

// MPCMessageEvent is published when an MPC message is routed
type MPCMessageEvent struct {
	MessageID   string   `json:"message_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"`
	CreatedAt   int64    `json:"created_at"`
}
