package channel_test

import (
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

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

	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	. "github.com/tidbcloud/AgentTeam/internal/api/testkit"
	"github.com/tidbcloud/AgentTeam/internal/core/domain"
)

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

	runtime := StartRuntime(t)

	router := gin.New()
	runtime.RegisterRoutes(router)
	server := httptest.NewServer(router)
	defer server.Close()

	client := server.Client()
	auth, workspaceID, _ := SetupTaskHTTPActor(t, client, server.URL, "channel-display-name-api@example.com", "channel-display-name-api")

	for _, displayName := range []string{
		"中文 频道",
		"文档、笔记、文本",
	} {
		t.Run(displayName, func(t *testing.T) {
			var channel dto.ChannelResponse
			response := DoJSON(t, client, http.MethodPost, server.URL+"/api/v1/workspaces/"+workspaceID+"/channels", map[string]any{
				"name":        displayName,
				"description": "display name can be localized",
			}, WorkspaceHeaders(auth.AccessToken, workspaceID), &channel)
			require.Equal(t, http.StatusOK, response.StatusCode)
			require.NotEmpty(t, channel.ID)
			require.NotEmpty(t, channel.Name)
			require.Equal(t, channel.Name, channel.Slug)
			require.Equal(t, displayName, channel.DisplayName)
			require.NotEqual(t, displayName, channel.Slug)
			require.NoError(t, domain.ValidateChannelSlug(channel.Slug))

			var storedSlug string
			var storedDisplayName string
			require.NoError(t, runtime.Pool.QueryRow(runtime.Ctx, `
SELECT slug, display_name
FROM scope_channel_profiles
WHERE workspace_id = $1 AND scope_id = $2
`, workspaceID, channel.ID).Scan(&storedSlug, &storedDisplayName))
			require.Equal(t, channel.Slug, storedSlug)
			require.Equal(t, displayName, storedDisplayName)

			var channels []dto.ChannelResponse
			response = DoJSON(t, client, http.MethodGet, server.URL+"/api/v1/workspaces/"+workspaceID+"/channels", nil, WorkspaceHeaders(auth.AccessToken, workspaceID), &channels)
			require.Equal(t, http.StatusOK, response.StatusCode)
			require.Contains(t, channels, channel)
		})
	}
}

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

	runtime := StartRuntime(t)

	router := gin.New()
	runtime.RegisterRoutes(router)
	server := httptest.NewServer(router)
	defer server.Close()

	client := server.Client()
	auth, workspaceID, _ := SetupTaskHTTPActor(t, client, server.URL, "lossy-channel-slug-api@example.com", "lossy-channel-slug-api")
	headers := WorkspaceHeaders(auth.AccessToken, workspaceID)

	var existing dto.ChannelResponse
	response := DoJSON(t, client, http.MethodPost, server.URL+"/api/v1/workspaces/"+workspaceID+"/channels", map[string]any{
		"name": "TiDB",
	}, headers, &existing)
	require.Equal(t, http.StatusOK, response.StatusCode)
	require.Equal(t, "tidb", existing.Slug)

	var localized dto.ChannelResponse
	response = DoJSON(t, client, http.MethodPost, server.URL+"/api/v1/workspaces/"+workspaceID+"/channels", map[string]any{
		"name": "TiDB字符集与排序规则转换",
	}, headers, &localized)
	require.Equal(t, http.StatusOK, response.StatusCode)
	require.Equal(t, "TiDB字符集与排序规则转换", localized.DisplayName)
	require.NotEqual(t, "tidb", localized.Slug)
	require.True(t, strings.HasPrefix(localized.Slug, "channel-"))
	require.NoError(t, domain.ValidateChannelSlug(localized.Slug))
}
