package dto

import (
	"bytes"
	"encoding/json"
	"time"

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

// TaskBoardOptionRequest creates or updates a task board field option.
type TaskBoardOptionRequest struct {
	FieldKind string   `json:"fieldKind,omitempty"`
	Key       string   `json:"key,omitempty"`
	Label     string   `json:"label,omitempty"`
	Aliases   []string `json:"aliases,omitempty"`
}

// TaskBoardOptionReorderRequest reorders a task board field option.
type TaskBoardOptionReorderRequest struct {
	Position int64 `json:"position"`
}

// TaskChecklistItem is one task checklist item in API wire payloads.
type TaskChecklistItem struct {
	ID      string `json:"id,omitempty"`
	Text    string `json:"text"`
	Checked bool   `json:"checked,omitempty"`
}

// TaskArtifact is one task artifact in API wire payloads.
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"`
}

// TaskReviewRequest is one task review request in API wire payloads.
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"`
}

// TaskActivityEvent is one task activity event in API wire payloads.
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
	// browser compatibility fields. Task 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"`
}

// TaskTimelineEntry is one task detail timeline item.
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"`
}

// TaskFieldValue is one custom field value in API wire payloads.
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"`
}

// TaskFieldOption is one task board field option.
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"`
}

// TaskProgressSummary is a compact task progress count.
type TaskProgressSummary struct {
	Total int64 `json:"total"`
	Done  int64 `json:"done"`
}

// TaskActor identifies a task actor.
type TaskActor struct {
	Type string `json:"type"`
	ID   string `json:"id"`
	Name string `json:"name"`
}

// TaskSourceThread identifies the source thread associated with a task.
type TaskSourceThread struct {
	ThreadChannelID string `json:"threadChannelId,omitempty"`
	ParentChannelID string `json:"parentChannelId"`
	ParentMessageID string `json:"parentMessageId"`
	Ref             string `json:"ref,omitempty"`
}

// TaskReadState is the API wire shape for the unified per-user Task
// conversation read state.
// The event-named fields are retained for backward-compatible clients.
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"`
	// WatchState mirrors the notification-policy self state ("active" or
	// "mute") so task surfaces can render the Watch control without a second
	// round-trip on open.
	WatchState string `json:"watchState,omitempty"`
}

// Task is the API wire task payload.
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"`
}

// RelatedTaskSignal is the latest high-signal task activity shown in a
// related-task row.
type RelatedTaskSignal struct {
	Type      string    `json:"type"`
	Payload   string    `json:"payload,omitempty"`
	CreatedAt time.Time `json:"createdAt"`
}

// RelatedTaskUnread is the viewer-local unread summary for a related-task row.
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"`
}

// RelatedTaskRow is the compact API wire shape used by thread and agent
// related-task views.
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"`
}

// RelatedTasksResponse returns compact task rows related to another task.
type RelatedTasksResponse struct {
	Tasks      []RelatedTaskRow `json:"tasks"`
	HasMore    bool             `json:"hasMore,omitempty"`
	NextCursor string           `json:"nextCursor,omitempty"`
}

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

// TaskDiscussionEntry is one task discussion entry in API wire payloads.
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 as a compatibility adapter for older task clients;
	// task discussion identity is AuthorProfile.
	CreatedBy           TaskActor                   `json:"createdBy"`
	ResolvedMentions    []ResolvedMention           `json:"resolvedMentions,omitempty"`
	Reactions           []MessageReactionAggregate  `json:"reactions,omitempty"`
	Attachments         []AppAttachment             `json:"attachments,omitempty"`
	CreatedAt           time.Time                   `json:"createdAt"`
	UpdatedAt           *time.Time                  `json:"updatedAt,omitempty"`
	EditedAt            *time.Time                  `json:"editedAt,omitempty"`
	EditedByMemberID    string                      `json:"editedByMemberId,omitempty"`
	EditRevision        int64                       `json:"editRevision,omitempty"`
	MessagePresentation *domain.MessagePresentation `json:"messagePresentation,omitempty"`
}

// TaskDetail is the full API wire detail for one task.
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       string              `json:"timelineNextCursor,omitempty"`
	AcceptanceCriteria       []TaskChecklistItem `json:"acceptanceCriteria,omitempty"`
	ReviewChecklist          []TaskChecklistItem `json:"reviewChecklist,omitempty"`
	Subtasks                 []Task              `json:"subtasks,omitempty"`
	SubtasksHasMore          bool                `json:"subtasksHasMore,omitempty"`
	SubtasksNextCursor       string              `json:"subtasksNextCursor,omitempty"`
	PinnedMessageRefs        []string            `json:"pinnedMessageRefs,omitempty"`
	PinnedMessageRefsHasMore bool                `json:"pinnedMessageRefsHasMore,omitempty"`
	RelevantURLs             []string            `json:"relevantURLs,omitempty"`
	RelevantURLsHasMore      bool                `json:"relevantURLsHasMore,omitempty"`
	WorkspaceRefs            []string            `json:"workspaceRefs,omitempty"`
	WorkspaceRefsHasMore     bool                `json:"workspaceRefsHasMore,omitempty"`
	Artifacts                []TaskArtifact      `json:"artifacts,omitempty"`
}

// TaskDetailResponse returns full detail for one task.
type TaskDetailResponse struct {
	Detail TaskDetail `json:"detail"`
}

// TaskSubtaskCursor is the wire continuation for one direct-child page.
type TaskSubtaskCursor struct {
	CreatedAt time.Time `json:"createdAt"`
	ID        string    `json:"id"`
}

// TaskSubtasksPageResponse returns one bounded direct-child page in newest-first
// order for GET /tasks/:taskId/subtasks.
type TaskSubtasksPageResponse struct {
	Tasks      []Task `json:"tasks,omitempty"`
	HasMore    bool   `json:"hasMore,omitempty"`
	NextCursor string `json:"nextCursor,omitempty"`
}

// TaskTimelineListResponse returns timeline entries for one task.
type TaskTimelineListResponse struct {
	Entries    []TaskTimelineEntry `json:"entries"`
	HasMore    bool                `json:"hasMore,omitempty"`
	NextCursor string              `json:"nextCursor,omitempty"`
}

// TaskView is the daemon-compatible task list item.
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"`
}

// CreatedTask is the daemon-compatible create result item.
type CreatedTask struct {
	TaskScopeID     string         `json:"taskScopeId,omitempty"`
	TaskNumber      int64          `json:"taskNumber"`
	Title           string         `json:"title"`
	Status          string         `json:"status,omitempty"`
	AssigneeProfile *AuthorProfile `json:"assigneeProfile,omitempty"`
	Reused          bool           `json:"reused,omitempty"`
}

// ClaimResult is the daemon-compatible claim result item.
type ClaimResult struct {
	TaskNumber int64  `json:"taskNumber"`
	Success    bool   `json:"success"`
	Reason     string `json:"reason,omitempty"`
}

// TaskBoardOptionsResponse returns task board field options.
type TaskBoardOptionsResponse struct {
	CanManage       bool              `json:"canManage"`
	PriorityOptions []TaskFieldOption `json:"priorityOptions,omitempty"`
	KindOptions     []TaskFieldOption `json:"kindOptions,omitempty"`
}

// TaskBoardOptionResponse returns a task board field option.
type TaskBoardOptionResponse struct {
	Option TaskFieldOption `json:"option"`
}

// TaskBoardOptionActiveResponse returns a task board field option active-state mutation result.
type TaskBoardOptionActiveResponse struct {
	Option        TaskFieldOption `json:"option"`
	AffectedTasks []Task          `json:"affectedTasks,omitempty"`
}

// TaskBoardViewStateRequest updates task board view-state data.
type TaskBoardViewStateRequest struct {
	View              string              `json:"view"`
	SearchQuery       string              `json:"searchQuery"`
	QuickFilters      []string            `json:"quickFilters"`
	StructuredFilters map[string][]string `json:"structuredFilters"`
	SortMode          string              `json:"sortMode"`
	// Deprecated: retained while older clients still round-trip board display
	// preferences through the server.
	CardPropertyToggles []string `json:"cardPropertyToggles,omitempty"`
	DoneCollapsed       bool     `json:"doneCollapsed"`
}

// TaskBrowseRequest is the browser-facing task browse query body.
type TaskBrowseRequest 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            string              `json:"cursor,omitempty"`
	ColumnCursors     map[string]string   `json:"columnCursors,omitempty"`
}

// TaskBoardViewStateResponse returns task board view-state data.
type TaskBoardViewStateResponse struct {
	ViewState TaskBoardViewStateRequest `json:"viewState"`
}

// TaskBoardViewStatePutResponse returns updated task board view-state data.
type TaskBoardViewStatePutResponse struct {
	ViewState TaskBoardViewStateRequest `json:"viewState"`
}

// TaskBoardSavedView is one user-saved workspace task-board filter view.
type TaskBoardSavedView struct {
	ID        string                    `json:"id"`
	Name      string                    `json:"name"`
	ViewState TaskBoardViewStateRequest `json:"viewState"`
	CreatedAt time.Time                 `json:"createdAt"`
	UpdatedAt time.Time                 `json:"updatedAt"`
}

// TaskBoardSavedViewRequest creates or replaces one saved view.
type TaskBoardSavedViewRequest struct {
	Name      string                    `json:"name"`
	ViewState TaskBoardViewStateRequest `json:"viewState"`
}

// TaskBoardSavedViewsResponse returns the caller's saved task-board views.
type TaskBoardSavedViewsResponse struct {
	SavedViews []TaskBoardSavedView `json:"savedViews"`
}

// TaskBoardSavedViewResponse returns one saved task-board view.
type TaskBoardSavedViewResponse struct {
	SavedView TaskBoardSavedView `json:"savedView"`
}

// TaskBrowseResponse returns row-browse task results.
type TaskBrowseResponse struct {
	QueryEcho    TaskBrowseRequest `json:"queryEcho"`
	Rows         []Task            `json:"rows"`
	TotalCount   int64             `json:"totalCount"`
	HasMore      bool              `json:"hasMore"`
	NextCursor   string            `json:"nextCursor,omitempty"`
	ColumnCounts map[string]int64  `json:"columnCounts,omitempty"`
}

// TaskFilterOption is one value available to a workspace Task filter.
type TaskFilterOption struct {
	Value string `json:"value"`
	Label string `json:"label"`
	Tone  string `json:"tone"`
}

// TaskFilterOptionPage is one bounded filter dimension result.
type TaskFilterOptionPage struct {
	Options    []TaskFilterOption `json:"options"`
	HasMore    bool               `json:"hasMore"`
	NextCursor string             `json:"nextCursor,omitempty"`
}

// TaskFilterOptionsResponse returns workspace-wide filter candidates in one
// request. A dimension-scoped search uses the same response shape.
type TaskFilterOptionsResponse struct {
	Channel  TaskFilterOptionPage `json:"channel"`
	Assignee TaskFilterOptionPage `json:"assignee"`
	Kind     TaskFilterOptionPage `json:"kind"`
	Priority TaskFilterOptionPage `json:"priority"`
}

// TaskBoardColumnPage returns one task board column page.
type TaskBoardColumnPage struct {
	Tasks      []Task `json:"tasks,omitempty"`
	Count      int64  `json:"count"`
	HasMore    bool   `json:"hasMore"`
	NextCursor string `json:"nextCursor,omitempty"`
}

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

// TaskBoardBrowseResponse returns board-browse task results.
type TaskBoardBrowseResponse struct {
	QueryEcho         TaskBrowseRequest              `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"`
}

// TaskPageResponse returns a list of task records.
type TaskPageResponse struct {
	Tasks []Task `json:"tasks"`
}

// TaskCreateInputRequest is the browser-facing rich task create input.
type TaskCreateInputRequest struct {
	Title            string `json:"title"`
	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"`
}

// TaskTitleRequest is the compact title entry used by bulk task create endpoints.
type TaskTitleRequest struct {
	Title string `json:"title"`
}

// TaskCreateRequest creates one or more top-level tasks.
type TaskCreateRequest struct {
	Tasks []TaskTitleRequest      `json:"tasks"`
	Task  *TaskCreateInputRequest `json:"task,omitempty"`
}

// TaskCreateSubtasksRequest creates one or more child tasks under a parent task.
type TaskCreateSubtasksRequest struct {
	Tasks []TaskTitleRequest      `json:"tasks"`
	Task  *TaskCreateInputRequest `json:"task,omitempty"`
}

// TaskUpdateRequest patches a task.
type TaskUpdateRequest struct {
	Status             *string             `json:"status,omitempty"`
	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"`
}

// UnmarshalJSON preserves the Task assignee clear operation:
// an omitted assigneeRef means "leave unchanged", while either null or an
// empty string means "unassign". encoding/json otherwise collapses null and
// omission for *string fields.
func (request *TaskUpdateRequest) UnmarshalJSON(data []byte) error {
	type taskUpdateRequestAlias TaskUpdateRequest
	var decoded taskUpdateRequestAlias
	if err := json.Unmarshal(data, &decoded); err != nil {
		return err
	}
	*request = TaskUpdateRequest(decoded)

	var fields map[string]json.RawMessage
	if err := json.Unmarshal(data, &fields); err != nil {
		return err
	}
	raw, present := fields["assigneeRef"]
	if present && bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
		empty := ""
		request.AssigneeRef = &empty
	}
	return nil
}

// TaskDeleteRequest controls how child tasks are handled when deleting a task.
type TaskDeleteRequest struct {
	SubtaskMode string `json:"subtaskMode,omitempty"`
}

// TaskResponse returns one task.
type TaskResponse struct {
	Task Task `json:"task"`
}

// MarkTaskReadResponse returns the updated task and read-state after marking a task read.
type MarkTaskReadResponse struct {
	Task      Task          `json:"task"`
	ReadState TaskReadState `json:"readState"`
}

// TaskResponseFromTask maps a task to its browser-facing response envelope.
func TaskResponseFromTask(task Task) TaskResponse {
	return TaskResponse{Task: task}
}

// TaskCheckpointRequest appends a checkpoint to a task.
type TaskCheckpointRequest struct {
	Text string `json:"text"`
}

// TaskBlockRequest marks a task blocked with a reason.
type TaskBlockRequest struct {
	Reason string `json:"reason"`
}
