package region_sync

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

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

func TestSyncClient_SyncUserCreate(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, "POST", r.Method)
		assert.Equal(t, "/api/internal/sync/user/create", r.URL.Path)
		assert.Equal(t, "test-sync-key", r.Header.Get("X-Sync-API-Key"))

		var req SyncUserRequest
		json.NewDecoder(r.Body).Decode(&req)
		assert.Equal(t, "testuser", req.Username)
		assert.Equal(t, 123, req.RemoteUserId)

		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(SyncUserResponse{Success: true})
	}))
	defer server.Close()

	client := NewSyncClient(server.URL, "test-sync-key")
	resp, err := client.SyncUserCreate(&SyncUserRequest{
		Username:     "testuser",
		RemoteUserId: 123,
	})
	require.NoError(t, err)
	assert.True(t, resp.Success)
}

func TestSyncClient_QueryQuota(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(QueryQuotaResponse{Success: true, Quota: 50000})
	}))
	defer server.Close()

	client := NewSyncClient(server.URL, "test-key")
	resp, err := client.QueryQuota(123)
	require.NoError(t, err)
	assert.True(t, resp.Success)
	assert.Equal(t, 50000, resp.Quota)
}

func TestSyncClient_BatchDeduct(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var req BatchDeductRequest
		json.NewDecoder(r.Body).Decode(&req)
		assert.Len(t, req.Records, 2)

		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(BatchDeductResponse{
			Success: true,
			Results: []DeductResult{
				{UserId: 100, Success: true},
				{UserId: 101, Success: true},
			},
		})
	}))
	defer server.Close()

	client := NewSyncClient(server.URL, "test-key")
	resp, err := client.BatchDeduct(&BatchDeductRequest{
		Records: []BatchDeductRecord{
			{UserId: 100, RequestId: "req-1", Quota: 100},
			{UserId: 101, RequestId: "req-2", Quota: 200},
		},
	})
	require.NoError(t, err)
	assert.True(t, resp.Success)
	assert.Len(t, resp.Results, 2)
}

func TestSyncClient_UpdateQuota(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, "/api/internal/sync/quota/update", r.URL.Path)

		var req UpdateQuotaRequest
		json.NewDecoder(r.Body).Decode(&req)
		assert.Equal(t, 123, req.RemoteUserId)
		assert.Equal(t, 50000, req.Quota)

		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(UpdateQuotaResponse{Success: true})
	}))
	defer server.Close()

	client := NewSyncClient(server.URL, "test-key")
	resp, err := client.UpdateQuota(123, 50000)
	require.NoError(t, err)
	assert.True(t, resp.Success)
}

func TestSyncClient_DoRequest_Error(t *testing.T) {
	// 测试请求错误处理
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 返回错误状态码
		w.WriteHeader(http.StatusInternalServerError)
	}))
	defer server.Close()

	client := NewSyncClient(server.URL, "test-key")
	_, err := client.QueryQuota(123)
	// 应该有错误，但不是因为 marshaling/unmarshaling
	assert.NotNil(t, err)
}
