package oving7.savingsaccount;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class ForeldreSparTest {

	private static final double epsilon = 0.001;

	private ForeldreSpar foreldreSpar;

	@BeforeEach
	public void setUp() {
		foreldreSpar = new ForeldreSpar(0.04, 3);
	}

	@Test
	@DisplayName("Check that withdraw works as expected")
	public void testWithdraw() {
		foreldreSpar.deposit(10_000.0);
		foreldreSpar.withdraw(1000.0);
		assertEquals(9000.0, foreldreSpar.getBalance(), epsilon,
				"The account balance is incorrect");

		assertThrows(IllegalArgumentException.class, () -> {
			foreldreSpar.withdraw(-10_000.0);
		}, "Negative withdrawal should have triggered an IllegalArgumentException!");

		assertEquals(9000, foreldreSpar.getBalance(), epsilon, "The account balance is incorrect");

		assertThrows(IllegalArgumentException.class, () -> {
			foreldreSpar.withdraw(10_000);
		}, "Should not be able to withdraw more money than is in the account");

		assertEquals(9000.0, foreldreSpar.getBalance(), epsilon,
				"The account balance is incorrect");

		foreldreSpar.withdraw(1000.0);
		foreldreSpar.withdraw(1000.0);

		assertThrows(IllegalStateException.class, () -> {
			foreldreSpar.withdraw(1000.0);
		}, "Should not be able to make more withdrawals than the set limit");

		foreldreSpar.endYearUpdate();
		foreldreSpar.withdraw(1000.0);
		assertEquals(7000.0 * (1 + 0.04) - 1000.0, foreldreSpar.getBalance(), epsilon,
				"The account balance is incorrect");
	}

	@Test
	@DisplayName("Check that remaining withdrawals are always correct")
	public void testRemainingWithdrawals() {
		foreldreSpar.deposit(10_000.0);
		foreldreSpar.withdraw(1000.0);
		assertEquals(2, foreldreSpar.getRemainingWithdrawals());

		foreldreSpar.withdraw(1000.0);
		foreldreSpar.withdraw(1000.0);
		assertEquals(0, foreldreSpar.getRemainingWithdrawals());

		assertThrows(IllegalStateException.class, () -> {
			foreldreSpar.withdraw(1000.0);
		}, "Should not be able to make more withdrawals than the set limit");

		foreldreSpar.endYearUpdate();
		assertEquals(3, foreldreSpar.getRemainingWithdrawals());
	}
}
