
import { AppConstants } from '../../constants/AppConstants.js';
import SessionWorkerManager from '../../SessionWorkerManager.js';
import AppActions, { EnumAppActions } from '../../app/AppActions.js';
import BaseActions from '../../app/BaseActions.js';
import DOMAINS from '../../constants/Domini.js';
import OPZIONI from '../../constants/Opzioni.js';
import Rest from '../../webapi/Rest.js';
import { NotificationManager } from 'arm-core-layouts';
import { i18n } from 'arm-common';
import KeepAliveWorkerManager from '../../KeepAliveWorkerManager.js';


export const EnumAccountActions = Object.freeze({
    LOGIN_SUCCESS: 'EnumAccountActions.LOGIN_SUCCESS',
    LOGIN_FAILED: 'EnumAccountActions.LOGIN_FAILED',
    LOGOUT: 'EnumAccountActions.LOGOUT',
    SSO: 'EnumAccountActions.SSO',
    UPDATE_FORM: 'EnumAccountActions.UPDATE_FORM',
    ALIVE_STATUS: 'EnumAccountActions.ALIVE_STATUS',
    SESSION_EXPIRED: 'account_actions.SESSION_EXPIRED',
});

const BASE_PATH = 'authentication';

class AccountActions extends BaseActions {
    getReducer(state) {
        if (typeof state === 'function') state = state();
        return state.account;
    }

    createPath(path) {
        return `${BASE_PATH}/${path}`;
    }

    login() {
        return async (dispatch, getState) => {
            const { userid, password } = this.getReducer(getState);

            try {
                const utente = await Rest.postForm(this.createPath('login'), { userid, password, clientVersion: AppConstants.VERSION }, dispatch);
                
                await dispatch(this.postLogin(utente));

                const username = utente.name || utente.lastName || ' ';
                
                NotificationManager.success(i18n("APP.ACCOUNT.WELCOME", "Benvenuto #username#!", "username", username));

                return utente;
            } catch (error) {
                console.warn("[AccountActions.js]: Authentication failed", error);
                
                dispatch({ type: EnumAccountActions.LOGIN_FAILED });
            }

            return Promise.reject();
        }
    }

    postLogin(resolve) {
        return async (dispatch) => {
            console.log("[AccountActions.js]: Authentication success");

            dispatch({ type: EnumAccountActions.LOGIN_SUCCESS, user: resolve });

            console.log("[AccountActions.js]: user language", resolve.codLang);

            KeepAliveWorkerManager.init(
                (aliveStatus) => dispatch(this.setAliveStatus(aliveStatus)),
                AppConstants.KEEP_ALIVE_MINUTES
            );

            await dispatch(this.loadUtilities());

            return resolve;
        }
    }

    setAliveStatus(aliveStatus) {
        return {
            type: EnumAccountActions.ALIVE_STATUS,
            aliveStatus: aliveStatus
        }
    }

    logout() {
        return dispatch => Rest.post("authentication/logout", null, dispatch).then(
            resolve => {
                dispatch({ type: EnumAccountActions.LOGOUT });
                return resolve;
            },
            reject => reject
        );
    }

    loadUtilities(utilities) {
        console.log("[AccountActions.js]: get OPTIONS, DOMAINS and AP_LANG");

        if (!utilities) {
            // Utilities di default.
            utilities = {
                codiciOpzioni: OPZIONI,
                codiciDomini: DOMAINS,
                codiciApLang: AppConstants.I18N_CODES
            };
        }

        return (dispatch) => {
            return Rest.post("utilities/load", utilities, dispatch, null).then(
                resolve => {
                    dispatch({
                        type: EnumAppActions.LOAD_OPZIONI,
                        opzioni: resolve.opzioni || [],
                    });
                    dispatch({
                        type: EnumAppActions.LOAD_DOMINI,
                        domini: resolve.domini || []
                    });
                    dispatch({
                        type: EnumAppActions.LOAD_I18N,
                        i18nlabels: resolve.apLang
                    });
                    return resolve;
                }
            )
        }
    }

    updateForm(value, key) {
        return {
            type: EnumAccountActions.UPDATE_FORM,
            value, key
        }
    }

    logoutExpiredSession() {
        return { type: EnumAccountActions.SESSION_EXPIRED }
    }
}

export default AccountActions = new AccountActions;