package rest_test

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

	"github.com/gin-gonic/gin"
	"github.com/nexuscrm/backend/internal/interfaces/rest"
	"github.com/stretchr/testify/assert"
)

// ---------------------------------------------------------------------------
// BulkHandler.CreateJob — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_CreateJob_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	body, _ := json.Marshal(map[string]interface{}{
		"object":    "Account",
		"operation": "insert",
	})
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("POST", "/jobs/ingest", bytes.NewReader(body))
	c.Request.Header.Set("Content-Type", "application/json")

	assert.Panics(t, func() { handler.CreateJob(c) })
}

func TestBulkHandler_CreateJob_InvalidJSON(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w, c := setupAuthenticatedContext("POST", "/jobs/ingest", []byte(`{invalid`))

	handler.CreateJob(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

// ---------------------------------------------------------------------------
// BulkHandler.CreateQueryJob — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_CreateQueryJob_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("POST", "/jobs/query", nil)

	assert.Panics(t, func() { handler.CreateQueryJob(c) })
}

func TestBulkHandler_CreateQueryJob_InvalidJSON(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w, c := setupAuthenticatedContext("POST", "/jobs/query", []byte(`{invalid`))

	handler.CreateQueryJob(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

func TestBulkHandler_CreateQueryJob_MissingQuery(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	body, _ := json.Marshal(map[string]interface{}{
		"operation": "query",
		"query":     "",
	})
	w, c := setupAuthenticatedContext("POST", "/jobs/query", body)

	handler.CreateQueryJob(c)
	assert.Equal(t, http.StatusBadRequest, w.Code)
}

// ---------------------------------------------------------------------------
// BulkHandler.GetJob — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_GetJob_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/jobs/ingest/job123", nil)
	c.Params = gin.Params{{Key: "jobId", Value: "job123"}}

	assert.Panics(t, func() { handler.GetJob(c) })
}

// ---------------------------------------------------------------------------
// BulkHandler.CloseJob — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_CloseJob_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("PATCH", "/jobs/ingest/job123", nil)
	c.Params = gin.Params{{Key: "jobId", Value: "job123"}}

	assert.Panics(t, func() { handler.CloseJob(c) })
}

// ---------------------------------------------------------------------------
// BulkHandler.UploadData — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_UploadData_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("PUT", "/jobs/ingest/job123/batches", nil)
	c.Params = gin.Params{{Key: "jobId", Value: "job123"}}

	assert.Panics(t, func() { handler.UploadData(c) })
}

// ---------------------------------------------------------------------------
// BulkHandler.GetQueryJob — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_GetQueryJob_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/jobs/query/job123", nil)
	c.Params = gin.Params{{Key: "jobId", Value: "job123"}}

	assert.Panics(t, func() { handler.GetQueryJob(c) })
}

// ---------------------------------------------------------------------------
// BulkHandler.GetQueryResults — input validation
// ---------------------------------------------------------------------------

func TestBulkHandler_GetQueryResults_Unauthenticated(t *testing.T) {
	handler := rest.NewBulkHandler(nil, nil, nil, nil, nil, nil)
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest("GET", "/jobs/query/job123/results", nil)
	c.Params = gin.Params{{Key: "jobId", Value: "job123"}}

	assert.Panics(t, func() { handler.GetQueryResults(c) })
}
