package mysql

import (
	"testing"

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

func TestGiftSenderBalanceVersionAfterCountsEverySenderLedgerEntry(t *testing.T) {
	tests := []struct {
		name           string
		current        int64
		robotTopUp     bool
		debit          bool
		selfGiftIncome bool
		want           int64
	}{
		{name: "coin debit", current: 7, debit: true, want: 8},
		{name: "robot top up and debit", current: 7, robotTopUp: true, debit: true, want: 9},
		{name: "self gift debit and income", current: 7, debit: true, selfGiftIncome: true, want: 9},
		{name: "bag gift without sender coin mutation", current: 7, want: 7},
		{name: "bag self gift income", current: 7, selfGiftIncome: true, want: 8},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			if got := giftSenderBalanceVersionAfter(test.current, test.robotTopUp, test.debit, test.selfGiftIncome); got != test.want {
				t.Fatalf("balance version = %d, want %d", got, test.want)
			}
		})
	}
}

func TestGiftReceiptReplayAndBatchAggregatePreserveBalanceVersion(t *testing.T) {
	first := receiptFromGiftMetadata("tx-1", giftMetadata{BillingReceipt: "receipt-1", BalanceAfter: 900, BalanceVersion: 11, PaidAtMS: 1_700_000_000_000})
	last := receiptFromGiftMetadata("tx-2", giftMetadata{BillingReceipt: "receipt-2", BalanceAfter: 800, BalanceVersion: 12, PaidAtMS: 1_700_000_000_000})
	if first.BalanceVersion != 11 || last.BalanceVersion != 12 {
		t.Fatalf("metadata replay lost balance version: first=%+v last=%+v", first, last)
	}
	aggregate, err := aggregateGiftReceipts([]ledger.BatchGiftTargetReceipt{
		{TargetUserID: 1, CommandID: "target-1", Receipt: first},
		{TargetUserID: 2, CommandID: "target-2", Receipt: last},
	})
	if err != nil {
		t.Fatalf("aggregate gift receipts: %v", err)
	}
	if aggregate.BalanceAfter != 800 || aggregate.BalanceVersion != 12 || aggregate.PaidAtMS != 1_700_000_000_000 {
		t.Fatalf("aggregate must expose final sender snapshot: %+v", aggregate)
	}
}

func TestAggregateGiftReceiptsRejectsDifferentWalletPaidTimes(t *testing.T) {
	_, err := aggregateGiftReceipts([]ledger.BatchGiftTargetReceipt{
		{Receipt: ledger.Receipt{PaidAtMS: 1_700_000_000_000}},
		{Receipt: ledger.Receipt{PaidAtMS: 1_700_000_000_001}},
	})
	if err == nil {
		t.Fatal("batch receipts with different wallet paid_at_ms must fail closed")
	}
}
