package integration

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"testing"
	"time"

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

// ==============================================================================
// Test: SOSL Search with go-salesforce client
// ==============================================================================

func TestGoSF_SearchSOSL(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	sf := newGoSFClient(t)
	if sf == nil {
		t.Skip("go-salesforce client not available")
	}

	uniqueTerm := fmt.Sprintf("SOSL_Unique_%d", time.Now().UnixNano())

	// 1. Create Account
	account := Account{
		Name: "Account " + uniqueTerm,
	}
	accResult, err := sf.InsertOne("Account", account)
	require.NoError(t, err)
	require.True(t, accResult.Success)

	// 2. Create Contact linked to Account
	contact := Contact{
		FirstName: "Contact",
		LastName:  uniqueTerm,
		Email:     "sosl@test.com",
		AccountId: accResult.Id,
	}
	conResult, err := sf.InsertOne("Contact", contact)
	require.NoError(t, err)
	require.True(t, conResult.Success)

	// Allow some time for indexing
	time.Sleep(1 * time.Second)

	// 3. Execute SOSL Search
	soslQuery := fmt.Sprintf("FIND {%s} IN ALL FIELDS RETURNING Account, Contact", uniqueTerm)
	encodedQuery := url.QueryEscape(soslQuery)

	resp, err := sf.DoRequest("GET", "/search?q="+encodedQuery, nil)
	require.NoError(t, err, "SOSL Search failed")
	defer resp.Body.Close()

	require.Equal(t, http.StatusOK, resp.StatusCode)

	var result struct {
		SearchRecords []map[string]interface{} `json:"searchRecords"`
	}
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)

	// 4. Verify results
	assert.GreaterOrEqual(t, len(result.SearchRecords), 2, "Should find at least 2 records")

	foundAccount := false
	foundContact := false

	for _, rec := range result.SearchRecords {
		attrs := rec["attributes"].(map[string]interface{})
		objType := attrs["type"].(string)

		if objType == "Account" {
			foundAccount = true
		} else if objType == "Contact" {
			foundContact = true
		}
	}

	assert.True(t, foundAccount, "Should find the Account")
	assert.True(t, foundContact, "Should find the Contact")
}
