package de.szut.casino.shared.service;

import de.szut.casino.shared.dto.BetDto;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.math.BigDecimal;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class BalanceServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private BalanceService balanceService;

    private UserEntity user;
    private BetDto betDto;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        user = new UserEntity();
        user.setBalance(BigDecimal.valueOf(100));
        betDto = new BetDto();
    }

    @Test
    void testHasFunds_sufficientFunds() {
        betDto.setBetAmount(BigDecimal.valueOf(50));
        assertTrue(balanceService.hasFunds(user, betDto));
    }

    @Test
    void testHasFunds_insufficientFunds() {
        betDto.setBetAmount(BigDecimal.valueOf(150));
        assertFalse(balanceService.hasFunds(user, betDto));
    }

    @Test
    void testHasFunds_exactFunds() {
        betDto.setBetAmount(BigDecimal.valueOf(100));
        assertTrue(balanceService.hasFunds(user, betDto));
    }

    @Test
    void testAddFunds() {
        BigDecimal amountToAdd = BigDecimal.valueOf(50);
        balanceService.addFunds(user, amountToAdd);
        assertEquals(BigDecimal.valueOf(150), user.getBalance());
        verify(userRepository, times(1)).save(user);
    }

    @Test
    void testSubtractFunds_sufficientFunds() {
        BigDecimal amountToSubtract = BigDecimal.valueOf(50);
        balanceService.subtractFunds(user, amountToSubtract);
        assertEquals(BigDecimal.valueOf(50), user.getBalance());
        verify(userRepository, times(1)).save(user);
    }

    @Test
    void testSubtractFunds_insufficientFunds() {
        BigDecimal amountToSubtract = BigDecimal.valueOf(150);
        assertThrows(IllegalStateException.class, () -> balanceService.subtractFunds(user, amountToSubtract));
        verify(userRepository, never()).save(user);
    }
}
