package integration

import (
	"encoding/json"
	"testing"

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

// ==============================================================================
// UI API Tests - record-ui, layout, object-info
// ==============================================================================

// TestUIAPI_ObjectInfo tests the /ui-api/object-info endpoint
func TestUIAPI_ObjectInfo(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test")
	}

	client := newHTTPClient(t)

	t.Run("Get_Account_ObjectInfo", func(t *testing.T) {
		resp, err := client.request("GET", "/services/data/v63.0/ui-api/object-info/Account", nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 200, resp.StatusCode, "Should return 200 OK")

		var result map[string]interface{}
		json.NewDecoder(resp.Body).Decode(&result)

		// Verify structure
		assert.NotNil(t, result["apiName"], "Should have apiName")
		assert.NotNil(t, result["fields"], "Should have fields")
		t.Logf("ObjectInfo apiName: %v", result["apiName"])
	})

	t.Run("Get_Contact_ObjectInfo", func(t *testing.T) {
		resp, err := client.request("GET", "/services/data/v63.0/ui-api/object-info/Contact", nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 200, resp.StatusCode)
	})

	t.Run("Get_NonExistent_ObjectInfo", func(t *testing.T) {
		resp, err := client.request("GET", "/services/data/v63.0/ui-api/object-info/NonExistentObject_XYZ", nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode, "Should return 404 for non-existent object")
	})
}

// TestUIAPI_Layout tests the /ui-api/layout endpoint
func TestUIAPI_Layout(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test")
	}

	client := newHTTPClient(t)

	t.Run("Get_Account_Layout", func(t *testing.T) {
		resp, err := client.request("GET", "/services/data/v63.0/ui-api/layout/Account", nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		// Accept 200 OK or 404 if no layout defined
		assert.True(t, resp.StatusCode == 200 || resp.StatusCode == 404,
			"Expected 200 or 404, got %d", resp.StatusCode)

		if resp.StatusCode == 200 {
			var result map[string]interface{}
			json.NewDecoder(resp.Body).Decode(&result)
			t.Logf("Layout response keys: %v", getKeys(result))
		}
	})
}

// TestUIAPI_RecordUI tests the /ui-api/record-ui endpoint
func TestUIAPI_RecordUI(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test")
	}

	client := newHTTPClient(t)
	sf := newGoSFClient(t)

	// Create a test record first
	account := map[string]interface{}{"Name": "UI API Test Account"}
	res, err := sf.InsertOne("Account", account)
	if err != nil {
		t.Skipf("Could not create test account: %v", err)
	}

	t.Run("Get_RecordUI", func(t *testing.T) {
		resp, err := client.request("GET", "/services/data/v63.0/ui-api/record-ui/"+res.Id, nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		// Accept 200 OK, 404, or 400 (invalid format)
		assert.True(t, resp.StatusCode == 200 || resp.StatusCode == 404 || resp.StatusCode == 400,
			"Expected 200/400/404, got %d", resp.StatusCode)

		if resp.StatusCode == 200 {
			var result map[string]interface{}
			json.NewDecoder(resp.Body).Decode(&result)
			t.Logf("RecordUI response has %d keys", len(result))
		}
	})

	// Cleanup
	sf.DeleteOne("Account", map[string]interface{}{"Id": res.Id})
}

// Helper to get map keys
func getKeys(m map[string]interface{}) []string {
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	return keys
}
