package eu.dnetlib.client.login;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.datepicker.client.CalendarUtil;

import eu.dnetlib.espas.gui.client.Crypto;
import eu.dnetlib.espas.gui.client.UserService;
import eu.dnetlib.espas.gui.client.UserServiceAsync;
import eu.dnetlib.espas.gui.shared.User;
import eu.dnetlib.espas.gui.shared.UserAccessException;
import eu.dnetlib.espas.gui.shared.UserAccessException.ErrorCode;

public class LoginPage {

    private Element loginError = Document.get().getElementById("loginError");
    private InputElement usernameElement = (InputElement) Document.get().getElementById("creds_username");
    private InputElement passwordElement = (InputElement) Document.get().getElementById("creds_password");
    private Element submitElement = Document.get().getElementById("submitButton");
    private Button submitButton = Button.wrap(submitElement);

	private UserServiceAsync userAccessService = GWT.create(UserService.class);

    private LoginListener loginListener;
	
	public LoginPage() {

        submitButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent arg0) {

                loginError.getStyle().setDisplay(Style.Display.NONE);

                if(usernameElement.getValue()==null || passwordElement.getValue()==null
                        || usernameElement.getValue().trim().equals("") || passwordElement.getValue().trim().equals("")) {

                    loginError.setInnerText("Login failed - Both email and password fields are required.");
                    loginError.getStyle().setDisplay(Style.Display.BLOCK);

                } else {

                    userAccessService.getUserById(usernameElement.getValue(), passwordElement.getValue(), new AsyncCallback<User>() {

                        @Override
                        public void onSuccess(User user) {

                            boolean isUserAdmin = false;
                            for(String role : user.getRoles()) {
                                if(role.equals("admin"))
                                    isUserAdmin = true;
                            }

                            if(isUserAdmin) {
                                User.currentUser = user;
                                Date expireDate = new Date();
                                CalendarUtil.addDaysToDate(expireDate, 1);
                                Cookies.setCookie("currentUser", Crypto.encrypt(usernameElement.getValue()), expireDate);

                                if (loginListener != null)
                                    loginListener.loginSucceeded(user);

                            } else {
                                loginError.setInnerText("Login failed - User not authorized..");
                                loginError.getStyle().setDisplay(Style.Display.BLOCK);
                            }
                        }

                        @Override
                        public void onFailure(Throwable t) {

                            if(t instanceof UserAccessException) {
                                UserAccessException uae = (UserAccessException) t;
                                if(uae.getErrorCode().equals(ErrorCode.INVALID_PASSWORD) || uae.getErrorCode().equals(ErrorCode.INVALID_USERNAME)) {
                                    loginError.setInnerText("Login failed - Invalid username or password.");
                                    loginError.getStyle().setDisplay(Style.Display.BLOCK);
                                } else if(uae.getErrorCode().equals(ErrorCode.NOT_ACTIVATED)) {
                                    loginError.setInnerText("Login failed - Your account has not yet been activated.");
                                    loginError.getStyle().setDisplay(Style.Display.BLOCK);
                                } else {
                                    loginError.setInnerText("Login failed - Something went wrong, please try again.");
                                    loginError.getStyle().setDisplay(Style.Display.BLOCK);
                                }
                            } else {
                                loginError.setInnerText("Login failed - Something went wrong, please try again.");
                                loginError.getStyle().setDisplay(Style.Display.BLOCK);
                            }
                        }
                    });
                }
            }
        });
	}

    public void showLoginPage() {
        Document.get().getElementById("wrapper").getStyle().setDisplay(Style.Display.NONE);
        Document.get().getElementById("login").getStyle().setDisplay(Style.Display.BLOCK);
    }

    public interface LoginListener {
        void loginSucceeded(User user);
    }

    public void setLoginListener(LoginListener loginListener) {
        this.loginListener = loginListener;
    }
}
