package ledger

import "testing"

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

	err := validatePost(PostParams{
		EventType:  "transfer.completed",
		SourceType: "transfer",
		SourceID:   "transfer-1",
		Lines: []LineParams{
			{LedgerAccountID: "account-1", Direction: "debit", AmountCents: 100, Currency: "EUR"},
			{LedgerAccountID: "account-2", Direction: "credit", AmountCents: 100, Currency: "EUR"},
		},
	})
	if err != nil {
		t.Fatalf("balanced post rejected: %v", err)
	}
}

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

	err := validatePost(PostParams{
		EventType:  "transfer.completed",
		SourceType: "transfer",
		SourceID:   "transfer-1",
		Lines: []LineParams{
			{LedgerAccountID: "account-1", Direction: "debit", AmountCents: 100, Currency: "EUR"},
			{LedgerAccountID: "account-2", Direction: "credit", AmountCents: 99, Currency: "EUR"},
		},
	})
	if err == nil {
		t.Fatal("expected unbalanced post to fail")
	}
}

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

	lines := make([]LineParams, 0, 10_000)
	for i := 0; i < 5_000; i++ {
		currency := "EUR"
		if i%2 == 0 {
			currency = "USD"
		}
		lines = append(lines,
			LineParams{LedgerAccountID: "debit-account", Direction: "debit", AmountCents: 1, Currency: currency},
			LineParams{LedgerAccountID: "credit-account", Direction: "credit", AmountCents: 1, Currency: currency},
		)
	}

	err := validatePost(PostParams{
		EventType:  "ledger.performance_test",
		SourceType: "test",
		SourceID:   "high-volume",
		Lines:      lines,
	})
	if err != nil {
		t.Fatalf("high-volume balanced post rejected: %v", err)
	}
}

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

	if got := reverseDirection("debit"); got != "credit" {
		t.Fatalf("reverse debit = %q, want credit", got)
	}
	if got := reverseDirection("credit"); got != "debit" {
		t.Fatalf("reverse credit = %q, want debit", got)
	}
}

func BenchmarkValidatePostHighVolumeBalancedLines(b *testing.B) {
	lines := make([]LineParams, 0, 10_000)
	for i := 0; i < 5_000; i++ {
		lines = append(lines,
			LineParams{LedgerAccountID: "debit-account", Direction: "debit", AmountCents: 1, Currency: "EUR"},
			LineParams{LedgerAccountID: "credit-account", Direction: "credit", AmountCents: 1, Currency: "EUR"},
		)
	}
	params := PostParams{
		EventType:  "ledger.performance_test",
		SourceType: "test",
		SourceID:   "benchmark",
		Lines:      lines,
	}

	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		if err := validatePost(params); err != nil {
			b.Fatalf("validatePost failed: %v", err)
		}
	}
}
