package walletmq

import (
	"strings"
	"testing"
)

func TestWalletOutboxMessageRoundTrip(t *testing.T) {
	encoded, err := EncodeWalletOutboxMessage(WalletOutboxMessage{
		AppCode:        "lalu",
		EventID:        "event-1",
		EventType:      "WalletRechargeRecorded",
		TransactionID:  "tx-1",
		CommandID:      "cmd-1",
		UserID:         1001,
		AssetType:      "COIN",
		AvailableDelta: 100,
		PayloadJSON:    `{"recharge_sequence":1}`,
		OccurredAtMS:   1_700_000_000_000,
	})
	if err != nil {
		t.Fatalf("EncodeWalletOutboxMessage failed: %v", err)
	}

	decoded, err := DecodeWalletOutboxMessage(encoded)
	if err != nil {
		t.Fatalf("DecodeWalletOutboxMessage failed: %v", err)
	}
	if decoded.MessageType != MessageTypeWalletOutboxEvent || decoded.EventID != "event-1" || decoded.PayloadJSON == "" {
		t.Fatalf("decoded message mismatch: %+v", decoded)
	}
}

func TestEventTypeTagUsesExactTrimmedEventType(t *testing.T) {
	tag, err := EventTypeTag("  WalletRechargeRecorded  ")
	if err != nil {
		t.Fatalf("EventTypeTag failed: %v", err)
	}
	if tag != EventTypeWalletRechargeRecorded {
		t.Fatalf("event tag = %q, want %q", tag, EventTypeWalletRechargeRecorded)
	}

	for _, invalid := range []string{"", TagWalletOutboxEvent, "Wallet RechargeRecorded", "WalletRechargeRecorded || *", "Wallet.RechargeRecorded"} {
		if _, err := EventTypeTag(invalid); err == nil {
			t.Fatalf("EventTypeTag(%q) unexpectedly succeeded", invalid)
		}
	}
}

func TestLegacyCompatibleTagExpressionIsDeterministicAndDeduplicated(t *testing.T) {
	first, err := LegacyCompatibleTagExpression(
		EventTypeWalletGiftDebited,
		EventTypeWalletRechargeRecorded,
		EventTypeWalletGiftDebited,
	)
	if err != nil {
		t.Fatalf("LegacyCompatibleTagExpression failed: %v", err)
	}
	second, err := LegacyCompatibleTagExpression(
		EventTypeWalletRechargeRecorded,
		EventTypeWalletGiftDebited,
	)
	if err != nil {
		t.Fatalf("LegacyCompatibleTagExpression failed: %v", err)
	}
	if first != second {
		t.Fatalf("expressions differ by input order: first=%q second=%q", first, second)
	}
	want := TagWalletOutboxEvent + " || " + EventTypeWalletGiftDebited + " || " + EventTypeWalletRechargeRecorded
	if first != want {
		t.Fatalf("expression = %q, want %q", first, want)
	}
	if strings.Count(first, EventTypeWalletGiftDebited) != 1 {
		t.Fatalf("typed tag was not deduplicated: %q", first)
	}
}

func TestLegacyCompatibleTagExpressionRejectsUnsafeOrMissingTypedTags(t *testing.T) {
	for _, eventTypes := range [][]string{
		nil,
		{TagWalletOutboxEvent},
		{"WalletRechargeRecorded || *"},
	} {
		if _, err := LegacyCompatibleTagExpression(eventTypes...); err == nil {
			t.Fatalf("LegacyCompatibleTagExpression(%v) unexpectedly succeeded", eventTypes)
		}
	}
}
