package task

import (
	"context"
	"encoding/json"
	"strings"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/core/domain"
)

type PrincipalType string

const (
	PrincipalTypeUser PrincipalType = "user"
)

type ServiceContext struct {
	RequestID      string         `json:"requestId,omitempty"`
	WorkspaceID    string         `json:"workspaceId"`
	Subject        SubjectContext `json:"subject"`
	InstallationID string         `json:"installationId,omitempty"`
	Scopes         []string       `json:"scopes,omitempty"`
}

type SubjectContext struct {
	PrincipalID   string        `json:"principalId"`
	PrincipalType PrincipalType `json:"principalType"`
	MemberID      string        `json:"memberId,omitempty"`
	DisplayName   string        `json:"displayName,omitempty"`
}

func NewUserServiceContext(workspaceID string, userID string, displayName string) ServiceContext {
	return ServiceContext{
		WorkspaceID: strings.TrimSpace(workspaceID),
		Subject: SubjectContext{
			PrincipalID:   strings.TrimSpace(userID),
			PrincipalType: PrincipalTypeUser,
			DisplayName:   strings.TrimSpace(displayName),
		},
	}
}

type BoardRef struct {
	ChannelID string `json:"channelId,omitempty"`
	Channel   string `json:"channel,omitempty"`
}

type TaskRef struct {
	TaskID     string `json:"taskId,omitempty"`
	TaskNumber int64  `json:"taskNumber,omitempty"`
}

type TaskActor struct {
	Type string `json:"type"`
	ID   string `json:"id"`
	Name string `json:"name"`
}

type AuthorProfile struct {
	ActorType      string `json:"actorType"`
	PrincipalID    string `json:"principalId,omitempty"`
	MemberID       string `json:"memberId,omitempty"`
	TargetID       string `json:"targetId,omitempty"`
	DisplayName    string `json:"displayName"`
	AvatarURL      string `json:"avatarUrl,omitempty"`
	ServiceKind    string `json:"serviceKind,omitempty"`
	ServiceSlug    string `json:"serviceSlug,omitempty"`
	ServiceBuiltin bool   `json:"serviceBuiltin,omitempty"`
	Badge          string `json:"badge,omitempty"`
}

type ContributionSource struct {
	Kind      string `json:"kind,omitempty"`
	RefType   string `json:"refType,omitempty"`
	RefID     string `json:"refId,omitempty"`
	RunID     string `json:"runId,omitempty"`
	EventID   string `json:"eventId,omitempty"`
	EventType string `json:"eventType,omitempty"`
	Label     string `json:"label,omitempty"`
}

type MessageReactionReactor struct {
	AuthorProfile *AuthorProfile `json:"authorProfile"`
}

type MessageReactionAggregate struct {
	Emoji    string                   `json:"emoji"`
	Count    int                      `json:"count"`
	Reactors []MessageReactionReactor `json:"reactors,omitempty"`
}

type ResolvedMention struct {
	Token         string `json:"token"`
	Type          string `json:"type"`
	ID            string `json:"id"`
	DisplayName   string `json:"displayName"`
	ResolvedToken string `json:"canonicalToken,omitempty"`
}

type TaskSourceThread struct {
	ThreadChannelID string `json:"threadChannelId,omitempty"`
	ParentChannelID string `json:"parentChannelId"`
	ParentMessageID string `json:"parentMessageId"`
	Ref             string `json:"ref,omitempty"`
}

type TaskFieldValue struct {
	OptionID string `json:"optionId,omitempty"`
	Key      string `json:"key,omitempty"`
	Label    string `json:"label,omitempty"`
	RawValue string `json:"rawValue,omitempty"`
	IsLegacy bool   `json:"isLegacy,omitempty"`
	IsNone   bool   `json:"isNone,omitempty"`
}

type TaskProgressSummary struct {
	Total int64 `json:"total"`
	Done  int64 `json:"done"`
}

type TaskReadState struct {
	UnreadCount            int64      `json:"unreadCount"`
	ManualUnread           bool       `json:"manualUnread"`
	LatestEventID          string     `json:"latestEventId,omitempty"`
	LatestEventCreatedAt   *time.Time `json:"latestEventCreatedAt,omitempty"`
	LastReadEventID        string     `json:"lastReadEventId,omitempty"`
	LastReadEventCreatedAt *time.Time `json:"lastReadEventCreatedAt,omitempty"`
	LastMessageReadSeq     int64      `json:"-"`
	LastActivityReadSeq    int64      `json:"-"`
	ManualUnreadGeneration int64      `json:"-"`
}

type Task struct {
	ID               string     `json:"id"`
	TaskScopeID      string     `json:"taskScopeId,omitempty"`
	ChannelID        string     `json:"channelId"`
	TaskNumber       int64      `json:"taskNumber"`
	Title            string     `json:"title"`
	Status           string     `json:"status"`
	Description      string     `json:"description,omitempty"`
	Kind             string     `json:"kind,omitempty"`
	Priority         string     `json:"priority,omitempty"`
	BlockedReason    string     `json:"blockedReason,omitempty"`
	LastActivityAt   *time.Time `json:"lastActivityAt,omitempty"`
	ArtifactCount    int64      `json:"artifactCount,omitempty"`
	ParentTaskRef    string     `json:"parentTaskRef,omitempty"`
	DiscussionCount  int64      `json:"discussionCount,omitempty"`

	AssigneeProfile    *AuthorProfile      `json:"assigneeProfile,omitempty"`
	KindField          *TaskFieldValue     `json:"kindField,omitempty"`
	PriorityField      *TaskFieldValue     `json:"priorityField,omitempty"`
	CheckpointProgress TaskProgressSummary `json:"checkpointProgress,omitempty"`
	SubtaskProgress    TaskProgressSummary `json:"subtaskProgress,omitempty"`

	CreatedAt time.Time `json:"createdAt"`

	CreatedByProfile *AuthorProfile `json:"createdByProfile,omitempty"`
	CreatedByType    string         `json:"createdByType"`
	CreatedByID      string         `json:"createdById"`
	CreatedByName    string         `json:"createdByName"`

	Source       *ContributionSource `json:"source,omitempty"`
	SourceThread *TaskSourceThread   `json:"sourceThread,omitempty"`
	ReadState    *TaskReadState      `json:"readState,omitempty"`
	AssignedAt   *time.Time          `json:"assignedAt,omitempty"`

	CompletedAt *time.Time `json:"completedAt,omitempty"`
}

type RelatedTaskSignal struct {
	Type      string    `json:"type"`
	Payload   string    `json:"payload,omitempty"`
	CreatedAt time.Time `json:"createdAt"`
}

type RelatedTaskUnread struct {
	Count        int64 `json:"count"`
	ManualUnread bool  `json:"manualUnread,omitempty"`
}

type RelatedTaskCursor struct {
	TaskNumber int64  `json:"taskNumber,omitempty"`
	TaskID     string `json:"taskId,omitempty"`
}

type RelatedTaskRow struct {
	TaskID          string              `json:"taskId"`
	TaskScopeID     string              `json:"taskScopeId,omitempty"`
	ChannelID       string              `json:"channelId"`
	TaskNumber      int64               `json:"taskNumber"`
	Title           string              `json:"title"`
	Status          string              `json:"status"`
	ParentTaskID    string              `json:"parentTaskId,omitempty"`
	ParentTaskRef   string              `json:"parentTaskRef,omitempty"`
	Source          *ContributionSource `json:"source,omitempty"`
	SourceThread    *TaskSourceThread   `json:"sourceThread,omitempty"`
	AssigneeProfile *AuthorProfile      `json:"assigneeProfile,omitempty"`
	LastSignal      *RelatedTaskSignal  `json:"lastSignal,omitempty"`
	Unread          RelatedTaskUnread   `json:"unread"`
	Route           string              `json:"route,omitempty"`
}

type RelatedTasksResponse struct {
	Tasks      []RelatedTaskRow  `json:"tasks"`
	HasMore    bool              `json:"hasMore,omitempty"`
	NextCursor RelatedTaskCursor `json:"nextCursor,omitempty"`
}

type RelatedTasksSummaryResponse struct {
	TaskCount    int64             `json:"taskCount"`
	Unread       RelatedTaskUnread `json:"unread"`
	StatusCounts map[string]int64  `json:"statusCounts,omitempty"`
}

type ListRelatedTasksForThreadRequest struct {
	Context         ServiceContext    `json:"context"`
	ThreadChannelID string            `json:"threadChannelId"`
	Limit           int               `json:"limit,omitempty"`
	Cursor          RelatedTaskCursor `json:"cursor,omitempty"`
	Status          string            `json:"status,omitempty"`
}

type ListRelatedExecutionTasksForAgentRequest struct {
	Context ServiceContext    `json:"context"`
	AgentID string            `json:"agentId"`
	Limit   int               `json:"limit,omitempty"`
	Cursor  RelatedTaskCursor `json:"cursor,omitempty"`
	Status  string            `json:"status,omitempty"`
}

type RelatedExecutionTasksSummaryForAgentRequest struct {
	Context ServiceContext    `json:"context"`
	AgentID string            `json:"agentId"`
	Limit   int               `json:"limit,omitempty"`
	Cursor  RelatedTaskCursor `json:"cursor,omitempty"`
	Status  string            `json:"status,omitempty"`
}

type RelatedTasksSummaryForThreadRequest struct {
	Context         ServiceContext `json:"context"`
	ThreadChannelID string         `json:"threadChannelId"`
}

type TaskView struct {
	TaskScopeID      string         `json:"taskScopeId,omitempty"`
	TaskNumber       int64          `json:"taskNumber"`
	Title            string         `json:"title"`
	Status           string         `json:"status"`
	AssigneeProfile  *AuthorProfile `json:"assigneeProfile,omitempty"`
	CreatedByProfile *AuthorProfile `json:"createdByProfile,omitempty"`
	CreatedByName    string         `json:"createdByName,omitempty"`
}

type CreatedTask struct {
	TaskScopeID string `json:"taskScopeId,omitempty"`
	TaskNumber  int64  `json:"taskNumber"`
	Title       string `json:"title"`
	Reused      bool   `json:"reused,omitempty"`
}

type ClaimResult struct {
	TaskNumber int64  `json:"taskNumber"`
	Success    bool   `json:"success"`
	Reason     string `json:"reason,omitempty"`
}

type TaskChecklistItem struct {
	ID      string `json:"id,omitempty"`
	Text    string `json:"text"`
	Checked bool   `json:"checked,omitempty"`
}

type TaskArtifact struct {
	ID               string          `json:"id"`
	Kind             string          `json:"kind"`
	Title            string          `json:"title,omitempty"`
	Payload          json.RawMessage `json:"payload,omitempty"`
	CreatedByProfile *AuthorProfile  `json:"createdByProfile,omitempty"`
	CreatedByRef     string          `json:"createdByRef,omitempty"`
	CreatedAt        time.Time       `json:"createdAt"`
}

type TaskActivityEvent struct {
	ID            string              `json:"id"`
	Type          string              `json:"type"`
	AuthorProfile *AuthorProfile      `json:"authorProfile,omitempty"`
	Source        *ContributionSource `json:"source,omitempty"`
	// ActorRef, ActorDisplayName, and SourceKind/Source* are retained only as
	// task activity compatibility fields for older task/daemon consumers.
	// Activity identity and provenance are AuthorProfile and Source.
	ActorRef         string    `json:"actorRef,omitempty"`
	ActorDisplayName string    `json:"actorDisplayName,omitempty"`
	Payload          string    `json:"payload,omitempty"`
	SourceKind       string    `json:"sourceKind,omitempty"`
	SourceMessageID  string    `json:"sourceMessageId,omitempty"`
	SourceActivityID string    `json:"sourceActivityId,omitempty"`
	CreatedAt        time.Time `json:"createdAt"`
}

type TaskReviewRequest struct {
	ID                  string          `json:"id"`
	Status              string          `json:"status"`
	RequestedByProfile  *AuthorProfile  `json:"requestedByProfile,omitempty"`
	ReviewerProfile     *AuthorProfile  `json:"reviewerProfile,omitempty"`
	DecidedByProfile    *AuthorProfile  `json:"decidedByProfile,omitempty"`
	RequestedByRef      string          `json:"requestedByRef,omitempty"`
	ReviewerRef         string          `json:"reviewerRef,omitempty"`
	Summary             string          `json:"summary,omitempty"`
	Questions           []string        `json:"questions,omitempty"`
	Decision            string          `json:"decision,omitempty"`
	DecisionSummary     string          `json:"decisionSummary,omitempty"`
	DecisionQuestions   []string        `json:"decisionQuestions,omitempty"`
	DecidedByRef        string          `json:"decidedByRef,omitempty"`
	ReviewTargetType    string          `json:"reviewTargetType,omitempty"`
	ReviewTargetPayload json.RawMessage `json:"reviewTargetPayload,omitempty"`
	RequestedAt         time.Time       `json:"requestedAt"`
	DecidedAt           *time.Time      `json:"decidedAt,omitempty"`
}

type TaskFieldOption struct {
	ID         string   `json:"id"`
	FieldKind  string   `json:"fieldKind"`
	Key        string   `json:"key"`
	Label      string   `json:"label"`
	Aliases    []string `json:"aliases,omitempty"`
	Position   int64    `json:"position"`
	IsActive   bool     `json:"isActive"`
	UsageCount int64    `json:"usageCount"`
}

type TaskBoardViewState struct {
	View                string              `json:"view"`
	SearchQuery         string              `json:"searchQuery"`
	QuickFilters        []string            `json:"quickFilters"`
	StructuredFilters   map[string][]string `json:"structuredFilters"`
	SortMode            string              `json:"sortMode"`
	CardPropertyToggles []string            `json:"cardPropertyToggles"`
	DoneCollapsed       bool                `json:"doneCollapsed"`
}

type TaskDiscussionEntry struct {
	ID            string              `json:"id"`
	TaskID        string              `json:"taskId"`
	Body          string              `json:"body"`
	AuthorProfile *AuthorProfile      `json:"authorProfile"`
	Source        *ContributionSource `json:"source,omitempty"`
	// CreatedBy is retained only as a compatibility adapter for older task
	// consumers; resolved discussion identity is AuthorProfile.
	CreatedBy        TaskActor                  `json:"createdBy"`
	ResolvedMentions []ResolvedMention          `json:"resolvedMentions,omitempty"`
	Reactions        []MessageReactionAggregate `json:"reactions,omitempty"`
	Attachments      []TaskDiscussionAttachment `json:"attachments,omitempty"`
	CreatedAt        time.Time                  `json:"createdAt"`
	UpdatedAt        *time.Time                 `json:"updatedAt,omitempty"`
	EditedAt         *time.Time                 `json:"editedAt,omitempty"`
	// EditedByMemberID and EditRevision are message-substrate fields used by
	// clients to render ordinary edited markers without exposing edit history.
	EditedByMemberID    string                      `json:"editedByMemberId,omitempty"`
	EditRevision        int64                       `json:"editRevision,omitempty"`
	MessagePresentation *domain.MessagePresentation `json:"messagePresentation,omitempty"`
}

type TaskDiscussionAttachment struct {
	ID           string `json:"id"`
	Filename     string `json:"filename"`
	ContentType  string `json:"contentType,omitempty"`
	SizeBytes    int64  `json:"sizeBytes,omitempty"`
	ThumbnailURL string `json:"thumbnailUrl,omitempty"`
}

type TaskTimelineEntry struct {
	ID         string               `json:"id"`
	Kind       string               `json:"kind"`
	CreatedAt  time.Time            `json:"createdAt"`
	Activity   *TaskActivityEvent   `json:"activity,omitempty"`
	Discussion *TaskDiscussionEntry `json:"discussion,omitempty"`
}

type TaskDetail struct {
	Task               Task                `json:"task"`
	ParentTask         *Task               `json:"parentTask,omitempty"`
	Checkpoints        []TaskChecklistItem `json:"checkpoints,omitempty"`
	Timeline           []TaskTimelineEntry `json:"timeline,omitempty"`
	TimelineHasMore    bool                `json:"timelineHasMore,omitempty"`
	TimelineNextCursor TaskTimelineCursor  `json:"timelineNextCursor,omitempty"`
	AcceptanceCriteria []TaskChecklistItem `json:"acceptanceCriteria,omitempty"`
	ReviewChecklist    []TaskChecklistItem `json:"reviewChecklist,omitempty"`
	Subtasks           []Task              `json:"subtasks,omitempty"`
	SubtasksHasMore    bool                `json:"subtasksHasMore,omitempty"`
	SubtasksNextCursor TaskSubtaskCursor   `json:"subtasksNextCursor,omitempty"`
	PinnedMessageRefs  []string            `json:"pinnedMessageRefs,omitempty"`
	RelevantURLs       []string            `json:"relevantURLs,omitempty"`
	WorkspaceRefs      []string            `json:"workspaceRefs,omitempty"`
	ReviewHistory      []TaskReviewRequest `json:"reviewHistory,omitempty"`
	Artifacts          []TaskArtifact      `json:"artifacts,omitempty"`
}

type TaskBrowseCursor struct {
	SortMode        string    `json:"sortMode,omitempty"`
	TaskID          string    `json:"taskId,omitempty"`
	CreatedAt       time.Time `json:"createdAt,omitempty"`
	ActivityAt      time.Time `json:"activityAt,omitempty"`
	Title           string    `json:"title,omitempty"`
	PriorityMissing bool      `json:"priorityMissing,omitempty"`
	PriorityLabel   string    `json:"priorityLabel,omitempty"`
	TaskNumber      int64     `json:"taskNumber,omitempty"`
}

type TaskTimelineCursor struct {
	Seq       int64     `json:"seq,omitempty"`
	CreatedAt time.Time `json:"createdAt,omitempty"`
	ID        string    `json:"id,omitempty"`
}

// TaskSubtaskCursor is the API port's opaque keyset continuation for one
// direct-child page. It carries the last returned row's UTC createdAt and id.
type TaskSubtaskCursor struct {
	CreatedAt time.Time `json:"createdAt,omitempty"`
	ID        string    `json:"id,omitempty"`
}

func (cursor TaskSubtaskCursor) IsZero() bool {
	return cursor == (TaskSubtaskCursor{})
}

type TaskBrowseQuery struct {
	Limit             int                         `json:"limit,omitempty"`
	SearchQuery       string                      `json:"searchQuery,omitempty"`
	SortMode          string                      `json:"sortMode,omitempty"`
	StatusFilter      string                      `json:"statusFilter,omitempty"`
	QuickFilters      []string                    `json:"quickFilters,omitempty"`
	StructuredFilters map[string][]string         `json:"structuredFilters,omitempty"`
	IncludeSubtasks   bool                        `json:"includeSubtasks,omitempty"`
	Cursor            TaskBrowseCursor            `json:"cursor,omitempty"`
	ColumnCursors     map[string]TaskBrowseCursor `json:"columnCursors,omitempty"`
}

type TaskRowBrowsePage struct {
	QueryEcho    TaskBrowseQuery  `json:"queryEcho"`
	Rows         []Task           `json:"rows"`
	TotalCount   int64            `json:"totalCount"`
	HasMore      bool             `json:"hasMore"`
	NextCursor   TaskBrowseCursor `json:"nextCursor,omitempty"`
	ColumnCounts map[string]int64 `json:"columnCounts,omitempty"`
}

type TaskBoardColumnPage struct {
	Tasks      []Task           `json:"tasks,omitempty"`
	Count      int64            `json:"count"`
	HasMore    bool             `json:"hasMore"`
	NextCursor TaskBrowseCursor `json:"nextCursor,omitempty"`
}

type TaskBoardColumnDefinition struct {
	Key    string `json:"key"`
	Name   string `json:"name,omitempty"`
	Source string `json:"source,omitempty"`
}

type TaskBoardBrowsePage struct {
	QueryEcho         TaskBrowseQuery                `json:"queryEcho"`
	TotalCount        int64                          `json:"totalCount"`
	ColumnOrder       []string                       `json:"columnOrder,omitempty"`
	ColumnDefinitions []TaskBoardColumnDefinition    `json:"columnDefinitions,omitempty"`
	ColumnCounts      map[string]int64               `json:"columnCounts"`
	Columns           map[string]TaskBoardColumnPage `json:"columns"`
}

type ListTasksRequest struct {
	Context         ServiceContext `json:"context"`
	Board           BoardRef       `json:"board"`
	Status          string         `json:"status,omitempty"`
	IncludeSubtasks bool           `json:"includeSubtasks,omitempty"`
}

type ListTasksResponse struct {
	ChannelID string     `json:"channelId,omitempty"`
	Tasks     []Task     `json:"tasks,omitempty"`
	TaskViews []TaskView `json:"taskViews,omitempty"`
}

type ListWorkspaceTasksRequest struct {
	Context         ServiceContext `json:"context"`
	Status          string         `json:"status,omitempty"`
	IncludeSubtasks bool           `json:"includeSubtasks,omitempty"`
}

type ListWorkspaceTasksResponse struct {
	Tasks []Task `json:"tasks,omitempty"`
}

type BrowseWorkspaceTasksRequest struct {
	Context ServiceContext  `json:"context"`
	Query   TaskBrowseQuery `json:"query"`
}

type BrowseWorkspaceTaskBoardRequest struct {
	Context ServiceContext  `json:"context"`
	Query   TaskBrowseQuery `json:"query"`
}

type BrowseChannelTasksRequest struct {
	Context ServiceContext  `json:"context"`
	Board   BoardRef        `json:"board"`
	Query   TaskBrowseQuery `json:"query"`
}

type BrowseTaskBoardRequest struct {
	Context ServiceContext  `json:"context"`
	Board   BoardRef        `json:"board"`
	Query   TaskBrowseQuery `json:"query"`
}

type TaskFilterOption struct {
	Value string `json:"value"`
	Label string `json:"label"`
	Tone  string `json:"tone"`
}

type TaskFilterOptionPage struct {
	Options    []TaskFilterOption `json:"options"`
	HasMore    bool               `json:"hasMore"`
	NextCursor string             `json:"nextCursor,omitempty"`
}

type ListWorkspaceTaskFilterOptionsRequest struct {
	Context   ServiceContext `json:"context"`
	ChannelID string         `json:"channelId,omitempty"`
	Dimension string         `json:"dimension,omitempty"`
	Query     string         `json:"query,omitempty"`
	Limit     int            `json:"limit,omitempty"`
	Cursor    string         `json:"cursor,omitempty"`
	Include   []string       `json:"include,omitempty"`
}

type ListWorkspaceTaskFilterOptionsResponse struct {
	Channel  TaskFilterOptionPage `json:"channel"`
	Assignee TaskFilterOptionPage `json:"assignee"`
	Kind     TaskFilterOptionPage `json:"kind"`
	Priority TaskFilterOptionPage `json:"priority"`
}

type ListTaskFieldOptionsRequest struct {
	Context ServiceContext `json:"context"`
}

type ListTaskFieldOptionsResponse struct {
	CanManage       bool              `json:"canManage"`
	PriorityOptions []TaskFieldOption `json:"priorityOptions,omitempty"`
	KindOptions     []TaskFieldOption `json:"kindOptions,omitempty"`
}

type GetTaskBoardViewStateRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
}

type GetTaskBoardViewStateResponse struct {
	ViewState TaskBoardViewState `json:"viewState"`
}

type PutTaskBoardViewStateRequest struct {
	Context   ServiceContext     `json:"context"`
	Board     BoardRef           `json:"board"`
	ViewState TaskBoardViewState `json:"viewState"`
}

type PutTaskBoardViewStateResponse struct {
	ViewState TaskBoardViewState `json:"viewState"`
}

type TaskBoardSavedView struct {
	ID          string             `json:"id"`
	WorkspaceID string             `json:"workspaceId,omitempty"`
	MemberID    string             `json:"memberId,omitempty"`
	Name        string             `json:"name"`
	ViewState   TaskBoardViewState `json:"viewState"`
	CreatedAt   time.Time          `json:"createdAt"`
	UpdatedAt   time.Time          `json:"updatedAt"`
}

type ListTaskBoardSavedViewsRequest struct {
	Context ServiceContext `json:"context"`
}

type ListTaskBoardSavedViewsResponse struct {
	SavedViews []TaskBoardSavedView `json:"savedViews"`
}

type CreateTaskBoardSavedViewRequest struct {
	Context   ServiceContext     `json:"context"`
	Name      string             `json:"name"`
	ViewState TaskBoardViewState `json:"viewState"`
}

type CreateTaskBoardSavedViewResponse struct {
	SavedView TaskBoardSavedView `json:"savedView"`
}

type UpdateTaskBoardSavedViewRequest struct {
	Context     ServiceContext     `json:"context"`
	SavedViewID string             `json:"savedViewId"`
	Name        string             `json:"name"`
	ViewState   TaskBoardViewState `json:"viewState"`
}

type UpdateTaskBoardSavedViewResponse struct {
	SavedView TaskBoardSavedView `json:"savedView"`
}

type DeleteTaskBoardSavedViewRequest struct {
	Context     ServiceContext `json:"context"`
	SavedViewID string         `json:"savedViewId"`
}

type DeleteTaskBoardSavedViewResponse struct{}

type TaskFieldOptionInput struct {
	FieldKind string   `json:"fieldKind,omitempty"`
	Key       string   `json:"key,omitempty"`
	Label     string   `json:"label,omitempty"`
	Aliases   []string `json:"aliases,omitempty"`
}

type UpsertTaskFieldOptionRequest struct {
	Context  ServiceContext       `json:"context"`
	OptionID string               `json:"optionId,omitempty"`
	Option   TaskFieldOptionInput `json:"option"`
}

type UpsertTaskFieldOptionResponse struct {
	Option        TaskFieldOption `json:"option"`
	AffectedTasks []Task          `json:"affectedTasks,omitempty"`
}

type ReorderTaskFieldOptionRequest struct {
	Context  ServiceContext `json:"context"`
	OptionID string         `json:"optionId"`
	Position int64          `json:"position"`
}

type ReorderTaskFieldOptionResponse struct {
	Option TaskFieldOption `json:"option"`
}

type SetTaskFieldOptionActiveRequest struct {
	Context  ServiceContext `json:"context"`
	OptionID string         `json:"optionId"`
	Active   bool           `json:"active"`
}

type SetTaskFieldOptionActiveResponse struct {
	Option        TaskFieldOption `json:"option"`
	AffectedTasks []Task          `json:"affectedTasks,omitempty"`
}

type CreateTaskMetadata struct {
	SourceThreadChannelID       string `json:"sourceThreadChannelId,omitempty"`
	SourceThreadParentChannelID string `json:"sourceThreadParentChannelId,omitempty"`
	SourceThreadParentMessageID string `json:"sourceThreadParentMessageId,omitempty"`
	SourceThreadRef             string `json:"sourceThreadRef,omitempty"`
}

type TaskCreateInput struct {
	Title            string `json:"title,omitempty"`
	Description      string `json:"description,omitempty"`
	Kind             string `json:"kind,omitempty"`
	Priority         string `json:"priority,omitempty"`
	KindOptionID     string `json:"kindOptionId,omitempty"`
	PriorityOptionID string `json:"priorityOptionId,omitempty"`
	AssigneeRef      string `json:"assigneeRef,omitempty"`
}

type CreateTasksRequest struct {
	Context  ServiceContext      `json:"context"`
	Board    BoardRef            `json:"board"`
	Titles   []string            `json:"titles"`
	Task     *TaskCreateInput    `json:"task,omitempty"`
	Metadata *CreateTaskMetadata `json:"metadata,omitempty"`
}

type CreateTasksResponse struct {
	ChannelID    string        `json:"channelId,omitempty"`
	Tasks        []Task        `json:"tasks,omitempty"`
	CreatedTasks []CreatedTask `json:"createdTasks,omitempty"`
}

type CreateSubtasksRequest struct {
	Context ServiceContext   `json:"context"`
	Board   BoardRef         `json:"board"`
	Task    TaskRef          `json:"task"`
	Titles  []string         `json:"titles"`
	Input   *TaskCreateInput `json:"input,omitempty"`
}

type CreateSubtasksResponse struct {
	ChannelID    string        `json:"channelId,omitempty"`
	Tasks        []Task        `json:"tasks,omitempty"`
	CreatedTasks []CreatedTask `json:"createdTasks,omitempty"`
}

type ListTaskSubtasksRequest struct {
	Context ServiceContext    `json:"context"`
	Board   BoardRef          `json:"board"`
	Task    TaskRef           `json:"task"`
	Limit   int               `json:"limit,omitempty"`
	Cursor  TaskSubtaskCursor `json:"cursor,omitempty"`
}

type ListTaskSubtasksResponse struct {
	Tasks      []Task            `json:"tasks,omitempty"`
	HasMore    bool              `json:"hasMore,omitempty"`
	NextCursor TaskSubtaskCursor `json:"nextCursor,omitempty"`
}

type ClaimTasksRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
	Tasks   []TaskRef      `json:"tasks"`
}

type ClaimTasksResponse struct {
	ChannelID          string        `json:"channelId,omitempty"`
	Task               Task          `json:"task,omitempty"`
	Tasks              []Task        `json:"tasks,omitempty"`
	Results            []ClaimResult `json:"results,omitempty"`
	ChangedTaskNumbers []int64       `json:"changedTaskNumbers,omitempty"`
}

type UnclaimTaskRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
	Task    TaskRef        `json:"task"`
}

type UnclaimTaskResponse struct {
	Task Task `json:"task"`
}

type TaskBlockInput struct {
	Reason string `json:"reason"`
}

type BlockTaskRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
	Task    TaskRef        `json:"task"`
	Block   TaskBlockInput `json:"block"`
}

type BlockTaskResponse struct {
	Task    Task `json:"task"`
	Changed bool `json:"changed"`
}

type UnblockTaskRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
	Task    TaskRef        `json:"task"`
}

type UnblockTaskResponse struct {
	Task    Task `json:"task"`
	Changed bool `json:"changed"`
}

type DeleteTaskRequest struct {
	Context     ServiceContext        `json:"context"`
	Board       BoardRef              `json:"board"`
	Task        TaskRef               `json:"task"`
	SubtaskMode DeleteTaskSubtaskMode `json:"subtaskMode,omitempty"`
}

type DeleteTaskResponse struct {
	ChannelID      string   `json:"channelId,omitempty"`
	DeletedTaskIDs []string `json:"deletedTaskIds,omitempty"`
	PromotedTasks  []Task   `json:"promotedTasks,omitempty"`
}

type DeleteTaskSubtaskMode string

type GetTaskDetailRequest struct {
	Context      ServiceContext `json:"context"`
	Board        BoardRef       `json:"board"`
	Task         TaskRef        `json:"task"`
	SkipTimeline bool           `json:"skipTimeline,omitempty"`
}

type GetTaskDetailResponse struct {
	Detail TaskDetail `json:"detail"`
}

type GetTaskTimelineRequest struct {
	Context ServiceContext     `json:"context"`
	Board   BoardRef           `json:"board"`
	Task    TaskRef            `json:"task"`
	Cursor  TaskTimelineCursor `json:"cursor,omitempty"`
}

type GetTaskTimelineResponse struct {
	Entries    []TaskTimelineEntry `json:"entries"`
	HasMore    bool                `json:"hasMore,omitempty"`
	NextCursor TaskTimelineCursor  `json:"nextCursor,omitempty"`
}

type MarkTaskReadRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
	Task    TaskRef        `json:"task"`
}

type MarkTaskReadResponse struct {
	Task      Task          `json:"task"`
	ReadState TaskReadState `json:"readState"`
}

type TaskCheckpointInput struct {
	Text string `json:"text"`
}

type AddTaskCheckpointRequest struct {
	Context    ServiceContext      `json:"context"`
	Board      BoardRef            `json:"board"`
	Task       TaskRef             `json:"task"`
	Checkpoint TaskCheckpointInput `json:"checkpoint"`
}

type AddTaskCheckpointResponse struct {
	Task Task `json:"task"`
}

type TaskUpdatePatch struct {
	Title              *string             `json:"title,omitempty"`
	Description        *string             `json:"description,omitempty"`
	Kind               *string             `json:"kind,omitempty"`
	Priority           *string             `json:"priority,omitempty"`
	KindOptionID       *string             `json:"kindOptionId,omitempty"`
	PriorityOptionID   *string             `json:"priorityOptionId,omitempty"`
	AssigneeRef        *string             `json:"assigneeRef,omitempty"`
	AcceptanceCriteria []TaskChecklistItem `json:"acceptanceCriteria,omitempty"`
	ReviewChecklist    []TaskChecklistItem `json:"reviewChecklist,omitempty"`
	PinnedMessageRefs  []string            `json:"pinnedMessageRefs,omitempty"`
	RelevantURLs       []string            `json:"relevantURLs,omitempty"`
	WorkspaceRefs      []string            `json:"workspaceRefs,omitempty"`
	BlockedReason      *string             `json:"blockedReason,omitempty"`
	ParentTaskRef      *string             `json:"parentTaskRef,omitempty"`
	AttachmentIDs      []string            `json:"attachmentIds,omitempty"`
}

type UpdateTaskRequest struct {
	Context ServiceContext  `json:"context"`
	Board   BoardRef        `json:"board"`
	Task    TaskRef         `json:"task"`
	Patch   TaskUpdatePatch `json:"patch"`
}

type UpdateTaskResponse struct {
	Task Task `json:"task"`
}

type UpdateTaskStatusRequest struct {
	Context ServiceContext `json:"context"`
	Board   BoardRef       `json:"board"`
	Task    TaskRef        `json:"task"`
	Status  string         `json:"status"`
}

type UpdateTaskStatusResponse struct {
	Task    Task `json:"task"`
	Changed bool `json:"changed"`
}

type TaskReviewRequestInput struct {
	ReviewerRef         string   `json:"reviewerRef,omitempty"`
	Summary             string   `json:"summary,omitempty"`
	Questions           []string `json:"questions,omitempty"`
	ReviewTargetType    string   `json:"reviewTargetType"`
	ReviewTargetPayload string   `json:"reviewTargetPayload,omitempty"`
}

type RequestTaskReviewRequest struct {
	Context ServiceContext         `json:"context"`
	Board   BoardRef               `json:"board"`
	Task    TaskRef                `json:"task"`
	Review  TaskReviewRequestInput `json:"review"`
}

type RequestTaskReviewResponse struct {
	Task   Task              `json:"task"`
	Review TaskReviewRequest `json:"review"`
}

type TaskReviewDecisionInput struct {
	ReviewID  string   `json:"reviewId"`
	Decision  string   `json:"decision,omitempty"`
	Summary   string   `json:"summary,omitempty"`
	Questions []string `json:"questions,omitempty"`
}

type TaskReviewReassignmentInput struct {
	ReviewID    string `json:"reviewId"`
	ReviewerRef string `json:"reviewerRef"`
}

type TaskReviewCancellationInput struct {
	ReviewID string `json:"reviewId"`
}

type ApproveTaskReviewRequest struct {
	Context ServiceContext          `json:"context"`
	Board   BoardRef                `json:"board"`
	Task    TaskRef                 `json:"task"`
	Review  TaskReviewDecisionInput `json:"review"`
}

type RequestTaskChangesRequest struct {
	Context ServiceContext          `json:"context"`
	Board   BoardRef                `json:"board"`
	Task    TaskRef                 `json:"task"`
	Review  TaskReviewDecisionInput `json:"review"`
}

type ReassignTaskReviewRequest struct {
	Context ServiceContext              `json:"context"`
	Board   BoardRef                    `json:"board"`
	Task    TaskRef                     `json:"task"`
	Review  TaskReviewReassignmentInput `json:"review"`
}

type MarkTaskReviewNotReviewableRequest struct {
	Context ServiceContext              `json:"context"`
	Board   BoardRef                    `json:"board"`
	Task    TaskRef                     `json:"task"`
	Review  TaskReviewCancellationInput `json:"review"`
}

type TaskReviewDecisionResponse struct {
	Task   Task              `json:"task"`
	Review TaskReviewRequest `json:"review"`
}

type TaskBoardService interface {
	ListTasks(ctx context.Context, request ListTasksRequest) (ListTasksResponse, error)
	ListWorkspaceTasks(ctx context.Context, request ListWorkspaceTasksRequest) (ListWorkspaceTasksResponse, error)
	BrowseWorkspaceTasks(ctx context.Context, request BrowseWorkspaceTasksRequest) (TaskRowBrowsePage, error)
	BrowseWorkspaceTaskBoard(ctx context.Context, request BrowseWorkspaceTaskBoardRequest) (TaskBoardBrowsePage, error)
	BrowseChannelTasks(ctx context.Context, request BrowseChannelTasksRequest) (TaskRowBrowsePage, error)
	BrowseTaskBoard(ctx context.Context, request BrowseTaskBoardRequest) (TaskBoardBrowsePage, error)
	ListWorkspaceTaskFilterOptions(ctx context.Context, request ListWorkspaceTaskFilterOptionsRequest) (ListWorkspaceTaskFilterOptionsResponse, error)
	ListTaskFieldOptions(ctx context.Context, request ListTaskFieldOptionsRequest) (ListTaskFieldOptionsResponse, error)
	GetTaskBoardViewState(ctx context.Context, request GetTaskBoardViewStateRequest) (GetTaskBoardViewStateResponse, error)
	PutTaskBoardViewState(ctx context.Context, request PutTaskBoardViewStateRequest) (PutTaskBoardViewStateResponse, error)
	ListTaskBoardSavedViews(ctx context.Context, request ListTaskBoardSavedViewsRequest) (ListTaskBoardSavedViewsResponse, error)
	CreateTaskBoardSavedView(ctx context.Context, request CreateTaskBoardSavedViewRequest) (CreateTaskBoardSavedViewResponse, error)
	UpdateTaskBoardSavedView(ctx context.Context, request UpdateTaskBoardSavedViewRequest) (UpdateTaskBoardSavedViewResponse, error)
	DeleteTaskBoardSavedView(ctx context.Context, request DeleteTaskBoardSavedViewRequest) (DeleteTaskBoardSavedViewResponse, error)
	UpsertTaskFieldOption(ctx context.Context, request UpsertTaskFieldOptionRequest) (UpsertTaskFieldOptionResponse, error)
	ReorderTaskFieldOption(ctx context.Context, request ReorderTaskFieldOptionRequest) (ReorderTaskFieldOptionResponse, error)
	SetTaskFieldOptionActive(ctx context.Context, request SetTaskFieldOptionActiveRequest) (SetTaskFieldOptionActiveResponse, error)
	CreateTasks(ctx context.Context, request CreateTasksRequest) (CreateTasksResponse, error)
	CreateSubtasks(ctx context.Context, request CreateSubtasksRequest) (CreateSubtasksResponse, error)
	ListTaskSubtasks(ctx context.Context, request ListTaskSubtasksRequest) (ListTaskSubtasksResponse, error)
	ClaimTasks(ctx context.Context, request ClaimTasksRequest) (ClaimTasksResponse, error)
	UnclaimTask(ctx context.Context, request UnclaimTaskRequest) (UnclaimTaskResponse, error)
	BlockTask(ctx context.Context, request BlockTaskRequest) (BlockTaskResponse, error)
	UnblockTask(ctx context.Context, request UnblockTaskRequest) (UnblockTaskResponse, error)
	DeleteTask(ctx context.Context, request DeleteTaskRequest) (DeleteTaskResponse, error)
	GetTaskDetail(ctx context.Context, request GetTaskDetailRequest) (GetTaskDetailResponse, error)
	GetTaskTimeline(ctx context.Context, request GetTaskTimelineRequest) (GetTaskTimelineResponse, error)
	MarkTaskRead(ctx context.Context, request MarkTaskReadRequest) (MarkTaskReadResponse, error)
	ListRelatedTasksForThread(ctx context.Context, request ListRelatedTasksForThreadRequest) (RelatedTasksResponse, error)
	ListRelatedExecutionTasksForAgent(ctx context.Context, request ListRelatedExecutionTasksForAgentRequest) (RelatedTasksResponse, error)
	RelatedExecutionTasksSummaryForAgent(ctx context.Context, request RelatedExecutionTasksSummaryForAgentRequest) (RelatedTasksSummaryResponse, error)
	RelatedTasksSummaryForThread(ctx context.Context, request RelatedTasksSummaryForThreadRequest) (RelatedTasksSummaryResponse, error)
	UpdateTask(ctx context.Context, request UpdateTaskRequest) (UpdateTaskResponse, error)
	UpdateTaskStatus(ctx context.Context, request UpdateTaskStatusRequest) (UpdateTaskStatusResponse, error)
	AddTaskCheckpoint(ctx context.Context, request AddTaskCheckpointRequest) (AddTaskCheckpointResponse, error)
	RequestTaskReview(ctx context.Context, request RequestTaskReviewRequest) (RequestTaskReviewResponse, error)
	ApproveTaskReview(ctx context.Context, request ApproveTaskReviewRequest) (TaskReviewDecisionResponse, error)
	RequestTaskChanges(ctx context.Context, request RequestTaskChangesRequest) (TaskReviewDecisionResponse, error)
	ReassignTaskReview(ctx context.Context, request ReassignTaskReviewRequest) (TaskReviewDecisionResponse, error)
	MarkTaskReviewNotReviewable(ctx context.Context, request MarkTaskReviewNotReviewableRequest) (TaskReviewDecisionResponse, error)
}
