package dto

import "time"

// AgentDeliveryCreateOptions carries explicit agent delivery routing controls
// for an existing visible message.
type AgentDeliveryCreateOptions struct {
	InterruptPolicy string `json:"interruptPolicy,omitempty"`
}

// MessageMentionHint carries editor-selected mention identity hints. The
// message store validates these against actual routing recipients before
// persisting them.
type MessageMentionHint struct {
	Type     string         `json:"type"`
	ID       string         `json:"id"`
	Token    string         `json:"token"`
	Metadata map[string]any `json:"metadata,omitempty"`
}

// AppMessageCreateResponse returns the persisted message and any reply thread
// opened as part of the create request.
type AppMessageCreateResponse struct {
	Message     AppMessage          `json:"message"`
	ReplyThread *ReplyThreadSummary `json:"replyThread,omitempty"`
}

// ReplyThreadSummary is the reply-thread summary returned with message create
// responses when the request starts a reply thread.
type ReplyThreadSummary struct {
	ThreadChannelID        string                   `json:"threadChannelId"`
	RootMessageID          string                   `json:"rootMessageId,omitempty"`
	ParentMessagePreview   string                   `json:"parentMessagePreview,omitempty"`
	ParentMessageMetadata  map[string]any           `json:"parentMessageMetadata,omitempty"`
	ParentMessageCreatedAt *time.Time               `json:"parentMessageCreatedAt,omitempty"`
	SubscriptionState      string                   `json:"subscriptionState,omitempty"`
	ReplyCount             int64                    `json:"replyCount"`
	LastReplyAt            *time.Time               `json:"lastReplyAt,omitempty"`
	LastReplyPreview       string                   `json:"lastReplyPreview,omitempty"`
	LastReplyAuthor        string                   `json:"lastReplyAuthor,omitempty"`
	LastReplyAuthorID      string                   `json:"lastReplyAuthorId,omitempty"`
	LastReplyAuthorType    string                   `json:"lastReplyAuthorType,omitempty"`
	ParticipantIDs         []string                 `json:"participantIds"`
	Participants           []ReplyThreadParticipant `json:"participants,omitempty"`
	ParticipantCount       int                      `json:"participantCount"`
	ReplyAuthorIDs         []string                 `json:"replyAuthorIds"`
	ReplyAuthors           []ReplyThreadParticipant `json:"replyAuthors"`
}

// OpenReplyThreadResponse returns the reply-thread summary. The optional
// conversation row is present only for mutations that explicitly affect Inbox state.
type OpenReplyThreadResponse struct {
	ThreadChannelID  string                   `json:"threadChannelId"`
	ReplyCount       int64                    `json:"replyCount"`
	LastReplyAt      *time.Time               `json:"lastReplyAt,omitempty"`
	ParticipantIDs   []string                 `json:"participantIds"`
	Participants     []ReplyThreadParticipant `json:"participants,omitempty"`
	ParticipantCount int                      `json:"participantCount"`
	ReplyAuthorIDs   []string                 `json:"replyAuthorIds"`
	ReplyAuthors     []ReplyThreadParticipant `json:"replyAuthors"`
	Conversation     *ConversationItem        `json:"conversation,omitempty"`
}

// ThreadSubscribeResponse returns the authoritative Inbox conversation row
// affected by a subscribe mutation.
type ThreadSubscribeResponse struct {
	Conversation *ConversationItem `json:"conversation,omitempty"`
}

// ReplyThreadParticipant is a display-ready participant snapshot for reply
// thread summaries. Clients render these directly instead of guessing from a
// partial local people directory.
type ReplyThreadParticipant struct {
	ID            string `json:"id"`
	Type          string `json:"type"`
	DisplayName   string `json:"displayName"`
	AvatarURL     string `json:"avatarUrl,omitempty"`
	MemberID      string `json:"memberId,omitempty"`
	OwnerMemberID string `json:"ownerMemberId,omitempty"`
	OwnerUserID   string `json:"ownerUserId,omitempty"`
	Visibility    string `json:"visibility,omitempty"`
}

// AppMessageReactionMutationRequest adds one reaction to a message.
type AppMessageReactionMutationRequest struct {
	Emoji string `json:"emoji"`
}

// AppMessageReactionListResponse lists message reaction aggregates.
type AppMessageReactionListResponse struct {
	Reactions []MessageReactionAggregate `json:"reactions"`
}

// AppMessageReactionMutationResponse returns mutation status plus current aggregates.
type AppMessageReactionMutationResponse struct {
	Changed   bool                       `json:"changed"`
	Reactions []MessageReactionAggregate `json:"reactions"`
}

// AppMessageRewindResponse acknowledges a successful rewind.
type AppMessageRewindResponse struct {
	OK bool `json:"ok"`
}

// AppMessageRecallResponse returns the actual mode selected by the recall
// endpoint. Mode "recall" is a single-message tombstone; mode "rewind" is the
// conversation suffix tombstone/runtime restore path.
type AppMessageRecallResponse struct {
	OK      bool                         `json:"ok"`
	Mode    string                       `json:"mode"`
	Changed bool                         `json:"changed,omitempty"`
	Message *AppMessage                  `json:"message,omitempty"`
	Rewind  *AppMessageRecallRewindState `json:"rewind,omitempty"`
}

type AppMessageRecallRewindState struct {
	ScopeID           string                         `json:"scopeId"`
	MessageID         string                         `json:"messageId"`
	FromSeq           int64                          `json:"fromSeq"`
	RewoundMessageIDs []string                       `json:"rewoundMessageIds,omitempty"`
	RewoundScopes     []AppMessageRecallRewoundScope `json:"rewoundScopes,omitempty"`
}

type AppMessageRecallRewoundScope struct {
	ScopeID           string   `json:"scopeId"`
	LatestSeq         int64    `json:"latestSeq"`
	RewoundMessageIDs []string `json:"rewoundMessageIds,omitempty"`
}
