package feishu

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

	"github.com/stretchr/testify/require"
)

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

	var tokenRequests int
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case "/open-apis/auth/v3/tenant_access_token/internal":
			tokenRequests++
			_ = json.NewEncoder(w).Encode(map[string]any{"code": 0, "tenant_access_token": "tenant-token", "expire": 3600})
		case "/open-apis/contact/v3/users/batch_get_id":
			require.Equal(t, "Bearer tenant-token", r.Header.Get("Authorization"))
			require.Equal(t, "user_id", r.URL.Query().Get("user_id_type"))
			var body map[string][]string
			require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
			require.Equal(t, []string{"ada@example.com"}, body["emails"])
			_ = json.NewEncoder(w).Encode(map[string]any{"code": 0, "data": map[string]any{"user_list": []map[string]string{{"user_id": " user_1 ", "email": " ada@example.com "}, {"user_id": ""}}}})
		default:
			http.NotFound(w, r)
		}
	}))
	defer server.Close()

	client, err := NewFeishuDirectoryHTTPClient(FeishuDirectoryHTTPClientOptions{BaseURL: server.URL + "/", AppID: "app", AppSecret: "secret", HTTPClient: server.Client()})
	require.NoError(t, err)
	identities, err := client.BatchGetUserIDsByEmail(context.Background(), " ada@example.com ")
	require.NoError(t, err)
	require.Equal(t, []FeishuUserIdentity{{UserID: "user_1", Email: "ada@example.com"}}, identities)
	require.Equal(t, 1, tokenRequests)

	token, err := client.EnsureTenantAccessToken(context.Background())
	require.NoError(t, err)
	require.Equal(t, "tenant-token", token)
	require.Equal(t, 1, tokenRequests, "cached token should be reused")
}

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

	frozen := true
	active := true
	user := feishuUserPayload{
		User_id:        " user_1 ",
		Name:           " Ada ",
		Email:          " ada@example.com ",
		Department_ids: []string{" dept_fallback "},
		Orders:         []feishuUserOrderPayload{{Department_id: " dept_primary ", Is_primary_dept: true}},
		Status:         feishuUserStatusPayload{Is_activated: &active},
	}.toOrganizationUser()
	require.Equal(t, "user_1", user.UserID)
	require.Equal(t, "dept_primary", user.PrimaryDepartmentID)
	require.True(t, user.Active)

	user = feishuUserPayload{Status: feishuUserStatusPayload{Is_frozen: &frozen}}.toOrganizationUser()
	require.False(t, user.Active)

	isDeleted := true
	department := feishuDepartmentPayload{Name: " Engineering ", Open_department_id: " dept_1 ", Parent_department_id: " root ", Status: feishuDepartmentStatusPayload{Is_deleted: &isDeleted}}.toOrganizationDepartment()
	require.Equal(t, FeishuDepartment{OpenDepartmentID: "dept_1", ParentOpenDepartmentID: "root", Name: "Engineering", IsDeleted: true}, department)

	require.Equal(t, []string{"a", "b"}, normalizeFeishuLookupValues([]string{" a ", "", "b", "a"}))
	require.Contains(t, APIErrorMessage(40004, ""), "missing department authority")
	require.Contains(t, APIErrorMessage(40004, ""), "grant the app contact directory access")
}
