package kb

import (
	"context"
	"encoding/json"
	"net/http"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/service/resource/repos"
)

func TestInitializeSourceRepositoryCreatesCodebaseLabels(t *testing.T) {
	var created []map[string]string
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch {
		case r.Method == http.MethodGet && r.URL.Path == "/api/v3/repos/ws/agentteam/labels":
			require.NoError(t, json.NewEncoder(w).Encode([]map[string]string{}))
		case r.Method == http.MethodPost && r.URL.Path == "/api/v3/repos/ws/agentteam/labels":
			var body map[string]string
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			created = append(created, body)
			w.WriteHeader(http.StatusCreated)
			require.NoError(t, json.NewEncoder(w).Encode(body))
		default:
			require.Failf(t, "unexpected request", "%s %s", r.Method, r.URL.String())
		}
	})
	store := AGSHTTPRepositoryStore{
		Handler:             handler,
		AuthHeader:          "X-AgentTeam-JWT",
		AuthorizationHeader: "Bearer internal.jwt.",
	}

	err := store.InitializeSourceRepository(context.Background(), KBSourceRepositoryInitializeRequest{
		Repository: repos.RepositoryIdentity{Owner: "ws", Name: "agentteam", FullName: "ws/agentteam"},
		SourceType: "codebase",
		Locale:     "zh-CN",
	})

	require.NoError(t, err)
	require.Len(t, created, 10)
	require.Equal(t, "架构", created[0]["name"])
	require.Equal(t, "0969da", created[0]["color"])
	require.NotEmpty(t, created[0]["description"])
}

func TestInitializeSourceRepositoryCreatesFileRepositoryLabels(t *testing.T) {
	var created []map[string]string
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch {
		case r.Method == http.MethodGet && r.URL.Path == "/api/v3/repos/ws/docs/labels":
			require.NoError(t, json.NewEncoder(w).Encode([]map[string]string{}))
		case r.Method == http.MethodPost && r.URL.Path == "/api/v3/repos/ws/docs/labels":
			var body map[string]string
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			created = append(created, body)
			w.WriteHeader(http.StatusCreated)
			require.NoError(t, json.NewEncoder(w).Encode(body))
		default:
			require.Failf(t, "unexpected request", "%s %s", r.Method, r.URL.String())
		}
	})
	store := AGSHTTPRepositoryStore{
		Handler:             handler,
		AuthHeader:          "X-AgentTeam-JWT",
		AuthorizationHeader: "Bearer internal.jwt.",
	}

	err := store.InitializeSourceRepository(context.Background(), KBSourceRepositoryInitializeRequest{
		Repository: repos.RepositoryIdentity{Owner: "ws", Name: "docs", FullName: "ws/docs"},
		SourceType: "file_repository",
		Locale:     "ja",
	})

	require.NoError(t, err)
	require.Len(t, created, 10)
	require.Equal(t, "ドキュメント", created[0]["name"])
	require.Equal(t, "0969da", created[0]["color"])
	require.NotEmpty(t, created[0]["description"])
}

func TestInitializeSourceRepositoryCreatesEnglishLabelsByDefault(t *testing.T) {
	var created []map[string]string
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch {
		case r.Method == http.MethodGet && r.URL.Path == "/api/v3/repos/ws/repo/labels":
			require.NoError(t, json.NewEncoder(w).Encode([]map[string]string{}))
		case r.Method == http.MethodPost && r.URL.Path == "/api/v3/repos/ws/repo/labels":
			var body map[string]string
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			created = append(created, body)
			w.WriteHeader(http.StatusCreated)
			require.NoError(t, json.NewEncoder(w).Encode(body))
		default:
			require.Failf(t, "unexpected request", "%s %s", r.Method, r.URL.String())
		}
	})
	store := AGSHTTPRepositoryStore{
		Handler:             handler,
		AuthHeader:          "X-AgentTeam-JWT",
		AuthorizationHeader: "Bearer internal.jwt.",
	}

	err := store.InitializeSourceRepository(context.Background(), KBSourceRepositoryInitializeRequest{
		Repository: repos.RepositoryIdentity{Owner: "ws", Name: "repo", FullName: "ws/repo"},
		SourceType: "codebase",
		Locale:     "",
	})

	require.NoError(t, err)
	require.Len(t, created, 10)
	require.Equal(t, "architecture", created[0]["name"])
}

func TestInitializeSourceRepositorySkipsUnsupportedSourceType(t *testing.T) {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.Failf(t, "unexpected request", "%s %s", r.Method, r.URL.String())
	})
	store := AGSHTTPRepositoryStore{
		Handler:             handler,
		AuthHeader:          "X-AgentTeam-JWT",
		AuthorizationHeader: "Bearer internal.jwt.",
	}

	err := store.InitializeSourceRepository(context.Background(), KBSourceRepositoryInitializeRequest{
		Repository: repos.RepositoryIdentity{Owner: "ws", Name: "repo", FullName: "ws/repo"},
		SourceType: "external_connector",
		Locale:     "en",
	})

	require.NoError(t, err)
}

func TestCodebaseRepositoryLabelsLocaleVariants(t *testing.T) {
	enLabels := codebaseRepositoryLabels("en")
	require.Len(t, enLabels, 10)
	require.Equal(t, "architecture", enLabels[0].Name)

	zhLabels := codebaseRepositoryLabels("zh-CN")
	require.Len(t, zhLabels, 10)
	require.Equal(t, "架构", zhLabels[0].Name)

	jaLabels := codebaseRepositoryLabels("ja")
	require.Len(t, jaLabels, 10)
	require.Equal(t, "アーキテクチャ", jaLabels[0].Name)
}

func TestFileRepositoryLabelsLocaleVariants(t *testing.T) {
	enLabels := fileRepositoryLabels("en")
	require.Len(t, enLabels, 10)
	require.Equal(t, "document", enLabels[0].Name)

	zhLabels := fileRepositoryLabels("zh-CN")
	require.Len(t, zhLabels, 10)
	require.Equal(t, "文档", zhLabels[0].Name)

	jaLabels := fileRepositoryLabels("ja")
	require.Len(t, jaLabels, 10)
	require.Equal(t, "ドキュメント", jaLabels[0].Name)
}
