package channel

import (
	"net/http"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	unreadservice "github.com/tidbcloud/AgentTeam/internal/unread"
)

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

	store := &channelHandlerTestStore{}
	realtime := &channelHandlerTestRealtime{}
	unread := &fakeChannelUnreadReader{workspaceHasUnread: true}
	handler := &ChannelDMHandler{appStore: store, realtime: realtime, unreadRuntime: unread}

	listResponse, err := handler.ListDM(channelWorkspaceRequest())
	require.NoError(t, err)
	require.Equal(t, []dto.DMChannel{{ID: "dm_1", PeerType: "user", PeerID: "usr_2", PeerName: "alice"}}, listResponse.Body)
	require.Equal(t, "usr_1", store.dmList.userID)
	require.Equal(t, defaultDMListLimit, store.dmList.limit)

	getResponse, err := handler.GetDM(channelWorkspaceRequest(gin.Param{Key: "channelId", Value: " dm_1 "}))
	require.NoError(t, err)
	require.Equal(t, dto.DMChannel{ID: "dm_1", PeerType: "user", PeerID: "usr_2", PeerName: "alice"}, getResponse.Body)
	require.Equal(t, "dm_1", store.dmGet.channelID)

	agentResponse, err := handler.OpenDM(channelWorkspaceJSON(dto.OpenDMRequest{AgentID: " agt_1 "}))
	require.NoError(t, err)
	require.Equal(t, "agt_1", store.dmAgent.agentID)
	require.Equal(t, "dm_agent", agentResponse.Body.(dto.DMChannel).ID)

	userResponse, err := handler.OpenDM(channelWorkspaceJSON(dto.OpenDMRequest{UserID: " usr_2 "}))
	require.NoError(t, err)
	require.Equal(t, "usr_2", store.dmUser.peerUserID)
	require.Equal(t, "dm_user", userResponse.Body.(dto.DMChannel).ID)

	hideResponse, err := handler.HideDM(channelWorkspaceRequest(gin.Param{Key: "channelId", Value: " dm_agent "}))
	require.NoError(t, err)
	require.Equal(t, "dm_agent", store.dmHidden.channelID)
	require.Equal(t, "dm_agent", hideResponse.Body.(dto.DMChannel).ID)
	require.True(t, hideResponse.Body.(dto.DMChannel).SidebarHidden)
	require.Equal(t, []unreadservice.ScopeInvalidated{{
		WorkspaceID: "wsp_1",
		ScopeID:     "dm_agent",
		MemberIDs:   []string{"mem_1"},
		Reason:      "dm_hide",
	}}, unread.invalidated)
	require.Equal(t, []unreadservice.UnreadDelta{
		channelSuppressedUnreadDelta("dm_agent", true),
	}, realtime.unreadUpdated)

	_, err = handler.OpenDM(channelWorkspaceJSON(dto.OpenDMRequest{}))
	requireHTTPError(t, err, http.StatusBadRequest, "agentId or userId is required")
}
