// Package user defines the public typed command and response payloads exposed
// at the authenticated Gateway -> User self-service boundary.
package user

import "time"

const (
	// MessageTypeGetMyAccount is the authenticated gateway message type used to
	// read the current regular-user account aggregate.
	MessageTypeGetMyAccount = "user.account.get"

	// MessageTypeUpdateMyProfile is the authenticated gateway message type used
	// to mutate self-service profile fields.
	MessageTypeUpdateMyProfile = "user.profile.update"

	// MessageTypeUpdateMySettings is the authenticated gateway message type used
	// to mutate self-service settings fields.
	MessageTypeUpdateMySettings = "user.settings.update"

	// MessageTypeListMySessions is the authenticated gateway message type used
	// to read the caller's active device sessions.
	MessageTypeListMySessions = "user.sessions.list"

	// MessageTypeRevokeMySession is the authenticated gateway message type used
	// to revoke one of the caller's device sessions.
	MessageTypeRevokeMySession = "user.sessions.revoke"

	// MessageTypeRevokeAllMySessions is the authenticated gateway message type
	// used to revoke every device session belonging to the caller (logout
	// everywhere).
	MessageTypeRevokeAllMySessions = "user.sessions.revoke_all"
)

// GetMyAccountRequest stores the authenticated self-service read request for
// the current regular-user account aggregate.
//
// The request body is intentionally empty because gateway derives user
// identity from the authenticated device session rather than from client
// payload fields.
type GetMyAccountRequest struct{}

// UpdateMyProfileRequest stores the authenticated self-service profile
// mutation request.
type UpdateMyProfileRequest struct {
	// DisplayName stores the requested replacement display name. An empty
	// value resets the stored display name.
	DisplayName string `json:"display_name"`
}

// UpdateMySettingsRequest stores the authenticated self-service settings
// mutation request.
type UpdateMySettingsRequest struct {
	// PreferredLanguage stores the requested BCP 47 language tag.
	PreferredLanguage string `json:"preferred_language"`

	// TimeZone stores the requested IANA time-zone name.
	TimeZone string `json:"time_zone"`
}

// ActorRef stores transport-ready audit actor metadata projected by User
// Service.
type ActorRef struct {
	// Type stores the machine-readable actor type.
	Type string `json:"type"`

	// ID stores the optional stable actor identifier.
	ID string `json:"id,omitempty"`
}

// EntitlementSnapshot stores the transport-ready current entitlement snapshot
// of one account.
type EntitlementSnapshot struct {
	// PlanCode stores the effective entitlement plan code.
	PlanCode string `json:"plan_code"`

	// IsPaid reports whether the effective entitlement is currently paid.
	IsPaid bool `json:"is_paid"`

	// Source stores the machine-readable source that produced the snapshot.
	Source string `json:"source"`

	// Actor stores the audit actor metadata attached to the current snapshot.
	Actor ActorRef `json:"actor"`

	// ReasonCode stores the machine-readable reason attached to the snapshot.
	ReasonCode string `json:"reason_code"`

	// StartsAt stores when the effective state started.
	StartsAt time.Time `json:"starts_at"`

	// EndsAt stores the optional finite entitlement expiry.
	EndsAt *time.Time `json:"ends_at,omitempty"`

	// UpdatedAt stores when the snapshot was last recomputed.
	UpdatedAt time.Time `json:"updated_at"`

	// MaxRegisteredRaceNames mirrors the per-tier quota carried in the
	// backend HTTP response (`backend.EntitlementSnapshot`). Gateway
	// re-validates the response shape with strict-unknown-field
	// decoding, so the field must be present here even when the
	// FlatBuffers schema does not yet carry it.
	MaxRegisteredRaceNames int32 `json:"max_registered_race_names"`
}

// ActiveSanction stores one transport-ready active sanction returned in the
// shared account aggregate.
type ActiveSanction struct {
	// SanctionCode stores the active sanction code.
	SanctionCode string `json:"sanction_code"`

	// Scope stores the machine-readable sanction scope.
	Scope string `json:"scope"`

	// ReasonCode stores the machine-readable sanction reason.
	ReasonCode string `json:"reason_code"`

	// Actor stores the audit actor metadata attached to the sanction.
	Actor ActorRef `json:"actor"`

	// AppliedAt stores when the sanction became active.
	AppliedAt time.Time `json:"applied_at"`

	// ExpiresAt stores the optional planned sanction expiry.
	ExpiresAt *time.Time `json:"expires_at,omitempty"`
}

// ActiveLimit stores one transport-ready active user-specific limit override
// returned in the shared account aggregate.
type ActiveLimit struct {
	// LimitCode stores the active limit code.
	LimitCode string `json:"limit_code"`

	// Value stores the current override value.
	Value int `json:"value"`

	// ReasonCode stores the machine-readable limit reason.
	ReasonCode string `json:"reason_code"`

	// Actor stores the audit actor metadata attached to the limit.
	Actor ActorRef `json:"actor"`

	// AppliedAt stores when the limit became active.
	AppliedAt time.Time `json:"applied_at"`

	// ExpiresAt stores the optional planned limit expiry.
	ExpiresAt *time.Time `json:"expires_at,omitempty"`
}

// Account stores the transport-ready account aggregate shared by User Service
// self-service read and mutation responses.
type Account struct {
	// UserID stores the durable regular-user identifier.
	UserID string `json:"user_id"`

	// Email stores the exact-after-trim login e-mail address.
	Email string `json:"email"`

	// UserName stores the immutable `player-<suffix>` handle assigned at
	// account creation.
	UserName string `json:"user_name"`

	// DisplayName stores the current optional free-text user label.
	DisplayName string `json:"display_name,omitempty"`

	// PreferredLanguage stores the current BCP 47 language tag.
	PreferredLanguage string `json:"preferred_language"`

	// TimeZone stores the current IANA time-zone name.
	TimeZone string `json:"time_zone"`

	// DeclaredCountry stores the optional current effective declared country.
	DeclaredCountry string `json:"declared_country,omitempty"`

	// Entitlement stores the current entitlement snapshot.
	Entitlement EntitlementSnapshot `json:"entitlement"`

	// ActiveSanctions stores the current active sanctions sorted by code.
	ActiveSanctions []ActiveSanction `json:"active_sanctions"`

	// ActiveLimits stores the current active user-specific limits sorted by
	// code.
	ActiveLimits []ActiveLimit `json:"active_limits"`

	// CreatedAt stores when the account was created.
	CreatedAt time.Time `json:"created_at"`

	// UpdatedAt stores when the account was last mutated.
	UpdatedAt time.Time `json:"updated_at"`
}

// AccountResponse stores the success payload shared by the authenticated
// GetMyAccount, UpdateMyProfile, and UpdateMySettings gateway message types.
type AccountResponse struct {
	// Account stores the current account aggregate.
	Account Account `json:"account"`
}

// ErrorBody stores the machine-readable and human-readable failure payload
// mirrored from the User Service trusted internal error envelope.
type ErrorBody struct {
	// Code stores the stable machine-readable failure code.
	Code string `json:"code"`

	// Message stores the client-safe failure message.
	Message string `json:"message"`
}

// ErrorResponse stores the error payload returned by the authenticated
// Gateway -> User boundary when User Service rejects a request semantically.
type ErrorResponse struct {
	// Error stores the mirrored error envelope body.
	Error ErrorBody `json:"error"`
}

// DeviceSession stores the transport-ready snapshot of one device session
// served by the authenticated user-surface session endpoints.
type DeviceSession struct {
	// DeviceSessionID stores the durable device-session identifier.
	DeviceSessionID string `json:"device_session_id"`

	// UserID stores the authenticated user identity bound to the session.
	UserID string `json:"user_id"`

	// Status stores the lifecycle state of the session
	// (`active` or `revoked`).
	Status string `json:"status"`

	// ClientPublicKey stores the standard base64-encoded raw 32-byte
	// Ed25519 client public key, when populated.
	ClientPublicKey string `json:"client_public_key,omitempty"`

	// CreatedAt stores when the session was created.
	CreatedAt time.Time `json:"created_at"`

	// RevokedAt stores when the session was revoked, if revoked.
	RevokedAt *time.Time `json:"revoked_at,omitempty"`

	// LastSeenAt stores when gateway last resolved this session.
	LastSeenAt *time.Time `json:"last_seen_at,omitempty"`
}

// ListMySessionsRequest stores the authenticated self-service "list my
// active sessions" command. The body is intentionally empty.
type ListMySessionsRequest struct{}

// ListMySessionsResponse stores the success payload of MessageTypeListMySessions.
type ListMySessionsResponse struct {
	// Items stores the caller's currently active device sessions.
	Items []DeviceSession `json:"items"`
}

// RevokeMySessionRequest stores the authenticated self-service single
// session revocation request.
type RevokeMySessionRequest struct {
	// DeviceSessionID identifies the device session to revoke. The
	// session must belong to the caller; otherwise the response carries
	// the same error shape as a missing session so foreign session ids
	// cannot be probed.
	DeviceSessionID string `json:"device_session_id"`
}

// RevokeMySessionResponse stores the success payload of
// MessageTypeRevokeMySession.
type RevokeMySessionResponse struct {
	// Session stores the post-revoke snapshot of the affected session.
	Session DeviceSession `json:"session"`
}

// RevokeAllMySessionsRequest stores the authenticated self-service
// "logout everywhere" command. The body is intentionally empty.
type RevokeAllMySessionsRequest struct{}

// DeviceSessionRevocationSummary stores the count of sessions revoked by a
// bulk operation.
type DeviceSessionRevocationSummary struct {
	// UserID identifies the user whose sessions were affected.
	UserID string `json:"user_id"`

	// RevokedCount stores how many sessions transitioned to revoked.
	RevokedCount int `json:"revoked_count"`
}

// RevokeAllMySessionsResponse stores the success payload of
// MessageTypeRevokeAllMySessions.
type RevokeAllMySessionsResponse struct {
	// Summary stores the user_id and revoked_count snapshot.
	Summary DeviceSessionRevocationSummary `json:"summary"`
}
