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 TestChannelLifecycleHandlerMethodsUseStoreAndRealtime(t *testing.T) {
	t.Parallel()

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

	archiveResponse, err := handler.Archive(channelWorkspaceRequest(gin.Param{Key: "channelId", Value: "chn_1"}))
	require.NoError(t, err)
	require.Equal(t, "chn_1", store.archived.channelID)
	require.True(t, archiveResponse.Body.(dto.ChannelResponse).Archived)
	require.Equal(t, []string{"wsp_1:usr_1"}, realtime.updatedForUser)
	require.Equal(t, []unreadservice.ScopeInvalidated{{
		WorkspaceID: "wsp_1",
		ScopeID:     "chn_1",
		MemberIDs:   []string{"mem_1"},
		Reason:      "channel_archive",
	}}, unread.invalidated)
	require.Equal(t, []unreadservice.UnreadDelta{
		channelSuppressedUnreadDelta("chn_1", true),
	}, realtime.unreadUpdated)

	unarchiveResponse, err := handler.Unarchive(channelWorkspaceRequest(gin.Param{Key: "channelId", Value: "chn_1"}))
	require.NoError(t, err)
	require.Equal(t, "chn_1", store.unarchived.channelID)
	require.False(t, unarchiveResponse.Body.(dto.ChannelResponse).Archived)
	require.Equal(t, []string{"wsp_1:usr_1", "wsp_1:usr_1"}, realtime.updatedForUser)
	require.Equal(t, unreadservice.ScopeInvalidated{
		WorkspaceID: "wsp_1",
		ScopeID:     "chn_1",
		MemberIDs:   []string{"mem_1"},
		Reason:      "channel_unarchive",
	}, unread.invalidated[1])
	require.Equal(t, []unreadservice.UnreadDelta{
		channelSuppressedUnreadDelta("chn_1", true),
		channelSuppressedUnreadDelta("chn_1", true),
	}, realtime.unreadUpdated)

	ownerResponse, err := handler.TransferOwner(channelWorkspaceJSONWithParams(dto.ChannelTransferOwnerRequest{UserID: " usr_2 "}, gin.Param{Key: "channelId", Value: "chn_1"}))
	require.NoError(t, err)
	require.Equal(t, " usr_2 ", store.transferred.ownerID)
	require.Equal(t, dto.EmptyResponse{}, ownerResponse.Body)
	require.Equal(t, []string{"wsp_1"}, realtime.updated)

	dismissResponse, err := handler.DismissOwnerContext(channelWorkspaceJSONWithParams(dto.ChannelDismissOwnerContextRequest{DismissedThroughGlobalSeq: 99}, gin.Param{Key: "channelId", Value: "chn_1"}))
	require.NoError(t, err)
	require.Equal(t, int64(99), store.dismissed.seq)
	require.Equal(t, dto.EmptyResponse{}, dismissResponse.Body)

	_, err = handler.TransferOwner(channelWorkspaceJSONWithParams(dto.ChannelTransferOwnerRequest{}, gin.Param{Key: "channelId", Value: "chn_1"}))
	requireHTTPError(t, err, http.StatusBadRequest, "userId is required")
}
