package ledger

import "testing"

func TestVipBenefitPresentationRoundTripPreservesOtherMetadata(t *testing.T) {
	presentation := &VipBenefitPresentation{
		Description: "头像框会自动合成当前用户头像",
		PreviewItems: []VipBenefitPreviewItem{{
			PreviewID: "frame-main", MediaType: "animation", AnimationURL: "https://cdn.example/frame.svga",
			PreviewURL: "https://cdn.example/frame.png", CompositionType: "user_avatar_center", SortOrder: 10,
		}},
		NumericReward: &VipBenefitNumericReward{Label: "每日返现", Value: 100, Unit: "金币", Period: "daily"},
	}
	metadata, err := MergeVipBenefitPresentation(`{"coin_amount":100}`, presentation)
	if err != nil {
		t.Fatalf("merge presentation failed: %v", err)
	}
	parsed, err := ParseVipBenefitPresentation(metadata)
	if err != nil || parsed == nil {
		t.Fatalf("parse presentation failed: parsed=%+v err=%v", parsed, err)
	}
	if parsed.Description != presentation.Description || len(parsed.PreviewItems) != 1 || parsed.PreviewItems[0].CompositionType != "user_avatar_center" || parsed.NumericReward == nil || parsed.NumericReward.Value != 100 {
		t.Fatalf("presentation round trip mismatch: %+v", parsed)
	}
	if metadata == "" || !containsJSONFragment(metadata, `"coin_amount":100`) {
		t.Fatalf("merge must preserve owner metadata: %s", metadata)
	}
}

func TestVipBenefitPresentationRejectsImplicitClientRules(t *testing.T) {
	invalid := VipBenefitPresentation{PreviewItems: []VipBenefitPreviewItem{{
		PreviewID: "wave", MediaType: "animation", CompositionType: "guess_from_benefit_code",
	}}}
	if err := ValidateVipBenefitPresentation(invalid); err == nil {
		t.Fatal("unknown composition type must be rejected")
	}
}

func containsJSONFragment(value string, fragment string) bool {
	for index := 0; index+len(fragment) <= len(value); index++ {
		if value[index:index+len(fragment)] == fragment {
			return true
		}
	}
	return false
}
