package converter

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"

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

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

	pinnedAt := time.Date(2026, 5, 25, 12, 1, 0, 0, time.UTC)
	cursor := message.ConversationCursor{PinnedAt: &pinnedAt, SortAt: time.Date(2026, 5, 25, 12, 0, 0, 0, time.UTC), ScopeID: "dm-1"}
	token := ToConversationCursorToken(cursor)
	require.NotEmpty(t, token)

	decoded, err := FromConversationCursorToken(token)
	require.NoError(t, err)
	require.Equal(t, cursor, decoded)
}

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

	pinnedAt := time.Date(2026, 6, 11, 12, 1, 0, 0, time.UTC)
	cursor := im.ConversationCursor{
		PinnedAt:       &pinnedAt,
		SortAt:         time.Date(2026, 6, 11, 12, 0, 0, 0, time.UTC),
		ConversationID: "channel:general",
	}
	token := ToIMConversationCursorToken(cursor)
	require.NotEmpty(t, token)

	decoded, err := FromIMConversationCursorToken(token)
	require.NoError(t, err)
	require.Equal(t, cursor, decoded)
}

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

	channel := ToConversationItem(message.ConversationItem{Kind: message.ConversationKindChannel, ScopeID: "ch one", Title: "General"})
	require.Equal(t, "channel:ch one", channel.ID)
	require.Equal(t, "channel", channel.Kind)
	require.Equal(t, "/inbox/channel/ch%20one", channel.Route)

	humanDM := ToConversationItem(message.ConversationItem{Kind: message.ConversationKindDM, PeerType: "human", ScopeID: "dm-1", Title: "Ada"})
	require.Equal(t, "dm:dm-1", humanDM.ID)
	require.Equal(t, "humanDm", humanDM.Kind)
	require.Equal(t, "/inbox/dm/dm-1", humanDM.Route)

	agentDM := ToConversationItem(message.ConversationItem{Kind: message.ConversationKindDM, PeerType: "agent", PeerID: "agt 1", ScopeID: "dm-2", Title: "agentteam1"})
	require.Equal(t, "agentDm", agentDM.Kind)
	require.Equal(t, "/inbox/agent/agt%201", agentDM.Route)

	serviceDM := ToConversationItem(message.ConversationItem{Kind: message.ConversationKindDM, PeerType: "service", PeerID: "appinst 1", ScopeID: "dm-3", Title: "Approval"})
	require.Equal(t, "serviceDm", serviceDM.Kind)
	require.Equal(t, "/inbox/dm/dm-3", serviceDM.Route)

	thread := ToConversationItem(message.ConversationItem{
		Kind:            message.ConversationKindThread,
		ScopeID:         "thr-1",
		ParentScopeID:   "ch one",
		ParentScopeType: "channel",
		Title:           "Thread",
	})
	require.Equal(t, "thread:thr-1", thread.ID)
	require.Equal(t, "replyThread", thread.Kind)
	require.Equal(t, "/inbox/thread/thr-1", thread.Route)

	dmThread := ToConversationItem(message.ConversationItem{
		Kind:            message.ConversationKindThread,
		ScopeID:         "thr dm",
		ParentScopeID:   "dm/1",
		ParentScopeType: "dm",
		Title:           "DM Thread",
	})
	require.Equal(t, "/inbox/thread/thr%20dm", dmThread.Route)

	knowledgeThread := ToConversationItem(message.ConversationItem{
		Kind:            message.ConversationKindThread,
		ScopeID:         "thr / kb",
		ParentScopeType: " kb ",
		Title:           "Knowledge thread",
	})
	require.Equal(t, "/inbox/kb/retrieval/thread/thr%20%2F%20kb", knowledgeThread.Route)

	serviceAccount := ToConversationItem(message.ConversationItem{
		Kind:     message.ConversationKindServiceAccount,
		ScopeID:  "svc scope 1",
		PeerType: "service",
		PeerID:   "sac principal 1",
		Title:    "AgentTeam 官方",
	})
	require.Equal(t, "serviceAccount:svc scope 1", serviceAccount.ID)
	require.Equal(t, "serviceAccount", serviceAccount.Kind)
	require.Equal(t, "/inbox/service-accounts/sac%20principal%201", serviceAccount.Route)

	task := ToConversationItem(message.ConversationItem{
		Kind:    message.ConversationKindTask,
		ScopeID: "scp_task_7",
		Title:   "Ship task",
		Task: &message.ConversationTaskMetadata{
			ID:        "tsk_7",
			ScopeID:   "scp_task_7",
			ChannelID: "chn / delivery",
			Number:    7,
			Route:     "/channels/chn%20%2F%20delivery/tasks/7",
		},
	})
	require.Equal(t, "task:scp_task_7", task.ID)
	require.Equal(t, "task", task.Kind)
	require.Equal(t, "/inbox/tasks/chn%20%2F%20delivery/7", task.Route)
}

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

	item := ToConversationItem(message.ConversationItem{
		Kind:            message.ConversationKindChannel,
		ScopeID:         "chn_team",
		Title:           "Frontend Squad",
		Subtitle:        "team_frontend",
		Subsystem:       message.ChannelSubsystemTeam,
		TeamID:          "team_frontend",
		TeamHandle:      "frontend",
		TeamDisplayName: "Frontend Squad",
	})

	require.Equal(t, message.ChannelSubsystemTeam, item.Subsystem)
	require.Equal(t, "team_frontend", item.TeamID)
	require.Equal(t, "frontend", item.TeamHandle)
	require.Equal(t, "Frontend Squad", item.TeamDisplayName)
	require.Equal(t, "/inbox/teams/team_frontend/channel/chn_team", item.Route)
}
