package message

import (
	"context"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
)

func TestAppMessagesFromVisibleRefsHydratesThreadAndTaskRouteContext(t *testing.T) {
	t.Parallel()

	ctx := context.Background()
	db := startMessagingTestPool(t, ctx)
	now := time.Date(2026, 6, 30, 10, 0, 0, 0, time.UTC)

	workspaceID := "wsp_search_route_context"
	userID := "usr_search_route_context"
	memberID := "mem_search_route_context"
	channelID := "chn_search_route_context"
	threadChannelID := "thr_search_route_context"
	parentMessageID := "msg_search_parent"
	taskID := "tsk_search_route_context"
	taskScopeID := "scope_task_search_route_context"

	insertMessagingWorkspace(t, ctx, db, workspaceID, now)
	insertMessagingUser(t, ctx, db, userID, "search-route-context@example.com", now)
	insertMessagingHumanMember(t, ctx, db, memberID, workspaceID, userID, now)
	insertMessagingChannel(t, ctx, db, channelID, workspaceID, "search-route-context", memberID, "", now)
	insertMessagingHumanScopeMessage(t, ctx, db, parentMessageID, workspaceID, channelID, "", memberID, "thread parent", 1, 1, now.Add(time.Minute))
	insertMessagingReplyThread(t, ctx, db, threadChannelID, workspaceID, channelID, parentMessageID, "searchroute", "", now.Add(2*time.Minute))
	insertMessagingHumanScopeMessage(t, ctx, db, "msg_search_thread_reply", workspaceID, threadChannelID, "", memberID, "thread reply hit", 1, 2, now.Add(3*time.Minute))
	insertConversationTaskForTest(t, ctx, db, conversationTaskFixture{
		WorkspaceID:       workspaceID,
		TaskID:            taskID,
		TaskScopeID:       taskScopeID,
		BoardID:           "tbd_search_route_context",
		ChannelID:         channelID,
		TaskNumber:        7,
		Title:             "Search route context task",
		Status:            "in_progress",
		CreatedByMemberID: memberID,
		OwnerMemberID:     memberID,
		Now:               now.Add(4 * time.Minute),
	})
	insertMessagingHumanScopeMessage(t, ctx, db, "msg_search_task_discussion", workspaceID, taskScopeID, "", memberID, "task discussion hit", 1, 1, now.Add(5*time.Minute))

	tx, err := db.BeginTx(ctx, coredb.TxOptions{})
	require.NoError(t, err)
	defer tx.Rollback(ctx)

	store := New(db, nil, 0, Options{})
	messages, err := store.InTx(tx).appMessagesFromVisibleRefs(ctx, workspaceID, []VisibleMessageRef{
		{
			Message: ScopeMessageRecord{
				ID:                 "msg_search_thread_reply",
				WorkspaceID:        workspaceID,
				ScopeID:            threadChannelID,
				Seq:                1,
				WorkspaceGlobalSeq: 2,
				AuthorMemberID:     memberID,
				AuthorType:         ScopeActorHuman,
				Content:            "thread reply hit",
				CreatedAt:          now.Add(3 * time.Minute),
				UpdatedAt:          now.Add(3 * time.Minute),
			},
			Reason: ScopeVisibilityReasonMembership,
		},
		{
			Message: ScopeMessageRecord{
				ID:                 "msg_search_task_discussion",
				WorkspaceID:        workspaceID,
				ScopeID:            taskScopeID,
				Seq:                1,
				WorkspaceGlobalSeq: 1,
				AuthorMemberID:     memberID,
				AuthorType:         ScopeActorHuman,
				MessageType:        MessageTypeTaskDiscussion,
				Content:            "task discussion hit",
				CreatedAt:          now.Add(5 * time.Minute),
				UpdatedAt:          now.Add(5 * time.Minute),
			},
			Reason: ScopeVisibilityReasonMembership,
		},
	})
	require.NoError(t, err)
	require.Len(t, messages, 2)

	var threadMessage AppMessage
	var taskMessage AppMessage
	for _, message := range messages {
		switch message.ID {
		case "msg_search_thread_reply":
			threadMessage = message
		case "msg_search_task_discussion":
			taskMessage = message
		}
	}

	require.Equal(t, "thread", threadMessage.ChannelType)
	require.Equal(t, channelID, threadMessage.ParentChannelID)
	require.Equal(t, "channel", threadMessage.ParentChannelType)
	require.Equal(t, parentMessageID, threadMessage.ParentMessageID)

	require.Equal(t, "task", taskMessage.ChannelType)
	require.NotNil(t, taskMessage.TaskContext)
	require.Equal(t, channelID, taskMessage.TaskContext.ChannelID)
	require.EqualValues(t, 7, taskMessage.TaskContext.TaskNumber)
}
