import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.List;
import org.junit.jupiter.api.Test;

class FactoryTest {

    @Test
    void moneyOfValidatesAndNormalizes() {
        assertEquals("USD", Money.of(100, " usd ").currency());
        assertThrows(IllegalArgumentException.class, () -> Money.of(-1, "PEN"));
        assertThrows(IllegalArgumentException.class, () -> Money.of(1, "SOLES"));
    }

    @Test
    void zeroInSolesIsAlwaysTheSameObject() {
        assertSame(Money.zero(), Money.of(0, "PEN"));
        assertSame(Money.zero(), Money.parse("0.00"));
    }

    @Test
    void parseReadsSoles() {
        assertEquals(Money.of(1250, "PEN"), Money.parse("12.5"));
        assertEquals(Money.of(1205, "PEN"), Money.parse("12.05"));
        assertEquals(Money.of(1200, "PEN"), Money.parse("12"));
    }

    @Test
    void notificationFactoryChoosesTheClass() {
        assertInstanceOf(EmailNotification.class, Notification.of("email", "a@b.pe", "hola"));
        assertInstanceOf(SmsNotification.class, Notification.of("sms", "999", "hola"));
        assertThrows(IllegalArgumentException.class, () -> Notification.of("fax", "1", "hola"));
    }

    @Test
    void importerSkipsCommentsAndBlankLines() {
        List<Notification> all = new NotificationImporter().importAll(List.of(
                "# comentario", "", "email;alice@uni.pe;Hola", "sms;999;Chau"));
        assertEquals(List.of(new EmailNotification("alice@uni.pe", "Hola"), new SmsNotification("999", "Chau")), all);
    }

    @Test
    void importerReportsTheLineNumber() {
        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
                () -> new SongImporter().importAll(List.of("A;B;100", "solo un campo")));
        assertEquals("línea 2: se esperaban 3 campos y hay 1", e.getMessage());
    }

    @Test
    void songImporterCreatesSongs() {
        assertEquals(List.of(new Song("Valicha", "Miguel Ángel Hurtado", 192)),
                new SongImporter().importAll(List.of("Valicha ; Miguel Ángel Hurtado ; 192")));
    }
}
