package rest

import (
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
)

// ---------------------------------------------------------------------------
// SearchParameterized — validation paths (GET)
// ---------------------------------------------------------------------------

func TestSearchParameterized_Unauthenticated(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/parameterizedSearch?q=test", nil)
	// No user in context

	assert.Panics(t, func() { h.SearchParameterized(c) })
}

func TestSearchParameterized_MissingQuery(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/parameterizedSearch", nil)
	setTestUser(c)

	h.SearchParameterized(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

// ---------------------------------------------------------------------------
// SearchParameterizedPOST — validation paths
// ---------------------------------------------------------------------------

func TestSearchParameterizedPOST_InvalidJSON(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("POST", "/parameterizedSearch", strings.NewReader("{invalid"))
	c.Request.Header.Set("Content-Type", "application/json")

	h.SearchParameterizedPOST(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

func TestSearchParameterizedPOST_Unauthenticated(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	body := `{"q":"test"}`
	c.Request = httptest.NewRequest("POST", "/parameterizedSearch", strings.NewReader(body))
	c.Request.Header.Set("Content-Type", "application/json")
	// No user in context

	assert.Panics(t, func() { h.SearchParameterizedPOST(c) })
}

func TestSearchParameterizedPOST_MissingQ(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	body := `{"sobjects":[{"name":"Account"}]}`
	c.Request = httptest.NewRequest("POST", "/parameterizedSearch", strings.NewReader(body))
	c.Request.Header.Set("Content-Type", "application/json")
	setTestUser(c)

	h.SearchParameterizedPOST(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

// ---------------------------------------------------------------------------
// SearchSOSL — validation paths
// ---------------------------------------------------------------------------

func TestSearchSOSL_Unauthenticated(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/search?q=FIND+%7Btest%7D", nil)
	// No user in context

	assert.Panics(t, func() { h.SearchSOSL(c) })
}

func TestSearchSOSL_MissingQuery(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/search", nil)
	setTestUser(c)

	h.SearchSOSL(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

func TestSearchSOSL_InvalidSOSL(t *testing.T) {
	h := &SearchHandler{}
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	// SOSL that doesn't start with FIND
	c.Request = httptest.NewRequest("GET", "/search?q=SELECT+Name+FROM+Account", nil)
	setTestUser(c)

	h.SearchSOSL(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}
