package wallet

import (
	"context"
	"strings"
	"testing"

	"hyapp/pkg/xerr"
	"hyapp/services/wallet-service/internal/domain/ledger"
)

// TestVipCommandStorageLengthsFailBeforeRepository keeps external strings within the VARCHAR
// boundaries used by transactions, outbox and entitlement identifiers; violations must be 4xx,
// never a MySQL data-too-long error surfaced as 5xx.
func TestVipCommandStorageLengthsFailBeforeRepository(t *testing.T) {
	service := New(nil)
	testCases := []struct {
		name string
		run  func() error
	}{
		{
			name: "purchase command id",
			run: func() error {
				_, err := service.PurchaseVip(context.Background(), ledger.PurchaseVipCommand{
					CommandID: strings.Repeat("x", 129), UserID: 1, Level: 1,
				})
				return err
			},
		},
		{
			name: "direct grant command id",
			run: func() error {
				_, err := service.GrantVip(context.Background(), ledger.GrantVipCommand{
					CommandID: strings.Repeat("x", 129), TargetUserID: 1, Level: 1,
					GrantSource: ledger.VipGrantSourceAdmin, OperatorUserID: 1,
				})
				return err
			},
		},
		{
			name: "equip request id",
			run: func() error {
				_, _, err := service.EquipVipTrialCard(context.Background(), ledger.EquipVipTrialCardCommand{
					RequestID: strings.Repeat("x", 129), UserID: 1, EntitlementID: "ent-1",
				})
				return err
			},
		},
		{
			name: "equip entitlement id",
			run: func() error {
				_, _, err := service.EquipVipTrialCard(context.Background(), ledger.EquipVipTrialCardCommand{
					RequestID: "req-1", UserID: 1, EntitlementID: strings.Repeat("x", 97),
				})
				return err
			},
		},
		{
			name: "unequip request id",
			run: func() error {
				_, _, err := service.UnequipVipTrialCard(context.Background(), ledger.UnequipVipTrialCardCommand{
					RequestID: strings.Repeat("x", 129), UserID: 1,
				})
				return err
			},
		},
		{
			name: "rebate claim command id",
			run: func() error {
				_, err := service.ClaimVipDailyCoinRebate(context.Background(), ledger.ClaimVipDailyCoinRebateCommand{
					CommandID: strings.Repeat("x", 129), UserID: 1, RebateID: "vip_rebate_1",
				})
				return err
			},
		},
		{
			name: "rebate id",
			run: func() error {
				_, err := service.ClaimVipDailyCoinRebate(context.Background(), ledger.ClaimVipDailyCoinRebateCommand{
					CommandID: "claim-rebate", UserID: 1, RebateID: strings.Repeat("x", 97),
				})
				return err
			},
		},
	}
	for _, testCase := range testCases {
		t.Run(testCase.name, func(t *testing.T) {
			if err := testCase.run(); !xerr.IsCode(err, xerr.InvalidArgument) {
				t.Fatalf("oversized VIP identifier must be invalid argument, got %v", err)
			}
		})
	}
}
