package com.red.circle.wallet.infra.tool;

import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.red.circle.common.business.core.enums.ReceiptType;
import com.red.circle.mq.business.model.event.wallet.WalletReceiptSyncEvent;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.wallet.infra.database.rds.service.WalletGoldBalanceService;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;

class WalletAssetSyncToolTest {

  @Test
  void syncGoldInitializesMissingBalanceWhenExpenditureUpdateMissesRow() {
    WalletGoldBalanceService balanceService = mock(WalletGoldBalanceService.class);
    when(balanceService.incrExpenditure(1001L, 1_500_000L)).thenReturn(false);
    when(balanceService.init("LIKEI", 1001L, 10_000_000L, 1_500_000L)).thenReturn(true);
    WalletAssetSyncTool tool = newTool(balanceService);

    WalletReceiptSyncEvent event = new WalletReceiptSyncEvent();
    event.setReceiptType(ReceiptType.EXPENDITURE);
    event.setSysOrigin("LIKEI");
    event.setUserId(1001L);
    event.setEventType("VOICE_ROOM_RED_PACKET_SEND");
    event.setEventId("VRPS:123");
    event.setAmount(PennyAmount.ofPenny(1_500_000L));
    event.setBalance(PennyAmount.ofPenny(8_500_000L));

    tool.syncGold(event);

    InOrder ordered = inOrder(balanceService);
    ordered.verify(balanceService).incrExpenditure(1001L, 1_500_000L);
    ordered.verify(balanceService).init("LIKEI", 1001L, 10_000_000L, 1_500_000L);
    verify(balanceService, never()).incrIncome(1001L, 1_500_000L);
  }

  @Test
  void syncGoldInitializesMissingBalanceWhenIncomeUpdateMissesRow() {
    WalletGoldBalanceService balanceService = mock(WalletGoldBalanceService.class);
    when(balanceService.incrIncome(1002L, 1_500_000L)).thenReturn(false);
    when(balanceService.init("LIKEI", 1002L, 11_500_000L, 0L)).thenReturn(true);
    WalletAssetSyncTool tool = newTool(balanceService);

    WalletReceiptSyncEvent event = new WalletReceiptSyncEvent();
    event.setReceiptType(ReceiptType.INCOME);
    event.setSysOrigin("LIKEI");
    event.setUserId(1002L);
    event.setEventType("VOICE_ROOM_RED_PACKET_CLAIM");
    event.setEventId("VRPC:123");
    event.setAmount(PennyAmount.ofPenny(1_500_000L));
    event.setBalance(PennyAmount.ofPenny(11_500_000L));

    tool.syncGold(event);

    InOrder ordered = inOrder(balanceService);
    ordered.verify(balanceService).incrIncome(1002L, 1_500_000L);
    ordered.verify(balanceService).init("LIKEI", 1002L, 11_500_000L, 0L);
    verify(balanceService, never()).incrExpenditure(1002L, 1_500_000L);
  }

  private WalletAssetSyncTool newTool(WalletGoldBalanceService balanceService) {
    return new WalletAssetSyncTool(null, null, null, null, null, balanceService, null, null, null,
        null);
  }
}
