package rest_test

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

	"github.com/gin-gonic/gin"
	"github.com/nexuscrm/backend/internal/features/metadata"
	"github.com/nexuscrm/backend/internal/interfaces/rest"
	"github.com/nexuscrm/backend/pkg/auth"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

func TestFlowHandler_UpdateFlowDefinition_MetadataEnvelopeProperties(t *testing.T) {
	gin.SetMode(gin.TestMode)

	repo := new(MockMetadataRepo)
	repo.
		On("PatchFlowDefinition", mock.Anything, "def001", mock.MatchedBy(func(patch *models.FlowDefinitionPatch) bool {
			return patch != nil &&
				patch.MasterLabel != nil && *patch.MasterLabel == "Renamed Flow" &&
				patch.Description != nil && *patch.Description == "Updated description"
		})).
		Return(nil).
		Once()

	handler := rest.NewFlowHandler(nil, nil, metadata.NewMetadataService(repo, nil, nil))
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Set(constants.ContextKeyUser, auth.UserSession{ID: "005000000000001", ProfileId: "00e000000000001"})
	c.Params = gin.Params{{Key: "id", Value: "def001"}}
	c.Request = httptest.NewRequest(
		http.MethodPatch,
		"/tooling/sobjects/FlowDefinition/def001",
		bytes.NewReader([]byte(`{"Metadata":{"masterLabel":"Renamed Flow","description":"Updated description"}}`)),
	)
	c.Request.Header.Set("Content-Type", "application/json")

	handler.UpdateFlowDefinition(c)

	assert.Equal(t, http.StatusNoContent, c.Writer.Status())
	repo.AssertExpectations(t)
}

func TestFlowHandler_UpdateFlowDefinition_FieldPatch(t *testing.T) {
	gin.SetMode(gin.TestMode)

	repo := new(MockMetadataRepo)
	repo.
		On("PatchFlowDefinition", mock.Anything, "def001", mock.MatchedBy(func(patch *models.FlowDefinitionPatch) bool {
			return patch != nil &&
				patch.MasterLabel != nil && *patch.MasterLabel == "Renamed Flow" &&
				patch.Description == nil
		})).
		Return(nil).
		Once()

	handler := rest.NewFlowHandler(nil, nil, metadata.NewMetadataService(repo, nil, nil))
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Set(constants.ContextKeyUser, auth.UserSession{ID: "005000000000001", ProfileId: "00e000000000001"})
	c.Params = gin.Params{{Key: "id", Value: "def001"}}
	c.Request = httptest.NewRequest(
		http.MethodPatch,
		"/tooling/sobjects/FlowDefinition/def001",
		bytes.NewReader([]byte(`{"MasterLabel":"Renamed Flow"}`)),
	)
	c.Request.Header.Set("Content-Type", "application/json")

	handler.UpdateFlowDefinition(c)

	assert.Equal(t, http.StatusNoContent, c.Writer.Status())
	repo.AssertExpectations(t)
}
