package eu.dnetlib.espas.gui.client;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.github.gwtbootstrap.client.ui.*;
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
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.Window;
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.RootPanel;

import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.sencha.gxt.widget.core.client.info.Info;
import eu.dnetlib.espas.gui.shared.InitLoad;
import eu.dnetlib.espas.gui.shared.ModelDocumentation;
import eu.dnetlib.espas.gui.shared.User;
import eu.dnetlib.espas.gui.shared.UserAccessException;
import eu.dnetlib.espas.gui.shared.UserAccessException.ErrorCode;

public abstract class EspasEntrypoint implements EntryPoint {
	
	private UserServiceAsync userAccessService = GWT.create(UserService.class);
    private SupportContentServiceAsync supportContentService = GWT.create(SupportContentService.class);

    public static InitLoad initLoad = null;

	public abstract void onLoad();

    protected Map<String, ClickHandler> getOverrideMenuHandlers() {
        return new HashMap<String, ClickHandler>();
    }
	
	@Override
	public final void onModuleLoad() {
		
		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			
			Logger logger = Logger.getLogger("UncaughtException");

			@Override
			public void onUncaughtException(Throwable arg0) {

				logger.log(Level.SEVERE, "Exception: ", arg0);
			}
		});

        String agreedToCookies = Cookies.getCookie("agreedToCookies");
        if(agreedToCookies==null) {
            loadCookieInfo();
        }

        ModelDocumentation.loadDocumentationMap();

        RegisterLoginElement registerLoginElement = new RegisterLoginElement();
        RootPanel.get("userInfo").clear();
        RootPanel.get("userInfo").add(registerLoginElement.asWidget());
        registerLoginElement.addRegisterLoginHandler();

        supportContentService.getSupportContent(new AsyncCallback<InitLoad>() {

            @Override
            public void onFailure(Throwable throwable) {

                initLoad = null;
                loadContent();
            }

            @Override
            public void onSuccess(InitLoad initLoad) {

                EspasEntrypoint.initLoad = initLoad;
                loadContent();
            }
        });
	}

    private void loadCookieInfo() {

        FlowPanel cookieInfoPanel = new FlowPanel();

        HTML cookieInfo = new HTML();
        cookieInfo.setHTML("<div class=\"cookiesInfoTitle\">ESPAS uses cookies</div><div>Cookies are small text files held on " +
                "your computer, which allow us to give you the best browsing experience possible. You can choose to block " +
                "cookies but parts of our site won't function optimally without them. By using the ESPAS portal you accept " +
                "our use of cookies.</div>");
        cookieInfo.addStyleName("inlineBlock");
        cookieInfo.addStyleName("cookieInfo");

        Button agreeButton = new Button();
        agreeButton.setText("OK");
        agreeButton.addStyleName("agreeToCookiesButton");
        agreeButton.setType(ButtonType.PRIMARY);
        agreeButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {

                Date expireDate = new Date();
                CalendarUtil.addDaysToDate(expireDate, 30);
                Cookies.setCookie("agreedToCookies", "true", expireDate);

                RootPanel.get("cookieInfoContainer").getElement().getStyle().setDisplay(Style.Display.NONE);
            }
        });

        cookieInfoPanel.add(cookieInfo);
        cookieInfoPanel.add(agreeButton);

        RootPanel.get("cookieInfoContainer").add(cookieInfoPanel);

        RootPanel.get("cookieInfoContainer").getElement().getStyle().setDisplay(Style.Display.BLOCK);
    }

    private void loadContent() {

        String encryptedEmail = Cookies.getCookie("currentUser");

        if (encryptedEmail != null) {

            userAccessService.getUserById(Crypto.decrypt(encryptedEmail), new AsyncCallback<User>() {

                @Override
                public void onFailure(Throwable t) {

                    Cookies.removeCookie("currentUser");
                    User.currentUser = null;

                    RootPanel.get("userInfo").clear();
                    RegisterLoginElement registerLoginElement = new RegisterLoginElement();
                    RootPanel.get("userInfo").add(registerLoginElement.asWidget());
                    registerLoginElement.addRegisterLoginHandler();

                    String url = GWT.getHostPageBaseURL() + "index.html";
                    Window.Location.replace(url);
                }

                @Override
                public void onSuccess(User user) {

                    User.currentUser = user;

                    UserInfoElement userInfoElement = new UserInfoElement(User.currentUser.getName());
                    RootPanel.get("userInfo").clear();
                    RootPanel.get("userInfo").add(userInfoElement.asWidget());
                    userInfoElement.addSignOutLinkHandler();

                    onLoad();

                    MainMenu.setOverrideHandlers(getOverrideMenuHandlers());
                    MainMenu.getInstance().addHandlers();
                    RootPanel.get("menu").add(MainMenu.getInstance().asWidget());
                    MainMenu.getInstance().update();
                }
            });

        } else {

            onLoad();

            MainMenu.setOverrideHandlers(getOverrideMenuHandlers());
            MainMenu.getInstance().addHandlers();
            RootPanel.get("menu").add(MainMenu.getInstance().asWidget());
            MainMenu.getInstance().update();
        }
    }

}
