package eu.dnetlib.client.adminpanel;

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.query.client.Function;
import com.google.gwt.user.client.Event;
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.Widget;
import eu.dnetlib.client.Admin;
import eu.dnetlib.client.AdminWidget;
import eu.dnetlib.espas.gui.client.UserService;
import eu.dnetlib.espas.gui.client.UserServiceAsync;
import eu.dnetlib.espas.gui.shared.User;

import java.util.List;

import static com.google.gwt.query.client.GQuery.$;

public class ActionsWidget implements AdminWidget {
	
	private static ActionsWidget instance = null;

    private FlowPanel manageActionsPanel = new FlowPanel();

    private Alert errorAlert = new Alert();
    private Alert successAlert = new Alert();

    private FlowPanel actionsPanel = new FlowPanel();
	
	private ActionServiceAsync actionService = GWT.create(ActionService.class);
	private UserServiceAsync userAccessService = GWT.create(UserService.class);
	
	private ActionsWidget() {

        manageActionsPanel.addStyleName("contentPanel");

        errorAlert.setType(AlertType.ERROR);
        errorAlert.setVisible(false);
        errorAlert.setClose(false);
        manageActionsPanel.add(errorAlert);

        successAlert.setType(AlertType.SUCCESS);
        successAlert.setVisible(false);
        successAlert.setClose(false);
        manageActionsPanel.add(successAlert);

        manageActionsPanel.add(actionsPanel);
	}
	
	public static final ActionsWidget getInstance() {
		
		if(instance==null)
			instance = new ActionsWidget();
		
		return instance;
	}

    @Override
    public void clear() {

        errorAlert.setVisible(false);
        successAlert.setVisible(false);

        actionsPanel.clear();
    }

    @Override
    public void reload() {

        Admin.menuBar.clear();

        Admin.menuBar.add(new HTML("<div class=\"sidebar-toggler visible-xs\"><i class=\"ion-navicon\"></i></div>"));
        Admin.menuBar.add(new HTML("<div class=\"page-title\" id=\"pageTitle\">Pending Actions</div>"));

        updateActions(true, null);
    }

    private void updateActions(final boolean clearAlerts, final String successMessage) {

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

        actionService.getPendingDataProviderUsers(new AsyncCallback<List<User>>() {

            @Override
            public void onSuccess(List<User> users) {

                if(clearAlerts) {
                    errorAlert.setVisible(false);
                    successAlert.setVisible(false);
                }

                if(successMessage!=null) {
                    successAlert.setText(successMessage);
                    successAlert.setVisible(true);
                }

                manageActionsPanel.removeStyleName("loading-big");
                manageActionsPanel.remove(loadingWheel);

                updateContents(users);
            }

            @Override
            public void onFailure(Throwable arg0) {

                successAlert.setVisible(false);

                errorAlert.setText("System error retrieving actions");
                errorAlert.setVisible(true);
            }
        });
    }

    @Override
    public void setToken(String token) {

    }

    @Override
    public void afterAdditionToRootPanel() {

    }
	
	public void updateContents(List<User> users) {

        actionsPanel.clear();

        String contents = "<div class=\"steps\">";

        if(users.size()==0) {

            contents += "<div class=\"alert alert-warning\">No pending actions found</div>";

        } else {

            for (User pendingDataProvider : users) {
                contents += "<div class=\"step clearfix\">" +
                        "<div class=\"info\">" +
                        "<span class=\"number\">" +
                        "<img src=\"imgs/user_data_provider.png\">" +
                        "</span>User " + pendingDataProvider.getName() + " (" + pendingDataProvider.getEmail() + ") has requested to become a " +
                        "data provider administrator." +
                        "</div>" +
                        "<div class=\"pull-right\">" +
                        "<a id=\"" + pendingDataProvider.getEmail() + "#accept\" class=\"btn btn-primary acceptDataProvider\" href=\"#\"><span>Accept</span></a>" +
                        "<a id=\"" + pendingDataProvider.getEmail() + "#deny\" class=\"btn btn-default denyDataProvider\" href=\"#\"><span>Deny</span></a>" +
                        "</div></div>";
            }
        }

        contents += "</div>";

        HTML usersList = new HTML();
        usersList.setHTML(contents);

        actionsPanel.add(usersList);

        addWidgetHandlers();

	}

	@Override
	public Widget asWidget() {
		return manageActionsPanel;
	}
	
	public void addWidgetHandlers() {
		
		$(".acceptDataProvider").click(new Function() {
			
			public boolean f(Event e) {

                errorAlert.setVisible(false);
                successAlert.setVisible(false);

				final String[] idParts = $(e).get(0).getId().split("#");

                final HTML loadingWheel = new HTML("<div class=\"loader-big\"></div><div class=\"whiteFilm\"></div>");
                manageActionsPanel.addStyleName("loading-big");
                manageActionsPanel.add(loadingWheel);
				
				userAccessService.addRoleToUser(idParts[0], "dataprovider", new AsyncCallback<Void>() {

					@Override
					public void onFailure(Throwable arg0) {

                        manageActionsPanel.removeStyleName("loading-big");
                        manageActionsPanel.remove(loadingWheel);

                        errorAlert.setText("Failed to grant user " + idParts[0] + " with data provider administrator role");
                        errorAlert.setVisible(true);
					}

					@Override
					public void onSuccess(Void arg0) {

                        manageActionsPanel.removeStyleName("loading-big");
                        manageActionsPanel.remove(loadingWheel);

                        updateActions(false, "Role data provider administrator successfully granted to user " + idParts[0]);
						AdminPanelController.getInstance().updateNoOfActions();
					}
				});
				
				return true;
			}
		});
		
		$(".denyDataProvider").click(new Function() {
			
			public boolean f(Event e) {

                errorAlert.setVisible(false);
                successAlert.setVisible(false);

				final String[] idParts = $(e).get(0).getId().split("#");

                final HTML loadingWheel = new HTML("<div class=\"loader-big\"></div><div class=\"whiteFilm\"></div>");
                manageActionsPanel.addStyleName("loading-big");
                manageActionsPanel.add(loadingWheel);
				
				userAccessService.denyDataProviderRoleToUser(idParts[0], new AsyncCallback<Void>() {

					@Override
					public void onFailure(Throwable arg0) {

                        manageActionsPanel.removeStyleName("loading-big");
                        manageActionsPanel.remove(loadingWheel);

                        errorAlert.setText("Failed to deny user " + idParts[0] + " the data provider administrator role");
                        errorAlert.setVisible(true);
					}

					@Override
					public void onSuccess(Void arg0) {

                        manageActionsPanel.removeStyleName("loading-big");
                        manageActionsPanel.remove(loadingWheel);

                        updateActions(false, "Role data provider administrator successfully denied to user " + idParts[0]);
                        AdminPanelController.getInstance().updateNoOfActions();
					}
				});
				
				return true;
			}
		});
	}
}
