package ch.zhaw.gartenverwaltung.types;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

class PlantTest {

    Plant testPlant;

    @BeforeEach
    void setUp() {
        List<GrowthPhase> growthPhases = new ArrayList<>();
        growthPhases.add(new GrowthPhase(MonthDay.of(2, 1), MonthDay.of(4, 4), 0, GrowthPhaseType.SOW, HardinessZone.ZONE_8A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(4, 2), MonthDay.of(6, 5), 0,  GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(6, 3), MonthDay.of(8, 6), 0,  GrowthPhaseType.HARVEST, HardinessZone.ZONE_8A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(3, 1), MonthDay.of(5, 4), 1,  GrowthPhaseType.SOW, HardinessZone.ZONE_8A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(5, 2), MonthDay.of(7, 5), 1,  GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(7, 3), MonthDay.of(9, 6), 1,  GrowthPhaseType.HARVEST, HardinessZone.ZONE_8A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(4, 1), MonthDay.of(6, 4), 0,  GrowthPhaseType.SOW, HardinessZone.ZONE_1A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(6, 2), MonthDay.of(8, 5), 0,  GrowthPhaseType.PLANT, HardinessZone.ZONE_1A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(7, 2), MonthDay.of(9, 5), 0,  GrowthPhaseType.PLANT, HardinessZone.ZONE_1A, new ArrayList<>()));
        growthPhases.add(new GrowthPhase(MonthDay.of(8, 3), MonthDay.of(10, 6), 0,  GrowthPhaseType.HARVEST, HardinessZone.ZONE_1A, new ArrayList<>()));

        testPlant = new Plant(
                20,
                "summertime onion",
                "Onion, (Allium cepa), herbaceous biennial plant in the amaryllis family (Amaryllidaceae) grown for its edible bulb. The onion is likely native to southwestern Asia but is now grown throughout the world, chiefly in the temperate zones. Onions are low in nutrients but are valued for their flavour and are used widely in cooking. They add flavour to such dishes as stews, roasts, soups, and salads and are also served as a cooked vegetable.",
                null,
                "15,30,2",
                0,
                "sandy to loamy, loose soil, free of stones",
                new ArrayList<>(),
                new WateringCycle(25, 0, null),
                growthPhases);
    }

    @AfterEach
    void tearDown() {
    }

    @Test
    void inZone() {
        assertEquals(7,testPlant.lifecycleForGroup(0).size());
        testPlant.inZone(HardinessZone.ZONE_8A);
        assertEquals(3,testPlant.lifecycleForGroup(0).size());
        assertEquals(Arrays.asList(3,5,7),testPlant.lifecycleForGroup(1).stream().map(gp ->gp.startDate().getMonthValue()).toList() );
        testPlant.inZone(HardinessZone.ZONE_1A);
        assertEquals(0,testPlant.lifecycleForGroup(0).size());
    }

    @Test
    void lifecycleForGroup() {
        assertEquals(Arrays.asList(2,4,6,4,6,7,8),testPlant.lifecycleForGroup(0).stream().map(gp ->gp.startDate().getMonthValue()).toList() );
        assertEquals(Arrays.asList(3,5,7),testPlant.lifecycleForGroup(1).stream().map(gp ->gp.startDate().getMonthValue()).toList() );

    }

    @Test
    void sowDateFromHarvestDate() {
        assertEquals(LocalDate.of(2022,8,1),
                testPlant.sowDateFromHarvestDate(LocalDate.of(2022,12,1))
        );
    }

    @Test
    void timeToHarvest() {
        testPlant.inZone(HardinessZone.ZONE_8A);
        assertEquals(122,testPlant.timeToHarvest(0));
    }

    @Test
    void lifecycleGroupFromHarvestDate() {
        testPlant.inZone(HardinessZone.ZONE_8A);
        assertEquals(0,testPlant.lifecycleGroupFromHarvestDate(LocalDate.of(2022,6,30)));
        assertEquals(1,testPlant.lifecycleGroupFromHarvestDate(LocalDate.of(2022,8,30)));
    }

    @Test
    void isDateInPhase() {
        assertTrue(testPlant.isDateInPhase(LocalDate.of(2022,6,30),GrowthPhaseType.HARVEST));
        assertTrue(testPlant.isDateInPhase(LocalDate.of(2022,8,30),GrowthPhaseType.HARVEST));
        assertTrue(testPlant.isDateInPhase(LocalDate.of(2022,2,1),GrowthPhaseType.SOW));
        assertTrue(testPlant.isDateInPhase(LocalDate.of(2022,4,2),GrowthPhaseType.PLANT));
        assertFalse(testPlant.isDateInPhase(LocalDate.of(2022,6,30),GrowthPhaseType.SOW));


    }
}