package triggerprojection

import (
	"strings"
	"testing"

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

func TestValidateAtomicTriggerSupport(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name        string
		def         *models.FlowDefinition
		version     *models.FlowVersion
		wantErr     bool
		wantMessage string
	}{
		{
			name: "nil version allowed",
		},
		{
			name: "non atomic allowed",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					Start: &models.FlowStart{TriggerType: "RecordAfterSave", Object: "Lead"},
				},
			},
		},
		{
			name: "atomic before-save allowed",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start:         &models.FlowStart{TriggerType: "RecordBeforeSave", Object: "Lead"},
				},
			},
		},
		{
			name: "atomic after-save rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start:         &models.FlowStart{TriggerType: "RecordAfterSave", Object: "Lead"},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save strict async-after-commit allowed",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						ScheduledPaths: []models.FlowScheduledPath{{
							PathType:  "AsyncAfterCommit",
							Connector: &models.FlowConnector{TargetReference: "RunAfterCommit"},
						}},
					},
				},
			},
		},
		{
			name: "atomic after-save async-after-commit with immediate connector rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						Connector:   &models.FlowConnector{TargetReference: "RunNow"},
						ScheduledPaths: []models.FlowScheduledPath{{
							PathType:  "AsyncAfterCommit",
							Connector: &models.FlowConnector{TargetReference: "RunAfterCommit"},
						}},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save timed path rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						ScheduledPaths: []models.FlowScheduledPath{{
							TimeSource:   "RecordTriggerEvent",
							OffsetNumber: 1,
							OffsetUnit:   "Minutes",
							Connector:    &models.FlowConnector{TargetReference: "RunLater"},
						}},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save async-after-commit with top-level start rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically:         true,
					StartElementReference: "RunNow",
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						ScheduledPaths: []models.FlowScheduledPath{{
							PathType:  "AsyncAfterCommit",
							Connector: &models.FlowConnector{TargetReference: "RunAfterCommit"},
						}},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save multiple async-after-commit paths rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						ScheduledPaths: []models.FlowScheduledPath{
							{PathType: "AsyncAfterCommit", Connector: &models.FlowConnector{TargetReference: "First"}},
							{PathType: "AsyncAfterCommit", Connector: &models.FlowConnector{TargetReference: "Second"}},
						},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save async-after-commit without connector rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						ScheduledPaths: []models.FlowScheduledPath{{
							PathType: "AsyncAfterCommit",
						}},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save async-after-commit with schedule rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType: "RecordAfterSave",
						Object:      "Lead",
						Schedule:    &models.FlowSchedule{},
						ScheduledPaths: []models.FlowScheduledPath{{
							PathType:  "AsyncAfterCommit",
							Connector: &models.FlowConnector{TargetReference: "RunAfterCommit"},
						}},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic after-save async-after-commit with connector source rejected",
			version: &models.FlowVersion{
				ProcessType: "AutoLaunchedFlow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start: &models.FlowStart{
						TriggerType:     "RecordAfterSave",
						Object:          "Lead",
						ConnectorSource: &models.FlowConnectorSource{},
						ScheduledPaths: []models.FlowScheduledPath{{
							PathType:  "AsyncAfterCommit",
							Connector: &models.FlowConnector{TargetReference: "RunAfterCommit"},
						}},
					},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic workflow current-record rejected",
			version: &models.FlowVersion{
				ProcessType: "Workflow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Variables: []models.FlowVariable{{
						Name:       "myVariable_current",
						DataType:   "SObject",
						ObjectType: "Lead",
					}},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "atomic workflow bogus start still rejected",
			version: &models.FlowVersion{
				ProcessType: "Workflow",
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Start:         &models.FlowStart{TriggerType: "Bogus"},
					Variables: []models.FlowVariable{{
						Name:       "myVariable_current",
						DataType:   "SObject",
						ObjectType: "Lead",
					}},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
		{
			name: "blank version process type inherits workflow definition",
			def:  &models.FlowDefinition{ProcessType: "Workflow"},
			version: &models.FlowVersion{
				Metadata: models.FlowMetadata{
					RunAtomically: true,
					Variables: []models.FlowVariable{{
						Name:       "myVariable_current",
						DataType:   "SObject",
						ObjectType: "Lead",
					}},
				},
			},
			wantErr:     true,
			wantMessage: `triggerType "RecordAfterSave" is unsupported`,
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			err := ValidateAtomicTriggerSupport(tc.def, tc.version)
			if tc.wantErr {
				if err == nil {
					t.Fatal("ValidateAtomicTriggerSupport() error = nil, want error")
				}
				if !strings.Contains(err.Error(), tc.wantMessage) {
					t.Fatalf("error = %q, want substring %q", err.Error(), tc.wantMessage)
				}
				return
			}
			if err != nil {
				t.Fatalf("ValidateAtomicTriggerSupport() error = %v, want nil", err)
			}
		})
	}
}
