package eu.dnetlib.client.user;

import com.github.gwtbootstrap.client.ui.Alert;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
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.*;
import eu.dnetlib.client.widgets.Anchor;
import eu.dnetlib.goldoa.domain.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by stefania on 4/22/15.
 */
public class MyRecentActivityWidget implements IsWidget {

    private FlowPanel recentRequestsPanel = new FlowPanel();

    private Alert errorLabel = new Alert();
    private Alert warningLabel = new Alert();

    private FlowPanel requestsListPanel = new FlowPanel();
    private Anchor viewAll = new Anchor();

    private DataServiceAsync dataService = GWT.create(DataService.class);
    private GoldOAConstants goldOAConstants = GWT.create(GoldOAConstants.class);

    public MyRecentActivityWidget() {

        errorLabel.addStyleName("alertLabel");
        errorLabel.addStyleName("marginTop30");
        errorLabel.setType(AlertType.ERROR);
        errorLabel.setClose(false);
        errorLabel.setVisible(false);

        warningLabel.addStyleName("alertLabel");
        warningLabel.addStyleName("marginTop30");
        warningLabel.setType(AlertType.WARNING);
        warningLabel.setClose(false);
        warningLabel.setVisible(false);

        viewAll.setText("View all...");
        viewAll.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                History.newItem("existingFundingRequests");
            }
        });

        final HTML loadingWheel = new HTML("<div class=\"loader\"></div><div class=\"whiteFilm\"></div>");
        requestsListPanel.addStyleName("loading-small");
        requestsListPanel.add(loadingWheel);

        if(Utils.currentUserHasRole("publisher")) {
            loadRequestsForPublisher(null, null, RequestSort.DATE, RequestSortOrder.DESCENDING, null, null, null, 0, 4);
        } else if(Utils.currentUserHasRole("library_staff")) {
            loadRequestsForLibrarian(null, null, RequestSort.DATE, RequestSortOrder.DESCENDING, null, null, null, 0, 4);
        } else {
            loadRequestsForGeneralUser(null, null, RequestSort.DATE, RequestSortOrder.DESCENDING, null, null, null, 0, 4);
        }

        requestsListPanel.addStyleName("recentRequestsList");

        recentRequestsPanel.add(errorLabel);
        recentRequestsPanel.add(warningLabel);
        recentRequestsPanel.add(requestsListPanel);
    }

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

    private void loadRequestsForLibrarian(Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order,
                                          RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilters,
                                          int from, int to) {

        List<String> organizationIds = new ArrayList<>();
        for(Affiliation affiliation : GoldOAPortal.currentUser.getAffiliations()) {
            if(affiliation.getOrganization()!=null)
                organizationIds.add(affiliation.getOrganization().getId());
        }

        dataService.getRequestsForOrganizations(organizationIds, fromDate, toDate, requestSortBy, order, requestFilter, term, statusFilters,
                from, to, new AsyncCallback<RequestInfoPage>() {

                    @Override
                    public void onFailure(Throwable throwable) {

                        requestsListPanel.clear();
                        requestsListPanel.removeStyleName("loading-small");

                        errorLabel.setText(goldOAConstants.errorGettingListOfFundingRequests());
                        errorLabel.setVisible(true);
                    }

                    @Override
                    public void onSuccess(RequestInfoPage requestInfoPage) {

                        requestsListPanel.clear();
                        requestsListPanel.removeStyleName("loading-small");

                        if(requestInfoPage.getRequests().isEmpty()) {
                            warningLabel.setText(goldOAConstants.warningNoFundingRequestsAvailable());
                            warningLabel.setVisible(true);
                        } else {
                            for(int i=0; i<requestInfoPage.getRequests().size(); i++)
                                drawRequestInfo(requestInfoPage.getRequests().get(i), i);
                            recentRequestsPanel.add(viewAll);
                        }
                    }
                });
    }

    private void loadRequestsForPublisher(Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order,
                                          RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilters,
                                          int from, int to) {

        dataService.getRequestsForPublisher(GoldOAPortal.currentUser.getPublisher().getId(), fromDate, toDate, requestSortBy, order,
                requestFilter, term, statusFilters, from, to, new AsyncCallback<RequestInfoPage>() {

                    @Override
                    public void onFailure(Throwable throwable) {

                        requestsListPanel.clear();
                        requestsListPanel.removeStyleName("loading-small");

                        errorLabel.setText(goldOAConstants.errorGettingListOfFundingRequests());
                        errorLabel.setVisible(true);
                    }

                    @Override
                    public void onSuccess(RequestInfoPage requestInfoPage) {

                        requestsListPanel.clear();
                        requestsListPanel.removeStyleName("loading-small");

                        if(requestInfoPage.getRequests().isEmpty()) {
                            warningLabel.setText(goldOAConstants.warningNoFundingRequestsAvailable());
                            warningLabel.setVisible(true);
                        } else {
                            for(int i=0; i<requestInfoPage.getRequests().size(); i++)
                                drawRequestInfo(requestInfoPage.getRequests().get(i), i);
                            recentRequestsPanel.add(viewAll);
                        }
                    }
                });
    }

    private void loadRequestsForGeneralUser(Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order,
                                            RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilters,
                                            int from, int to) {

        dataService.getRequestsForUser(GoldOAPortal.currentUser.getId(), fromDate, toDate, requestSortBy, order, requestFilter,
                term, statusFilters, from, to, new AsyncCallback<RequestInfoPage>() {

                    @Override
                    public void onFailure(Throwable throwable) {

                        requestsListPanel.clear();
                        requestsListPanel.removeStyleName("loading-small");

                        errorLabel.setText(goldOAConstants.errorGettingListOfFundingRequests());
                        errorLabel.setVisible(true);
                    }

                    @Override
                    public void onSuccess(RequestInfoPage requestInfoPage) {

                        requestsListPanel.clear();
                        requestsListPanel.removeStyleName("loading-small");

                        if(requestInfoPage.getRequests().isEmpty()) {
                            warningLabel.setText(goldOAConstants.warningNoFundingRequestsAvailable());
                            warningLabel.setVisible(true);
                        } else {
                            for(int i=0; i<requestInfoPage.getRequests().size(); i++)
                                drawRequestInfo(requestInfoPage.getRequests().get(i), i);
                            recentRequestsPanel.add(viewAll);
                        }
                    }
                });
    }

    private void drawRequestInfo(final RequestInfo requestInfo, int i) {

        final HTML requestInfoElement = new HTML();
        if(((i+1)%2)==1)
            requestInfoElement.addStyleName("odd");

        String content = "";

        if(requestInfo.getPublication()!=null) {
            if(requestInfo.getPublication().getTitle().length()>50)
                content += requestInfo.getPublication().getTitle().substring(0, 50) + " ... ";
            else
                content += requestInfo.getPublication().getTitle();
        }
        content += "<div class=\"status\">" + requestInfo.getStatus().getValue().toUpperCase() + "</div>";

        requestInfoElement.setHTML(content);

        requestInfoElement.addMouseOverHandler(new MouseOverHandler() {
            @Override
            public void onMouseOver(MouseOverEvent mouseOverEvent) {
                if(requestInfo.getPublication()!=null && requestInfo.getPublication().getTitle().length()>50)
                    requestInfoElement.setTitle(requestInfo.getPublication().getTitle());
            }
        });

        requestsListPanel.add(requestInfoElement);
    }
}
