package packs

import (
	"encoding/json"
	"strings"
	"testing"

	"github.com/nexuscrm/shared/pkg/models"
)

// buildStandardFlowPayload marshals a FlowMetadata with the required top-level
// fields into the []byte payload expected by newSourceBackedStandardFlowComponent.
func buildStandardFlowPayload(t *testing.T, meta models.FlowMetadata) []byte {
	t.Helper()
	type wrapper struct {
		ProcessType string `json:"processType"`
		Label       string `json:"label"`
		models.FlowMetadata
	}
	raw, err := json.Marshal(wrapper{
		ProcessType:  "AutoLaunchedFlow",
		Label:        "Test Flow",
		FlowMetadata: meta,
	})
	if err != nil {
		t.Fatalf("failed to marshal flow payload: %v", err)
	}
	return raw
}

func TestNewSourceBackedStandardFlowComponent_ConnectorSource_Valid(t *testing.T) {
	meta := models.FlowMetadata{
		Start: &models.FlowStart{
			ConnectorSource: &models.FlowConnectorSource{
				OwnerPack:   "my-pack",
				ProfileName: "MyProfile",
				ObjectKey:   "contacts",
				ItemsPath:   "$.results",
				ItemIDPath:  "$.id",
			},
		},
	}
	payload := buildStandardFlowPayload(t, meta)
	component := ManifestComponent{Kind: "standard_flow", BusinessKey: "valid_connector"}
	_, err := newSourceBackedStandardFlowComponent("my-pack", component, payload, nil, nil, nil)
	if err != nil {
		t.Fatalf("newSourceBackedStandardFlowComponent() error = %v, want nil for valid connectorSource", err)
	}
}

func TestNewSourceBackedStandardFlowComponent_ConnectorSource_MissingRequiredField(t *testing.T) {
	meta := models.FlowMetadata{
		Start: &models.FlowStart{
			ConnectorSource: &models.FlowConnectorSource{
				// OwnerPack intentionally blank
				ProfileName: "MyProfile",
				ObjectKey:   "contacts",
				ItemsPath:   "$.results",
				ItemIDPath:  "$.id",
			},
		},
	}
	payload := buildStandardFlowPayload(t, meta)
	component := ManifestComponent{Kind: "standard_flow", BusinessKey: "bad_connector"}
	_, err := newSourceBackedStandardFlowComponent("my-pack", component, payload, nil, nil, nil)
	if err == nil {
		t.Fatal("newSourceBackedStandardFlowComponent() error = nil, want error for missing OwnerPack")
	}
	if !strings.Contains(err.Error(), "OwnerPack is required") {
		t.Fatalf("error = %q, want substring %q", err.Error(), "OwnerPack is required")
	}
}

func TestNewSourceBackedStandardFlowComponent_ConnectorSource_CoPresenceWithObject(t *testing.T) {
	meta := models.FlowMetadata{
		Start: &models.FlowStart{
			Object: "Contact",
			ConnectorSource: &models.FlowConnectorSource{
				OwnerPack:   "my-pack",
				ProfileName: "MyProfile",
				ObjectKey:   "contacts",
				ItemsPath:   "$.results",
				ItemIDPath:  "$.id",
			},
		},
	}
	payload := buildStandardFlowPayload(t, meta)
	component := ManifestComponent{Kind: "standard_flow", BusinessKey: "bad_combined"}
	_, err := newSourceBackedStandardFlowComponent("my-pack", component, payload, nil, nil, nil)
	if err == nil {
		t.Fatal("newSourceBackedStandardFlowComponent() error = nil, want error for connectorSource + Object co-presence")
	}
	if !strings.Contains(err.Error(), "cannot be combined with Start.Object") {
		t.Fatalf("error = %q, want substring about co-presence", err.Error())
	}
}
