package audit

import (
	"testing"
)

// TestBuildApprovalEvents_AllKinds covers each ApprovalKind → Action mapping
// with Entrypoint=APPROVAL and EntrypointDetail=ProcessDeveloperName.
func TestBuildApprovalEvents_AllKinds(t *testing.T) {
	t.Parallel()

	cases := []struct {
		kind       ApprovalKind
		wantAction AuditAction
	}{
		{ApprovalKindSubmit, ActionSubmit},
		{ApprovalKindApprove, ActionApprove},
		{ApprovalKindReject, ActionReject},
		{ApprovalKindRecall, ActionUpdate}, // Recall is modeled as an UPDATE on the approval state
	}
	auth := ApprovalAuthContext{ChangedById: "005xx0000000001", RequestId: "req-a", TraceId: "tr-a"}
	for _, tc := range cases {
		tc := tc
		t.Run(string(tc.kind), func(t *testing.T) {
			t.Parallel()
			action := ApprovalAction{
				Kind:                   tc.kind,
				ObjectApiName:          "Opportunity",
				RecordId:               "006AAA",
				ProcessDeveloperName:   "My_Approval_Process",
				InstanceId:             "04gxx0000000001",
			}
			events, err := BuildApprovalEvents(auth, action)
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if len(events) != 1 {
				t.Fatalf("len(events) = %d, want 1", len(events))
			}
			ev := events[0]
			if ev.Entrypoint != EntrypointApproval {
				t.Errorf("Entrypoint = %q, want APPROVAL", ev.Entrypoint)
			}
			if ev.EntrypointDetail != action.ProcessDeveloperName {
				t.Errorf("EntrypointDetail = %q, want %q", ev.EntrypointDetail, action.ProcessDeveloperName)
			}
			if ev.Action != tc.wantAction {
				t.Errorf("Action = %q, want %q", ev.Action, tc.wantAction)
			}
			if ev.ObjectApiName != "Opportunity" || ev.RecordId != "006AAA" {
				t.Errorf("target record mismatch: %+v", ev)
			}
			if err := ev.Validate(); err != nil {
				t.Errorf("Validate() failed: %v", err)
			}
		})
	}
}

// TestBuildApprovalEvents_InvalidInput rejects unknown kind and missing target record.
func TestBuildApprovalEvents_InvalidInput(t *testing.T) {
	t.Parallel()

	cases := []struct {
		name   string
		auth   ApprovalAuthContext
		action ApprovalAction
	}{
		{
			name: "unknown kind",
			auth: ApprovalAuthContext{ChangedById: "005"},
			action: ApprovalAction{
				Kind: ApprovalKind("NOPE"), ObjectApiName: "Opp", RecordId: "006", ProcessDeveloperName: "p",
			},
		},
		{
			name: "missing RecordId",
			auth: ApprovalAuthContext{ChangedById: "005"},
			action: ApprovalAction{
				Kind: ApprovalKindSubmit, ObjectApiName: "Opp", ProcessDeveloperName: "p",
			},
		},
		{
			name: "missing ChangedById",
			auth: ApprovalAuthContext{},
			action: ApprovalAction{
				Kind: ApprovalKindSubmit, ObjectApiName: "Opp", RecordId: "006", ProcessDeveloperName: "p",
			},
		},
	}
	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			if _, err := BuildApprovalEvents(tc.auth, tc.action); err == nil {
				t.Fatal("expected error, got nil")
			}
		})
	}
}
