// Package mictime defines user-scoped microphone duration facts.
package mictime

const (
	// RoomMicChangedEventType is the room-service outbox event consumed by this read model.
	RoomMicChangedEventType = "RoomMicChanged"

	// ActionUp opens a mic session and starts seat occupation time.
	ActionUp = "up"
	// ActionPublishConfirmed starts effective microphone online time for an open session.
	ActionPublishConfirmed = "publish_confirmed"
	// ActionChange moves the occupied seat without splitting duration.
	ActionChange = "change"
	// ActionDown closes a session and rolls duration into daily/lifetime aggregates.
	ActionDown = "down"

	// PublishStatePending means the user occupies a business mic seat but has not confirmed RTC audio.
	PublishStatePending = "pending_publish"
	// PublishStatePublishing means RTC audio has been confirmed for the session.
	PublishStatePublishing = "publishing"
	// PublishStateIdle means the seat has been released.
	PublishStateIdle = "idle"

	// SessionStatusPendingPublish is persisted before RTC audio confirmation.
	SessionStatusPendingPublish = "pending_publish"
	// SessionStatusPublishing is persisted after publish_confirmed.
	SessionStatusPublishing = "publishing"
	// SessionStatusEnded is terminal and must never be reopened by replayed events.
	SessionStatusEnded = "ended"

	// EventTypeUserMicSessionClosed is emitted after a session is closed and aggregates are durable.
	EventTypeUserMicSessionClosed = "UserMicSessionClosed"
	// EventTypeUserMicDailyStatsUpdated is emitted for each UTC day touched by a closed session.
	EventTypeUserMicDailyStatsUpdated = "UserMicDailyStatsUpdated"
	// EventTypeUserMicLifetimeStatsUpdated is emitted when lifetime totals receive one session delta.
	EventTypeUserMicLifetimeStatsUpdated = "UserMicLifetimeStatsUpdated"

	// CompensationReasonPendingPublishTimeout closes pending sessions whose expected room-service timeout event never arrived.
	CompensationReasonPendingPublishTimeout = "compensated_publish_timeout"
	// CompensationReasonPublishingMaxWindow closes publishing sessions at a configured safety ceiling.
	CompensationReasonPublishingMaxWindow = "compensated_publishing_max_window"
)

// RoomMicEvent is the decoded RoomMicChanged fact used by user-service duration aggregation.
type RoomMicEvent struct {
	AppCode            string
	EventID            string
	EventType          string
	RoomID             string
	RoomVersion        int64
	OutboxCreatedAtMs  int64
	OccurredAtMs       int64
	ActorUserID        int64
	TargetUserID       int64
	FromSeat           int32
	ToSeat             int32
	Action             string
	MicSessionID       string
	PublishState       string
	Reason             string
	PublishDeadlineMs  int64
	PublishEventTimeMs int64
}

// ApplyResult describes one idempotent event application.
type ApplyResult struct {
	Consumed bool
	Skipped  bool
	Closed   bool
	Reason   string
}

// CompensationOptions bounds abnormal open sessions so missing down events cannot accumulate forever.
type CompensationOptions struct {
	NowMs                     int64
	BatchSize                 int
	PendingPublishMaxAgeMs    int64
	PublishingSessionMaxAgeMs int64
}

// CompensationResult summarizes one compensation scan.
type CompensationResult struct {
	ClosedCount             int
	PendingPublishClosed    int
	PublishingSessionClosed int
}

// LifetimeStats is the user-wide aggregate consumed by host tasks and profile views.
type LifetimeStats struct {
	AppCode        string
	UserID         int64
	SeatOccupiedMs int64
	MicOnlineMs    int64
	SessionCount   int64
	FirstMicAtMs   int64
	LastMicAtMs    int64
	UpdatedAtMs    int64
}
