package taskboard

import (
	"context"

	"github.com/tidbcloud/AgentTeam/internal/store/access"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
)

func (txs TxStore) GetTaskTimeline(ctx context.Context, request GetTaskTimelineRequest) (GetTaskTimelineResponse, error) {
	workspaceID, err := request.Context.requireWorkspaceID()
	if err != nil {
		return GetTaskTimelineResponse{}, err
	}

	switch request.Context.principalType() {
	case PrincipalTypeUser:
		userID, _, err := request.Context.requireUser()
		if err != nil {
			return GetTaskTimelineResponse{}, err
		}
		return txs.getTaskTimelineForUser(ctx, userID, workspaceID, request.Board, request.Task, request.Cursor)
	case PrincipalTypeAgent:
		agent, err := request.Context.requireAgentActor()
		if err != nil {
			return GetTaskTimelineResponse{}, err
		}
		return txs.getTaskTimelineForAgent(ctx, agent, request.Board, request.Task, request.Cursor)
	default:
		return GetTaskTimelineResponse{}, badRequest("context subject principalType is required")
	}
}

func (txs TxStore) getTaskTimelineForUser(ctx context.Context, userID string, workspaceID string, board BoardRef, taskRef TaskRef, cursor TaskTimelineCursor) (GetTaskTimelineResponse, error) {
	task, err := txs.resolveReadableUserTask(ctx, txs.tx, userID, workspaceID, board, taskRef)
	if err != nil {
		return GetTaskTimelineResponse{}, err
	}
	membership, err := access.LoadHumanWorkspaceMember(ctx, txs.tx, userID, workspaceID)
	if err != nil {
		return GetTaskTimelineResponse{}, err
	}
	page, err := NewTaskTimelineReadService(txs.tx).LoadTimelinePage(ctx, workspaceID, task.ID, membership.Member.ID, message.ScopeActorHuman, cursor, taskDetailTimelinePageSize)
	if err != nil {
		return GetTaskTimelineResponse{}, err
	}
	if err := attachResolvedMentionsForTaskTimelineEntries(ctx, txs.tx, workspaceID, membership.Member.ID, task.TaskScopeID, page.Entries); err != nil {
		return GetTaskTimelineResponse{}, err
	}
	return GetTaskTimelineResponse{
		Entries:    page.Entries,
		HasMore:    page.HasMore,
		NextCursor: page.NextCursor,
	}, nil
}

func (txs TxStore) getTaskTimelineForAgent(ctx context.Context, agent AgentActor, board BoardRef, taskRef TaskRef, cursor TaskTimelineCursor) (GetTaskTimelineResponse, error) {
	task, err := txs.resolveReadableAgentTask(ctx, txs.tx, agent, board, taskRef)
	if err != nil {
		return GetTaskTimelineResponse{}, err
	}
	page, err := NewTaskTimelineReadService(txs.tx).LoadTimelinePage(ctx, agent.WorkspaceID, task.ID, agent.MemberID, message.ScopeActorAgent, cursor, taskDetailTimelinePageSize)
	if err != nil {
		return GetTaskTimelineResponse{}, err
	}
	if err := attachResolvedMentionsForTaskTimelineEntries(ctx, txs.tx, agent.WorkspaceID, agent.MemberID, task.TaskScopeID, page.Entries); err != nil {
		return GetTaskTimelineResponse{}, err
	}
	return GetTaskTimelineResponse{
		Entries:    page.Entries,
		HasMore:    page.HasMore,
		NextCursor: page.NextCursor,
	}, nil
}
