package be.iminds.ilabt.jfed.experimenter_gui.login;

import be.iminds.ilabt.jfed.experimenter_gui.debug.LogViewer;
import be.iminds.ilabt.jfed.ui.javafx.util.StageUtils;
import be.iminds.ilabt.jfed.lowlevel.user.UserLoginInfo;
import be.iminds.ilabt.jfed.ui.javafx.GuiceFXMLUtil;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Provider;

/**
 * User: twalcari
 * Date: 8/9/2016
 * Time: 15:45
 */
public class SimpleUserLoginDialog {
    private static final Logger LOG = LoggerFactory.getLogger(SimpleUserLoginDialog.class);

    private final Stage stage;
    private final SimpleUserLoginController controller;

    private final GuiceFXMLUtil guiceFXMLUtil;
    private final Provider<LogViewer> logViewerProvider;

    @Inject
    public SimpleUserLoginDialog(GuiceFXMLUtil guiceFXMLUtil, Provider<LogViewer> logViewerProvider) {
        this.guiceFXMLUtil = guiceFXMLUtil;
        this.logViewerProvider = logViewerProvider;

        GuiceFXMLUtil.Result<?, SimpleUserLoginController> result =
                guiceFXMLUtil.createFromFXML(SimpleUserLoginController.class);
        controller = result.getController();

        stage = new Stage();
        stage.setTitle("jFed login");
        stage.setResizable(false);
        StageUtils.setJFedStageIcons(stage);

        final Scene scene = new Scene(result.getRoot());
        scene.getAccelerators().put(
                new KeyCodeCombination(KeyCode.F10, KeyCodeCombination.CONTROL_DOWN),
                () -> logViewerProvider.get().show()
        );
        stage.setScene(scene);

    }

    @Nullable
    public SimpleUserLoginController.Result showAndWait(@Nullable UserLoginInfo oldUserLoginInfo) {
        controller.setUserLoginInfo(oldUserLoginInfo);

        stage.showAndWait();

        return controller.getResult();
    }

    @Nullable
    public UserLoginDirector.UserLoginResult showLocalLoginAndWait(UserLoginInfo providedUserLoginInfo) {
        controller.setUserLoginInfo(providedUserLoginInfo);

        //check if the current loginmodel in the UserLoginModelManager is a supported type, otherwise revert to null
        //This should not happen in practice! The UserLoginDirector should divert the user to the {@link AdvancedUserLogin}
        if (providedUserLoginInfo != null && !SimpleUserLoginController.isSupportedLoginMethod(providedUserLoginInfo)) {
            LOG.warn("UserLoginDialog does not support models of type {}", providedUserLoginInfo.getUserLoginTypeName());
            controller.setUserLoginInfo(null);
        }

        if (controller.getUserLoginInfo() != null) {
            controller.showLocalLoginMethod();
        }

        stage.showAndWait();

        if (controller.getResult() instanceof SimpleUserLoginController.LoggedInResult) {
            final SimpleUserLoginController.LoggedInResult result =
                    (SimpleUserLoginController.LoggedInResult) controller.getResult();
            return new UserLoginDirector.UserLoginResult(result.getUserLoginInfo(), result.getLoggedInUser());
        } else
            return null;
    }
}
