package ru.ulstu.grant.model;

import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.file.model.FileData;
import ru.ulstu.project.model.Project;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Entity
@Table(name = "grants")
public class Grant extends BaseEntity {
    public enum GrantStatus {
        APPLICATION("Заявка"),
        ON_COMPETITION("Отправлен на конкурс"),
        SUCCESSFUL_PASSAGE("Успешное прохождение"),
        IN_WORK("В работе"),
        COMPLETED("Завершен"),
        FAILED("Провалены сроки"),
        LOADED_FROM_KIAS("Загружен автоматически");

        private String statusName;

        GrantStatus(String statusName) {
            this.statusName = statusName;
        }

        public String getStatusName() {
            return statusName;
        }
    }

    @NotBlank
    private String title;

    @Enumerated(value = EnumType.STRING)
    private GrantStatus status = GrantStatus.APPLICATION;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "grant_id")
    private List<Deadline> deadlines = new ArrayList<>();

    //Описание гранта
    @NotNull
    private String comment;

    //Заявка на грант
    @ManyToOne
    @JoinColumn(name = "file_id")
    private FileData application;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "project_id")
    private Project project;

    public GrantStatus getStatus() {
        return status;
    }

    public void setStatus(GrantStatus status) {
        this.status = status;
    }

    public List<Deadline> getDeadlines() {
        return deadlines;
    }

    public void setDeadlines(List<Deadline> deadlines) {
        this.deadlines = deadlines;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public FileData getApplication() {
        return application;
    }

    public void setApplication(FileData application) {
        this.application = application;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }

    public Optional<Deadline> getNextDeadline() {
        return deadlines
                .stream()
                .filter(deadline -> deadline.getDate() != null)
                .sorted(Comparator.comparing(Deadline::getDate))
                .filter(d -> d.getDate().after(new Date()))
                .findFirst();
    }
}
