//go:build test && dev

package payments

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"crussell/clock"
	"crussell/db"
	"crussell/mw"
	"crussell/testutils"
	"crussell/testutils/fixtures"
	"crussell/testutils/jwt"

	"github.com/go-chi/chi/v5"
)

// =============================================================================
// ApplyLoyaltyRedemption — POST /api/bookings/{id}/apply-redemption
// =============================================================================

func setupLoyaltyUser(t *testing.T, ctx context.Context, q db.Querier, stamps int) (string, string, string) {
	t.Helper()
	userID, err := fixtures.CreateTestUser(q)
	if err != nil {
		t.Fatalf("failed to create user: %v", err)
	}

	_, err = q.Exec(ctx,
		"UPDATE users SET loyalty_stamps = $1 WHERE id = $2", stamps, userID)
	if err != nil {
		t.Fatalf("failed to set loyalty_stamps: %v", err)
	}

	// Create a pending loyalty_redemption if stamps >= 10
	if stamps >= 10 {
		_, err = q.Exec(ctx, `
			INSERT INTO loyalty_redemptions (user_id, status, redeemed_at, expires_at)
			VALUES ($1, 'pending', NOW(), NOW() + INTERVAL '6 months')
		`, userID)
		if err != nil {
			t.Fatalf("failed to create loyalty redemption: %v", err)
		}
	}

	serviceID, err := fixtures.CreateTestService(q)
	if err != nil {
		t.Fatalf("failed to create service: %v", err)
	}

	bookingID, err := fixtures.CreateTestBookingAtTime(q, userID, serviceID, time.Date(2099, 12, 31, 10, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("failed to create booking: %v", err)
	}

	_, err = q.Exec(ctx,
		"UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
	if err != nil {
		t.Fatalf("failed to set booking status: %v", err)
	}

	userToken := jwt.GenerateUserToken(userID)
	return userID, bookingID, userToken
}

func makeApplyRedemptionRequest(bookingID, token string, ctx context.Context) *httptest.ResponseRecorder {
	handler := http.HandlerFunc(ApplyLoyaltyRedemption)

	req := httptest.NewRequest("POST", "/api/bookings/"+bookingID+"/apply-redemption", nil)
	req.Header.Set("Authorization", "Bearer "+token)

	rctx := chi.NewRouteContext()
	rctx.URLParams.Add("id", bookingID)
	ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)

	userID := extractUserFromTestJWT(token)
	if userID != nil {
		ctx = context.WithValue(ctx, mw.UserIDKey, userID.userID)
		ctx = context.WithValue(ctx, mw.UserRoleKey, userID.role)
	}

	req = req.WithContext(ctx)
	w := httptest.NewRecorder()
	handler.ServeHTTP(w, req)
	return w
}

func TestApplyLoyaltyRedemption_Success(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	_, bookingID, userToken := setupLoyaltyUser(t, ctx, tx, 10)

	w := makeApplyRedemptionRequest(bookingID, userToken, ctx)
	if w.Code != http.StatusOK {
		t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
	}

	var resp map[string]interface{}
	if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
		t.Fatalf("failed to parse response: %v", err)
	}

	if resp["success"] != true {
		t.Error("expected success=true")
	}
	discountAmount, ok := resp["discount_amount"].(float64)
	if !ok || discountAmount <= 0 {
		t.Errorf("expected positive discount_amount, got %v", resp["discount_amount"])
	}

	// Verify booking_discounts was created
	var discountCount int
	err := tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'loyalty'", bookingID).Scan(&discountCount)
	if err != nil {
		t.Fatalf("failed to query booking_discounts: %v", err)
	}
	if discountCount != 1 {
		t.Errorf("expected 1 loyalty discount record, got %d", discountCount)
	}

	// Verify stamps were deducted (10 - 10 = 0)
	var stamps int
	err = tx.QueryRow(ctx, "SELECT loyalty_stamps FROM users WHERE id = (SELECT user_id FROM bookings WHERE id = $1)", bookingID).Scan(&stamps)
	if err != nil {
		t.Fatalf("failed to query stamps: %v", err)
	}
	if stamps != 0 {
		t.Errorf("expected 0 stamps after redemption, got %d", stamps)
	}

	// Verify a discount payment record was created
	var paymentCount int
	err = tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM payments WHERE booking_id = $1 AND payment_method = 'discount'", bookingID).Scan(&paymentCount)
	if err != nil {
		t.Fatalf("failed to query payments: %v", err)
	}
	if paymentCount != 1 {
		t.Errorf("expected 1 discount payment record, got %d", paymentCount)
	}
}

func TestApplyLoyaltyRedemption_InsufficientStamps(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	_, bookingID, userToken := setupLoyaltyUser(t, ctx, tx, 5)

	w := makeApplyRedemptionRequest(bookingID, userToken, ctx)
	if w.Code != http.StatusBadRequest && w.Code != http.StatusConflict {
		t.Fatalf("expected 4xx for insufficient stamps, got %d: %s", w.Code, w.Body.String())
	}
}

func TestApplyLoyaltyRedemption_AlreadyApplied(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	_, bookingID, userToken := setupLoyaltyUser(t, ctx, tx, 10)

	// First call should succeed
	w := makeApplyRedemptionRequest(bookingID, userToken, ctx)
	if w.Code != http.StatusOK {
		t.Fatalf("first call expected 200, got %d: %s", w.Code, w.Body.String())
	}

	// Second call should be rejected
	w = makeApplyRedemptionRequest(bookingID, userToken, ctx)
	if w.Code != http.StatusConflict && w.Code != http.StatusBadRequest {
		t.Fatalf("second call expected 4xx, got %d: %s", w.Code, w.Body.String())
	}

	// Verify still only 1 discount record
	var discountCount int
	tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'loyalty'", bookingID).Scan(&discountCount)
	if discountCount != 1 {
		t.Errorf("expected 1 loyalty discount record, got %d", discountCount)
	}
}

func TestApplyLoyaltyRedemption_TerminalBooking(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	_, bookingID, userToken := setupLoyaltyUser(t, ctx, tx, 10)

	// Set booking to a terminal status
	_, err := tx.Exec(ctx,
		"UPDATE bookings SET status = 'completed' WHERE id = $1", bookingID)
	if err != nil {
		t.Fatalf("failed to set booking status: %v", err)
	}

	w := makeApplyRedemptionRequest(bookingID, userToken, ctx)
	if w.Code != http.StatusBadRequest {
		t.Fatalf("expected 400 for terminal booking, got %d: %s", w.Code, w.Body.String())
	}
}

// =============================================================================
// applyEligibleCampaignsAtPayment — campaign auto-apply at payment time
// =============================================================================

func setupCampaignTest(t *testing.T, ctx context.Context, q db.Querier) (string, string, string) {
	t.Helper()
	userID, err := fixtures.CreateTestUser(q)
	if err != nil {
		t.Fatalf("failed to create user: %v", err)
	}

	serviceID, err := fixtures.CreateTestService(q)
	if err != nil {
		t.Fatalf("failed to create service: %v", err)
	}

	bookingID, err := fixtures.CreateTestBookingAtTime(q, userID, serviceID, time.Date(2099, 12, 31, 10, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("failed to create booking: %v", err)
	}

	_, err = q.Exec(ctx,
		"UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
	if err != nil {
		t.Fatalf("failed to set booking status: %v", err)
	}

	userToken := jwt.GenerateUserToken(userID)
	return userID, bookingID, userToken
}

func TestCampaignAutoApply_TimeBased(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	// Create an active time-based campaign
	now := clock.Now()
	var campaignID string
	err := tx.QueryRow(ctx, `
		INSERT INTO discount_campaigns (name, campaign_type, discount_percent, status, start_date, end_date, times_redeemed)
		VALUES ($1, 'time_based', 10, 'active', $2, $3, 0)
		RETURNING id
	`, "Early Payment Sale", now.Add(-24*time.Hour), now.Add(24*time.Hour)).Scan(&campaignID)
	if err != nil {
		t.Fatalf("failed to create campaign: %v", err)
	}

	// Insert a deposit payment to trigger campaign auto-apply
	_, err = tx.Exec(ctx, `
		INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_at, updated_at)
		VALUES ($1, 'deposit', 'online_square', 2500, 'completed', NOW(), NOW())
	`, bookingID)
	if err != nil {
		t.Fatalf("failed to create payment: %v", err)
	}

	// Call applyEligibleCampaignsAtPayment
	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	// Verify booking_discounts was created
	var discountCount int
	tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'campaign'", bookingID).Scan(&discountCount)
	if discountCount != 1 {
		t.Errorf("expected 1 campaign discount, got %d", discountCount)
	}

	// Verify times_redeemed was incremented
	var timesRedeemed int
	tx.QueryRow(ctx,
		"SELECT times_redeemed FROM discount_campaigns WHERE id = $1", campaignID).Scan(&timesRedeemed)
	if timesRedeemed != 1 {
		t.Errorf("expected 1 redemption, got %d", timesRedeemed)
	}
}

func TestCampaignAutoApply_UserMilestone(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	// Give user 5 completed bookings to match milestone_value=5
	for i := 0; i < 5; i++ {
		var bid string
		tx.QueryRow(ctx, `
			INSERT INTO bookings (user_id, start_time, status) VALUES ($1, $2, 'completed') RETURNING id
		`, userID, time.Date(2024, time.Month(i+1), 15, 10, 0, 0, 0, time.UTC)).Scan(&bid)
	}

	// Create user milestone campaign for 5th booking
	var campaignID string
	err := tx.QueryRow(ctx, `
		INSERT INTO discount_campaigns (name, campaign_type, discount_percent, status, start_date, end_date, milestone_type, milestone_value, max_redemptions, times_redeemed)
		VALUES ($1, 'milestone', 15, 'active', NOW(), NOW() + INTERVAL '1 year', 'per_user_booking_count', 5, 1, 0)
		RETURNING id
	`, "5th Booking Bonus").Scan(&campaignID)
	if err != nil {
		t.Fatalf("failed to create campaign: %v", err)
	}

	// Insert a payment
	_, err = tx.Exec(ctx, `
		INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_at, updated_at)
		VALUES ($1, 'deposit', 'online_square', 2500, 'completed', NOW(), NOW())
	`, bookingID)
	if err != nil {
		t.Fatalf("failed to create payment: %v", err)
	}

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	var discountCount int
	tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'campaign'", bookingID).Scan(&discountCount)
	if discountCount != 1 {
		t.Errorf("expected 1 campaign discount, got %d", discountCount)
	}
}

func TestCampaignAutoApply_GlobalMilestoneSkippedOnline(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	// Set global completed count high enough
	now := clock.Now()
	for i := 0; i < 100; i++ {
		tx.QueryRow(ctx, `
			INSERT INTO bookings (user_id, start_time, status) VALUES ($1, $2, 'completed') RETURNING id
		`, userID, now.Add(-time.Duration(i)*24*time.Hour)).Scan(new(string))
	}

	// Create global milestone campaign at milestone_value=100
	var campaignID string
	err := tx.QueryRow(ctx, `
		INSERT INTO discount_campaigns (name, campaign_type, discount_percent, status, start_date, end_date, milestone_type, milestone_value, max_redemptions, times_redeemed)
		VALUES ($1, 'milestone', 20, 'active', NOW(), NOW() + INTERVAL '1 year', 'global_booking_count', 100, 5, 0)
		RETURNING id
	`, "100th Booking Celebration").Scan(&campaignID)
	if err != nil {
		t.Fatalf("failed to create campaign: %v", err)
	}

	// Insert an ONLINE payment first (not in_person_card)
	_, err = tx.Exec(ctx, `
		INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_at, updated_at)
		VALUES ($1, 'deposit', 'online_square', 2500, 'completed', NOW(), NOW())
	`, bookingID)
	if err != nil {
		t.Fatalf("failed to create payment: %v", err)
	}

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	// Verify NO discount was applied (global milestone skipped for online payment)
	var discountCount int
	tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'campaign'", bookingID).Scan(&discountCount)
	if discountCount != 0 {
		t.Errorf("expected 0 campaign discounts (global milestone skipped for online), got %d", discountCount)
	}
}

func TestCampaignAutoApply_GlobalMilestoneAppliedInPerson(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	for i := 0; i < 100; i++ {
		tx.QueryRow(ctx, `
			INSERT INTO bookings (user_id, start_time, status) VALUES ($1, $2, 'completed') RETURNING id
		`, userID, time.Date(2024, time.Month(i%12+1), 15, 10, 0, 0, 0, time.UTC)).Scan(new(string))
	}

	var campaignID string
	err := tx.QueryRow(ctx, `
		INSERT INTO discount_campaigns (name, campaign_type, discount_percent, status, start_date, end_date, milestone_type, milestone_value, max_redemptions, times_redeemed)
		VALUES ($1, 'milestone', 20, 'active', NOW(), NOW() + INTERVAL '1 year', 'global_booking_count', 100, 5, 0)
		RETURNING id
	`, "100th Booking Celebration").Scan(&campaignID)
	if err != nil {
		t.Fatalf("failed to create campaign: %v", err)
	}

	// Insert an IN-PERSON payment
	_, err = tx.Exec(ctx, `
		INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_at, updated_at)
		VALUES ($1, 'full', 'in_person_card', 5000, 'completed', NOW(), NOW())
	`, bookingID)
	if err != nil {
		t.Fatalf("failed to create payment: %v", err)
	}

	// Simulate what CreateBookingPayment does: set status to confirmed after payment
	tx.Exec(ctx,
		"UPDATE bookings SET status = 'confirmed', updated_at = NOW() WHERE id = $1", bookingID)

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	var discountCount int
	tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'campaign'", bookingID).Scan(&discountCount)
	if discountCount != 1 {
		t.Errorf("expected 1 campaign discount (in-person global milestone), got %d", discountCount)
	}
}

func TestCampaignAutoApply_DoubleApplyGuard(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	now := clock.Now()
	var campaignID string
	err := tx.QueryRow(ctx, `
		INSERT INTO discount_campaigns (name, campaign_type, discount_percent, status, start_date, end_date, times_redeemed)
		VALUES ($1, 'time_based', 10, 'active', $2, $3, 0)
		RETURNING id
	`, "Test Sale", now.Add(-24*time.Hour), now.Add(24*time.Hour)).Scan(&campaignID)
	if err != nil {
		t.Fatalf("failed to create campaign: %v", err)
	}

	// Manually insert a booking_discount to simulate it was already applied at payment time
	_, err = tx.Exec(ctx, `
		INSERT INTO booking_discounts (booking_id, user_id, discount_source, source_id, campaign_type, discount_percent, original_total, discount_amount)
		VALUES ($1, $2, 'campaign', $3, 'time_based', 10, 5000, 500)
	`, bookingID, userID, campaignID)
	if err != nil {
		t.Fatalf("failed to insert existing discount: %v", err)
	}

	// Pretend campaign was already redeemed
	tx.Exec(ctx,
		"UPDATE discount_campaigns SET times_redeemed = 1 WHERE id = $1", campaignID)

	// Insert payment to trigger applyEligibleCampaignsAtPayment
	tx.Exec(ctx, `
		INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_at, updated_at)
		VALUES ($1, 'deposit', 'online_square', 2500, 'completed', NOW(), NOW())
	`, bookingID)

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	// Verify still only 1 discount
	var discountCount int
	tx.QueryRow(ctx,
		"SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'campaign'", bookingID).Scan(&discountCount)
	if discountCount != 1 {
		t.Errorf("expected 1 campaign discount (no double-apply), got %d", discountCount)
	}
}

// =============================================================================
// Referral discount via applyEligibleCampaignsAtPayment
// =============================================================================

func TestCampaignAutoApply_ReferralDiscount(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	// Create the referral + discount
	var refID string
	err := tx.QueryRow(ctx, `
		INSERT INTO user_referrals (referrer_id, referred_id)
		VALUES ($1, $2)
		RETURNING id
	`, userID, userID).Scan(&refID)
	if err != nil {
		t.Fatalf("failed to create referral: %v", err)
	}

	var rdID string
	err = tx.QueryRow(ctx, `
		INSERT INTO referral_discounts (user_id, referral_id, discount_percent, used)
		VALUES ($1, $2, 10.00, false)
		RETURNING id
	`, userID, refID).Scan(&rdID)
	if err != nil {
		t.Fatalf("failed to insert referral discount: %v", err)
	}

	// Insert payment to trigger auto-apply
	_, err = tx.Exec(ctx, `
		INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_at, updated_at)
		VALUES ($1, 'deposit', 'online_square', 2500, 'completed', NOW(), NOW())
	`, bookingID)
	if err != nil {
		t.Fatalf("failed to create payment: %v", err)
	}

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	// Verify referral discount was applied
	var discountCount int
	err = tx.QueryRow(ctx,
		`SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'referral'`, bookingID).Scan(&discountCount)
	if err != nil {
		t.Fatalf("failed to count referral discounts: %v", err)
	}
	if discountCount != 1 {
		t.Errorf("expected 1 referral discount, got %d", discountCount)
	}

	// Verify referral discount was marked as used
	var used bool
	err = tx.QueryRow(ctx,
		"SELECT used FROM referral_discounts WHERE id = $1", rdID).Scan(&used)
	if err != nil {
		t.Fatalf("failed to query referral discount: %v", err)
	}
	if !used {
		t.Error("expected referral discount to be marked as used")
	}

	// Verify discount payment was created
	var paymentCount int
	tx.QueryRow(ctx,
		`SELECT COUNT(*) FROM payments WHERE booking_id = $1 AND payment_method = 'discount'`, bookingID).Scan(&paymentCount)
	if paymentCount == 0 {
		t.Error("expected at least 1 discount payment to be created")
	}
}

func TestCampaignAutoApply_ReferralDiscount_DoubleApplyGuard(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	var refID string
	err := tx.QueryRow(ctx, `
		INSERT INTO user_referrals (referrer_id, referred_id)
		VALUES ($1, $2)
		RETURNING id
	`, userID, userID).Scan(&refID)
	if err != nil {
		t.Fatalf("failed to create referral: %v", err)
	}

	var rdID string
	err = tx.QueryRow(ctx, `
		INSERT INTO referral_discounts (user_id, referral_id, discount_percent, used)
		VALUES ($1, $2, 10.00, false)
		RETURNING id
	`, userID, refID).Scan(&rdID)
	if err != nil {
		t.Fatalf("failed to insert referral discount: %v", err)
	}

	// Pre-apply the referral discount to simulate it was applied on a previous attempt
	_, err = tx.Exec(ctx, `
		INSERT INTO booking_discounts (booking_id, user_id, discount_source, source_id, discount_percent, original_total, discount_amount)
		VALUES ($1, $2, 'referral', $3, 10.00, 5000, 500)
	`, bookingID, userID, rdID)
	if err != nil {
		t.Fatalf("failed to insert existing booking discount: %v", err)
	}

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	// Verify no second referral discount was applied
	var discountCount int
	tx.QueryRow(ctx,
		`SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'referral'`, bookingID).Scan(&discountCount)
	if discountCount != 1 {
		t.Errorf("expected 1 referral discount (no double-apply), got %d", discountCount)
	}

	// Verify referral discount is still unused (since the function should skip it)
	var used bool
	tx.QueryRow(ctx,
		"SELECT used FROM referral_discounts WHERE id = $1", rdID).Scan(&used)
	if used {
		t.Error("expected referral discount to remain unused (skipped by double-apply guard)")
	}
}

func TestCampaignAutoApply_ReferralDiscount_AlreadyUsed(t *testing.T) {
	t.Parallel()
	ctx, tx := testutils.SetupTestTx(t)
	userID, bookingID, _ := setupCampaignTest(t, ctx, tx)

	var refID string
	err := tx.QueryRow(ctx, `
		INSERT INTO user_referrals (referrer_id, referred_id)
		VALUES ($1, $2)
		RETURNING id
	`, userID, userID).Scan(&refID)
	if err != nil {
		t.Fatalf("failed to create referral: %v", err)
	}

	// Create an already-used referral discount
	var rdID string
	err = tx.QueryRow(ctx, `
		INSERT INTO referral_discounts (user_id, referral_id, discount_percent, used)
		VALUES ($1, $2, 10.00, true)
		RETURNING id
	`, userID, refID).Scan(&rdID)
	if err != nil {
		t.Fatalf("failed to insert used referral discount: %v", err)
	}

	applyEligibleCampaignsAtPayment(ctx, tx, bookingID, userID)

	var discountCount int
	tx.QueryRow(ctx,
		`SELECT COUNT(*) FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'referral'`, bookingID).Scan(&discountCount)
	if discountCount != 0 {
		t.Errorf("expected 0 referral discounts (already used), got %d", discountCount)
	}
}
