package ch.zhaw.gartenverwaltung.types;


import java.time.LocalDate;
import java.util.Optional;

/**
 * Models a Task
 * May be created using the builder pattern.
 */
public class Task {
    private Long id;
    private String name;
    private String description;
    private LocalDate startDate;
    private Integer interval;
    private LocalDate endDate;
    private LocalDate nextExecution;
    private LocalDate nextNotification;
    private long cropId;
    private boolean done;

    /**
     * default constructor
     * (used by Json deserializer)
     */
    public Task(){
        name= "";
        description= "";
        startDate = LocalDate.now();
        endDate = startDate;
        nextExecution = startDate;
    }

    public Task(String name, String description, LocalDate startDate, long cropId) {
        this.name = name;
        this.description = description;
        this.startDate = startDate;
        this.endDate = startDate;
        nextExecution = startDate;
        this.cropId = cropId;
    }

    public Task(String name, String description, LocalDate startDate, LocalDate endDate, int interval, long cropId) {
        this.name = name;
        this.description = description;
        this.startDate = startDate;
        nextExecution = startDate;
        this.endDate = endDate;
        this.interval = interval;
        this.cropId = cropId;
    }

    // Builder-pattern-style setters
    public Task withId(long id) {
        this.id = id;
        return this;
    }
    public Task withInterval(int interval) {
        this.interval = interval;
        return this;
    }
    public Task withEndDate(LocalDate endDate) {
        this.endDate = endDate;
        return this;
    }

    public boolean isInTimePeriode(LocalDate searchStartDate, LocalDate searchEndDate){
        return endDate.isAfter(searchStartDate) && startDate.isBefore(searchEndDate);
    }

    public void done(){
        if(interval != null && interval != 0 && !nextExecution.plusDays(interval).isAfter(endDate)){
            nextExecution = nextExecution.plusDays(interval);
        } else {
            nextExecution = null;
        }
    }

    public boolean isDone(){
        return nextExecution == null;
    }

    public void setNextExecution(LocalDate nextExecution) {
        this.nextExecution = nextExecution;
    }

    public void setNextNotification(LocalDate nextNotification) {
        this.nextNotification = nextNotification;
    }

    // Getters
    public LocalDate getNextNotification() { return nextNotification; }
    public LocalDate getNextExecution() { return nextExecution; }
    public Optional<Long> getId() { return Optional.ofNullable(id); }
    public String getName() { return name; }
    public String getDescription() { return description; }
    public LocalDate getStartDate() { return startDate; }
    public long getCropId() { return cropId; }

    public Optional<Integer> getInterval() {
        return Optional.ofNullable(interval);
    }
    public Optional<LocalDate> getEndDate() {
        return Optional.ofNullable(endDate);
    }

    public Task updateTask(Task task) {
        this.name = task.getName();
        this.description = task.getDescription();
        this.startDate = task.getStartDate();
        this.endDate = task.getEndDate().orElse(null);
        this.interval = task.getInterval().orElse(0);
        this.cropId = task.getCropId();
        return this;
    }
}
