// Package roomtime defines user-scoped in-room duration facts.
package roomtime

const (
	// RoomUserJoinedEventType opens an in-room session when the durable outbox fact arrives.
	RoomUserJoinedEventType = "RoomUserJoined"
	// RoomUserLeftEventType closes an in-room session on voluntary or stale-swept leave.
	RoomUserLeftEventType = "RoomUserLeft"
	// RoomUserKickedEventType closes an in-room session; kick/system evict/close room 只发该事实，不再补 RoomUserLeft。
	RoomUserKickedEventType = "RoomUserKicked"

	// SessionStatusOpen means the user is considered inside the room by the read model.
	SessionStatusOpen = "open"
	// SessionStatusEnded is terminal and must never be reopened by replayed events.
	SessionStatusEnded = "ended"

	// EventTypeUserRoomDailyStatsUpdated is emitted for each UTC day touched by a closed session.
	EventTypeUserRoomDailyStatsUpdated = "UserRoomDailyStatsUpdated"

	// EndReasonLeft closes a session from RoomUserLeft.
	EndReasonLeft = "left"
	// EndReasonKicked closes a session from RoomUserKicked（含系统驱逐与关房清场）.
	EndReasonKicked = "kicked"
	// EndReasonSupersededByJoin closes a lingering open session in another room when a newer join arrives.
	EndReasonSupersededByJoin = "superseded_by_join"
	// EndReasonSupersededByRejoin closes a lingering open session in the same room when a newer join arrives.
	EndReasonSupersededByRejoin = "superseded_by_rejoin"
	// EndReasonOrphanLeft closes a session synthesized from a leave fact that arrived before its join fact.
	EndReasonOrphanLeft = "orphan_left"

	// CompensationReasonOpenSessionMaxWindow closes open sessions at a configured safety ceiling.
	CompensationReasonOpenSessionMaxWindow = "compensated_open_session_max_window"
)

// RoomPresenceEvent is the decoded room presence fact used by user-service in-room duration aggregation.
type RoomPresenceEvent struct {
	AppCode      string
	EventID      string
	EventType    string
	RoomID       string
	RoomVersion  int64
	OccurredAtMs int64
	// UserID is the presence subject: RoomUserJoined/RoomUserLeft 的 user_id，RoomUserKicked 的 target_user_id。
	UserID int64
	// IsRobot 只在 RoomUserJoined 上有意义，会话开启时固化，机器人会话不产生统计事实。
	IsRobot bool
}

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

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

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