package integration

import (
	"fmt"
	"testing"
	"time"

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

// ==============================================================================
// Salesforce SDK Compatibility Test Suite
// ==============================================================================

// TestSFCompat_Init verifies authentication via the SDK
func TestSFCompat_Init(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}
	sf := newGoSFClient(t)
	require.NotNil(t, sf, "SDK Client should initialize successfully")
}

// TestSFCompat_Query verifies generic soql queries via SDK
func TestSFCompat_Query(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	sf := newGoSFClient(t)

	t.Run("successful_query", func(t *testing.T) {
		var records []Account
		// SDK Query expects a pointer to a slice of structs/maps, NOT the wrapper object
		err := sf.Query("SELECT Id, Name FROM Account LIMIT 10", &records)
		require.NoError(t, err)
		assert.NotNil(t, records)
		// TotalSize is inferred from slice length or not returned directly in this helper signature
	})

	t.Run("query_with_filter", func(t *testing.T) {
		var records []Account
		err := sf.Query("SELECT Id, Name FROM Account WHERE Name != '' LIMIT 5", &records)
		require.NoError(t, err)
		assert.NotNil(t, records)
	})
}

// TestSFCompat_CRUD verifies Create, Update, Delete via SDK
func TestSFCompat_CRUD(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	sf := newGoSFClient(t)

	// 1. Create
	uniqName := fmt.Sprintf("SDK Account %d", time.Now().UnixNano())
	newAccount := map[string]interface{}{
		"Name": uniqName,
	}

	t.Log("Creating Account via SDK...")
	// InsertOne returns (SalesforceResult, error)
	res, err := sf.InsertOne("Account", newAccount)
	require.NoError(t, err)
	require.True(t, res.Success)
	require.NotEmpty(t, res.Id, "Created ID should not be empty")

	// 2. Update
	t.Logf("Updating Account %s...", res.Id)
	updateMap := map[string]interface{}{
		"Id":   res.Id, // UpdateOne expects Id in the record usually, checking implementation
		"Name": "Updated SDK Name",
	}
	// UpdateOne(sObjectName string, record any) error
	err = sf.UpdateOne("Account", updateMap)
	require.NoError(t, err, "Update should succeed")

	// 3. Retrieve (Verify Update via Query)
	var records []Account
	err = sf.Query(fmt.Sprintf("SELECT Name FROM Account WHERE Id = '%s'", res.Id), &records)
	require.NoError(t, err)
	require.Equal(t, 1, len(records))
	assert.Equal(t, "Updated SDK Name", records[0].Name)

	// 4. Delete
	t.Logf("Deleting Account %s...", res.Id)
	deleteRecord := map[string]interface{}{
		"Id": res.Id,
	}
	err = sf.DeleteOne("Account", deleteRecord)
	require.NoError(t, err)

	// 5. Verify Delete
	var records2 []Account
	err = sf.Query(fmt.Sprintf("SELECT Id FROM Account WHERE Id = '%s'", res.Id), &records2)
	require.NoError(t, err)
	assert.Equal(t, 0, len(records2), "Record should be gone")
}

// TestSFCompat_BulkJobLifecycle verifies Bulk v2 via SDK helpers
func TestSFCompat_BulkJobLifecycle(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	sf := newGoSFClient(t)

	// Using the high-level InsertBulk helper which handles Job Create, Upload, Close, Poll
	records := []map[string]interface{}{
		{"Name": "Bulk SDK Account 1"},
		{"Name": "Bulk SDK Account 2"},
	}

	t.Log("Executing InsertBulk via SDK...")
	// InsertBulk(sObjectName string, records any, batchSize int, waitForResults bool) ([]string, error)
	// It returns list of Job IDs created (if batched) or similar?
	// SDK valid sig: InsertBulk(obj, records, batchSize, waitForResults)
	ids, err := sf.InsertBulk("Account", records, 1000, true)
	require.NoError(t, err)
	require.NotEmpty(t, ids, "Should return successful job IDs")

	t.Logf("Bulk Job IDs: %v", ids)
}
