import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

class SavingsAccountTest {

    @Test
    void inheritsDepositAndBalance() {
        SavingsAccount s = new SavingsAccount("A-001", 2);
        s.deposit(10_000);
        assertEquals(10_000, s.balance());
        assertEquals("A-001", s.id());
    }

    @Test
    void applyInterestAddsMonthlyRate() {
        SavingsAccount s = new SavingsAccount("A-001", 2);
        s.deposit(100_000);
        s.applyInterest();
        assertEquals(102_000, s.balance());
    }

    @Test
    void fourthWithdrawalInAMonthIsRejected() {
        SavingsAccount s = new SavingsAccount("A-001", 0);
        s.deposit(10_000);
        for (int i = 0; i < SavingsAccount.MAX_WITHDRAWALS; i++) {
            assertTrue(s.withdraw(100));
        }
        assertFalse(s.withdraw(100));
        assertEquals(9_700, s.balance());
    }

    @Test
    void applyInterestResetsWithdrawals() {
        SavingsAccount s = new SavingsAccount("A-001", 0);
        s.deposit(10_000);
        for (int i = 0; i < SavingsAccount.MAX_WITHDRAWALS; i++) {
            s.withdraw(100);
        }
        s.applyInterest();
        assertTrue(s.withdraw(100));
    }

    @Test
    void failedWithdrawalDoesNotCount() {
        SavingsAccount s = new SavingsAccount("A-001", 0);
        assertFalse(s.withdraw(500));       // no hay saldo
        s.deposit(10_000);
        for (int i = 0; i < SavingsAccount.MAX_WITHDRAWALS; i++) {
            assertTrue(s.withdraw(100));
        }
    }

    @Test
    void constructorRejectsNegativeRate() {
        assertThrows(IllegalArgumentException.class, () -> new SavingsAccount("A-001", -1));
    }

    @Test
    void constructorOfSuperclassStillValidatesId() {
        assertThrows(IllegalArgumentException.class, () -> new SavingsAccount(" ", 2));
    }

    @Test
    void toStringExtendsTheInheritedOne() {
        SavingsAccount s = new SavingsAccount("A-001", 2);
        assertEquals("BankAccount[A-001, saldo 0] (ahorros, 2 % mensual)", s.toString());
    }
}
