package eu.dnetlib.client.user;

import com.github.gwtbootstrap.client.ui.Alert;
import com.github.gwtbootstrap.client.ui.Form;
import com.github.gwtbootstrap.client.ui.ListBox;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.github.gwtbootstrap.client.ui.constants.AlternateSize;
import com.github.gwtbootstrap.client.ui.constants.FormType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import eu.dnetlib.client.GoldOAConstants;
import eu.dnetlib.client.widgets.FormFieldSet;
import eu.dnetlib.client.widgets.TextBox;
import eu.dnetlib.client.widgets.ValueChangeEvent;
import eu.dnetlib.client.widgets.ValueChangeHandler;
import eu.dnetlib.goldoa.domain.Project;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by stefania on 4/8/15.
 */
public class FutureEligibleProjectsInfoElement implements IsWidget {

    private FlowPanel futureEligibleProjectsPanel = new FlowPanel();

    private TextBox search = new TextBox();
    private Form sortByForm = new Form();
    private ListBox sortByListForm = new ListBox();

    private FlowPanel futureEligibleProjectsInfoPanel = new FlowPanel();
    private HTML futureEligibleProjectsInfo = new HTML();
    private String futureEligibleProjectsInfoContents = "";
    private Alert futureEligibleProjectsWarningLabel = new Alert();

    private DateTimeFormat dtf = DateTimeFormat.getFormat("yyyy/MM/dd");

    private List<Project> allProjects = new ArrayList<>();
    private List<Project> matchingProjects = new ArrayList<>();

    private GoldOAConstants goldOAConstants = GWT.create(GoldOAConstants.class);

    public FutureEligibleProjectsInfoElement(List<Project> projectList) {

        allProjects.addAll(projectList);
        matchingProjects.addAll(projectList);

        sortRequestsByAcronym();

        futureEligibleProjectsWarningLabel.setText(goldOAConstants.warningNoAvailableEligibleProjects());
        futureEligibleProjectsWarningLabel.addStyleName("alertLabel");
        futureEligibleProjectsWarningLabel.setType(AlertType.WARNING);
        futureEligibleProjectsWarningLabel.setClose(false);
        futureEligibleProjectsWarningLabel.setVisible(false);

        search.addStyleName("searchTextBox");
        search.setPlaceholder("Filter...");
        search.setValueChangeHandler(new ValueChangeHandler() {
            @Override
            public void handle(ValueChangeEvent valueChangeEvent) {

                matchingProjects.clear();
                futureEligibleProjectsWarningLabel.setVisible(false);

                if(valueChangeEvent.getNewValue()!=null && !valueChangeEvent.getNewValue().trim().equals("")) {
                    for (Project project : allProjects) {
                        if (project.getAcronym().toLowerCase().contains(valueChangeEvent.getNewValue().toLowerCase())
                                || dtf.format(project.getEndDate()).contains(valueChangeEvent.getNewValue().toLowerCase())
                                || project.getGrant().toLowerCase().contains(valueChangeEvent.getNewValue().toLowerCase())
                                || project.getTitle().toLowerCase().contains(valueChangeEvent.getNewValue().toLowerCase())) {

                            matchingProjects.add(project);
                        }
                    }
                    redrawProjectList();
                    if(matchingProjects.size()==0) {
                        futureEligibleProjectsWarningLabel.setVisible(true);
                        futureEligibleProjectsInfoPanel.clear();
                    }
                } else {
                    matchingProjects.addAll(allProjects);
                    redrawProjectList();
                }
            }
        });

        sortByListForm.addItem("Acronym", "acronym");
        sortByListForm.addItem("Title", "name");
        sortByListForm.addItem("Grant Id", "ga");
        sortByListForm.addItem("End Date", "date");
        sortByListForm.setAlternateSize(AlternateSize.SMALL);
        sortByListForm.addChangeHandler(new ChangeHandler() {
            @Override
            public void onChange(ChangeEvent event) {
                if(sortByListForm.getValue().equals("date")) {
                    sortRequestsByDate();
                } else if(sortByListForm.getValue().equals("acronym")){
                    sortRequestsByAcronym();
                } else if(sortByListForm.getValue().equals("name")) {
                    sortRequestsByName();
                } else {
                    sortRequestsByGA();
                }
            }
        });
        sortByForm.setType(FormType.HORIZONTAL);
        sortByForm.add(new FormFieldSet("Sort by", sortByListForm));
        sortByForm.addStyleName("float-right");

        futureEligibleProjectsPanel.add(sortByForm);
        futureEligibleProjectsPanel.add(search);
        futureEligibleProjectsPanel.add(futureEligibleProjectsWarningLabel);
        futureEligibleProjectsPanel.add(futureEligibleProjectsInfoPanel);

        if(projectList.isEmpty()) {
            futureEligibleProjectsWarningLabel.setVisible(true);
        }
    }

    @Override
    public Widget asWidget() {
        return futureEligibleProjectsPanel;
    }

    public void addStyleName(String styleName) {
        futureEligibleProjectsPanel.addStyleName(styleName);
    }

    private void redrawProjectList() {

        futureEligibleProjectsInfoPanel.clear();
        futureEligibleProjectsInfoContents = "";

        for(int i=0; i<matchingProjects.size(); i++) {
            if(((i+1)%2)==1)
                futureEligibleProjectsInfoContents += "<dd class=\"odd\">";
            else
                futureEligibleProjectsInfoContents += "<dd>";

            if (matchingProjects.get(i).getAcronym() != null)
                futureEligibleProjectsInfoContents += "<span class=\"strong\">" + matchingProjects.get(i).getAcronym() + "</span>";

            if (matchingProjects.get(i).getGrant() !=null)
                futureEligibleProjectsInfoContents += "<span class=\"strong\"> - " + matchingProjects.get(i).getGrant() + "</span>";

            if (matchingProjects.get(i).getTitle() != null)
                futureEligibleProjectsInfoContents += " \"" + matchingProjects.get(i).getTitle() + "\" ";

            if (matchingProjects.get(i).getEndDate()!=null)
                futureEligibleProjectsInfoContents += " (end date " + dtf.format(matchingProjects.get(i).getEndDate()) + ")";

            futureEligibleProjectsInfoContents += "</dd>";
        }
        futureEligibleProjectsInfo.setHTML(futureEligibleProjectsInfoContents);

        futureEligibleProjectsInfoPanel.add(futureEligibleProjectsInfo);
    }

    private void sortRequestsByDate() {

        Collections.sort(matchingProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getEndDate().compareTo(p2.getEndDate());
            }
        });
        Collections.sort(allProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getEndDate().compareTo(p2.getEndDate());
            }
        });
        redrawProjectList();
    }

    private void sortRequestsByAcronym() {

        Collections.sort(matchingProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getAcronym().toLowerCase().compareTo(p2.getAcronym().toLowerCase());
            }
        });
        Collections.sort(allProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getAcronym().toLowerCase().compareTo(p2.getAcronym().toLowerCase());
            }
        });

        redrawProjectList();
    }

    private void sortRequestsByName() {

        Collections.sort(matchingProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getTitle().toLowerCase().compareTo(p2.getTitle().toLowerCase());
            }
        });
        Collections.sort(allProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getTitle().toLowerCase().compareTo(p2.getTitle().toLowerCase());
            }
        });
        redrawProjectList();
    }

    private void sortRequestsByGA() {

        Collections.sort(matchingProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getGrant().toLowerCase().compareTo(p2.getGrant().toLowerCase());
            }
        });
        Collections.sort(allProjects, new Comparator<Project>() {

            public int compare(Project p1, Project p2) {
                return p1.getGrant().toLowerCase().compareTo(p2.getGrant().toLowerCase());
            }
        });
        redrawProjectList();
    }
}
