package ch.zhaw.gartenverwaltung.gardenplan;

import ch.zhaw.gartenverwaltung.io.*;
import ch.zhaw.gartenverwaltung.taskList.PlantNotFoundException;
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
import ch.zhaw.gartenverwaltung.types.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.time.LocalDate;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.List;

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

public class GardenPlanModelTest {
    GardenPlan gardenPlan;
    List<Crop> cropList;
    Crop exampleCropOnion;
    Crop exampleCropCarrot;
    Crop exampleCrop1;
    Crop exampleCrop2;
    Crop exampleCrop3;
    Plant examplePlantOnion;
    Plant examplePlantCarrot;
    Gardenplanmodel model;

    @BeforeEach
    void setUp() throws IOException {


        examplePlantOnion = new Plant(
                0,
                "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<>(),
                List.of(new GrowthPhase(MonthDay.of(6, 4), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.HARVEST, HardinessZone.ZONE_8A, new ArrayList<>()),
                        new GrowthPhase(MonthDay.of(4, 3), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()),
                        new GrowthPhase(MonthDay.of(8, 5), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()),
                        new GrowthPhase(MonthDay.of(2, 8), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()),
                        new GrowthPhase(MonthDay.of(10, 2), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>())));

        exampleCropOnion = new Crop(examplePlantOnion.id(),  LocalDate.of(2023,3,1));
        exampleCropOnion.withId(3);
        examplePlantCarrot = new Plant(
                1,
                "Early Carrot",
                "Carrot, (Daucus carota), herbaceous, generally biennial plant of the Apiaceae family that produces an edible taproot. Among common varieties root shapes range from globular to long, with lower ends blunt to pointed. Besides the orange-coloured roots, white-, yellow-, and purple-fleshed varieties are known.",
                null,
                "5,35,2.5",
                0,
                "sandy to loamy, loose soil, free of stones",
                new ArrayList<>(),
                List.of(new GrowthPhase(MonthDay.of(4, 4), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>())));
        exampleCropCarrot = new Crop(examplePlantCarrot.id(), LocalDate.now());
        exampleCropCarrot.withId(5);

        exampleCrop1 = new Crop(1, LocalDate.of(2023,2,25));
        exampleCrop1.withId(0);
        exampleCrop1.withArea(0.5);
        exampleCrop2 = new Crop(1,LocalDate.of(2023,3,1));
        exampleCrop2.withId(1);
        exampleCrop2.withArea(0.5);
        exampleCrop3 = new Crop(0,LocalDate.of(2023,3,01));
        exampleCrop3.withId(2);
        exampleCrop3.withArea(1.0);

        cropList = new ArrayList<>();
        cropList.add(exampleCrop1);
        cropList.add(exampleCrop2);
        cropList.add(exampleCrop3);
        gardenPlan = mockGardenPlan(cropList);

        TaskListModel taskListModel = new TaskListModel(new JsonTaskDatabase(), new JsonPlantDatabase());
        model = new Gardenplanmodel(taskListModel);
    }

    GardenPlan mockGardenPlan(List<Crop> cropList) throws IOException {
        GardenPlan gardenPlan = mock(GardenPlan.class);
        when(gardenPlan.getCrops()).thenReturn(cropList);
        when(gardenPlan.getCropById(5)).thenReturn(java.util.Optional.ofNullable(exampleCropCarrot));
        when(gardenPlan.getCropById(3)).thenReturn(java.util.Optional.ofNullable(exampleCropOnion));
        return gardenPlan;
    }

    @Test
    void plantAsCrop() throws HardinessZoneNotSetException, IOException, PlantNotFoundException {

        model.plantAsCrop(examplePlantOnion, LocalDate.of(2023,3,1));
        exampleCropOnion = model.getCrop(2L).get();
        assertEquals(model.getCrops().get(2),exampleCropOnion);

    }

    @Test
    void removeCrop() throws IOException {
        exampleCrop1.withId(2);
        exampleCrop1.withArea(1.500000);
        model.removeCrop(exampleCrop1);
        assertEquals(2,model.getCrops().size());
    }
}
