import { auth } from '@services/AuthService';
import {
  ActionContext,
  ActionMethod,
  ActionTree,
  GetterTree,
  mapActions,
  mapGetters,
  mapState,
  MutationTree,
} from 'vuex';

interface State {
  currentUser: null | Record<any, any>;
  accessTokenExpired: boolean;
  isLoggedIn: boolean;
}

export const state = {
  currentUser: null,
  accessTokenExpired: false,
  isLoggedIn: false,
};

export const getters: GetterTree<State, State> = {
  currentUser(state) {
    return state.currentUser;
  },
  accessTokenExpired(state) {
    return state.accessTokenExpired;
  },
  isLoggedIn(state) {
    return state.isLoggedIn;
  },
};

export const mutations: MutationTree<State> = {
  currentUser(state, currentUser) {
    state.currentUser = currentUser;
  },
  accessTokenExpired(state, accessTokenExpired) {
    state.accessTokenExpired = accessTokenExpired;
  },

  isLoggedIn(state, isLoggedIn) {
    state.isLoggedIn = isLoggedIn;
  },
};

export const actions: ActionTree<State, State> = {
  getAccessToken() {
    return auth.getAccessToken();
  },
  loginOidcClient() {
    return auth.login();
  },
  logoutOidcClient() {
    return auth.logout();
  },

  initOidcClient({ commit }: ActionContext<State, State>): Promise<State> {
    return new Promise((resolve, reject) => {
      auth
        .getUser()
        .then((user) => {
          if (user) {
            commit('currentUser', user.profile);
            commit('accessTokenExpired', user.expired);
            commit('isLoggedIn', !user.expired);

            return resolve();
          } else {
            return reject();
          }
        })
        .catch((e) => {
          return reject(e);
        });
    });
  },
};

export const oidcClientComputed = {
  ...mapState('oidcClient', {
    currentUser: (state: any) => state.currentUser,

    accessTokenExpired: (state: any) => state.accessTokenExpired,

    isLoggedIn: (state: any) => state.isLoggedIn,
  }),
  ...mapGetters('oidcClient', [
    'currentUser',
    'accessTokenExpired',
    'isLoggedIn',
  ]),
};

export const oidcClientMethods: {
  getAccessToken: ActionMethod;
  loginOidcClient: ActionMethod;
  logoutOidcClient: ActionMethod;
  initOidcClient: ActionMethod;
} = mapActions('oidcClient', [
  'getAccessToken',
  'loginOidcClient',
  'logoutOidcClient',
  'initOidcClient',
]);
