package gift

import (
	"context"
	"testing"

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

type fakeGiftLedgerStore struct {
	debitCalls int
	lastDebit  ledger.DebitGiftCommand
}

func (f *fakeGiftLedgerStore) DebitGift(_ context.Context, command ledger.DebitGiftCommand) (ledger.Receipt, error) {
	f.debitCalls++
	f.lastDebit = command
	return ledger.Receipt{TransactionID: "tx-direct"}, nil
}

func (f *fakeGiftLedgerStore) BatchDebitGift(_ context.Context, _ ledger.BatchDebitGiftCommand) (ledger.BatchGiftReceipt, error) {
	return ledger.BatchGiftReceipt{}, nil
}

func TestDebitGiftAllowsDirectGiftWithoutRoomID(t *testing.T) {
	store := &fakeGiftLedgerStore{}
	svc := New(store)

	_, err := svc.DebitGift(context.Background(), ledger.DebitGiftCommand{
		AppCode:      "lalu",
		CommandID:    "cmd-direct-gift",
		DirectGift:   true,
		SenderUserID: 10001,
		TargetUserID: 10002,
		GiftID:       "rose",
		GiftCount:    1,
	})
	if err != nil {
		t.Fatalf("direct gift without room_id must reach repository: %v", err)
	}
	if store.debitCalls != 1 || !store.lastDebit.DirectGift || store.lastDebit.RoomID != "" {
		t.Fatalf("direct gift command was not preserved: calls=%d command=%+v", store.debitCalls, store.lastDebit)
	}
}

func TestDebitGiftRequiresRoomIDForRoomGift(t *testing.T) {
	store := &fakeGiftLedgerStore{}
	svc := New(store)

	_, err := svc.DebitGift(context.Background(), ledger.DebitGiftCommand{
		AppCode:      "lalu",
		CommandID:    "cmd-room-gift",
		SenderUserID: 10001,
		TargetUserID: 10002,
		GiftID:       "rose",
		GiftCount:    1,
	})
	if !xerr.IsCode(err, xerr.InvalidArgument) {
		t.Fatalf("room gift without room_id must be invalid argument, got %v", err)
	}
	if store.debitCalls != 0 {
		t.Fatalf("invalid room gift must not reach repository, calls=%d", store.debitCalls)
	}
}
