import { addResolveFunctionsToSchema } from 'graphql-tools';

import {
   authenticateUser,
   findUserByEMail,
   updateResetPwdTokenInUser,
} from './../../mongoDbApi/services/user/authenticationDbService';
import {
   createNewToken,
   createNewResetPasswordToken
} from './../../jwtApi/jwtService';

const types = `
type MenuItem {
   label: String!
   path: String!
}
type MenuGroup {
   label: String!
   menuItems: [MenuItem!]!
   subMenus: [MenuGroup!]
}
interface IAuthorized {
   id: ID!
   name: String!
   role: Role!
   navigation: [MenuGroup!]
}
type Viewer implements IUser, IAuthorized {
   id: ID!
   name: String!
   token: String!
   role: Role!
   navigation: [MenuGroup!]
}
input Credentials {
   email: String
   password: String
}
`;

const queries = `
getViewer: Viewer!
`;

const _queriesResolver = {
   Query: {
      getViewer(_, args, context) {
         let knownViewer = context.viewer;

         return createNewToken(knownViewer).then(token => {
            return {
               id: knownViewer.id,
               name: knownViewer.name,
               role: knownViewer.role,
               token,
            };
         });
      }
   }
};

const mutations = `
login(credentials: Credentials): Viewer!
sendResetPassword(email: String): Boolean!
resetPassword(password: String, token: String): Boolean!
`;

const _mutationsResolver = {
   Mutation: {
      login(_, { credentials }) {
         let knownUser = null;
         return authenticateUser(credentials).then(user => {
            knownUser = user;
            return createNewToken(knownUser);
         }).then(token => {
            return {
               id: knownUser.id,
               token
            };
         }).catch(error => {
            return Promise.reject(error);
         });
      },
      sendResetPassword(_, { email }) {
         return findUserByEMail(email).then(knownUser => {
            return createNewResetPasswordToken(knownUser).then(token => {
               return updateResetPwdTokenInUser(token, knownUser.id).then(user => {
                  return true;
               });
            });
         }).catch(error => {
            return Promise.reject(error);
         });
      },
      resetPassword(_, { password, token }) {
         return true;
      }
   }
};

/**
 * @public
 * @function addResolversTo
 * @description adds the resolvers to the executable schema
 * @param {any} executableSchema - the executable schema
 */
const addResolversTo = (executableSchema) => {
   addResolveFunctionsToSchema(executableSchema, _queriesResolver);
   addResolveFunctionsToSchema(executableSchema, _mutationsResolver);
};

export {
   types,
   queries,
   mutations,
   addResolversTo,
};
@@ -215,27 +215,8 @@
 t %7B%0A
-   createNewToken,%0A
    c
@@ -842,100 +842,74 @@
 gs, 
-context) %7B%0A         let knownViewer = context.viewer;%0A%0A         return createNewToken(knownV
+%7B viewer, tokenHandler %7D) %7B%0A         return tokenHandler.encrypt(v
 iewe
@@ -967,22 +967,17 @@
     id: 
-knownV
+v
 iewer.id
@@ -999,22 +999,17 @@
   name: 
-knownV
+v
 iewer.na
@@ -1037,14 +1037,9 @@
 le: 
-knownV
+v
 iewe
@@ -1351,16 +1351,34 @@
 entials 
+%7D, %7B tokenHandler 
 %7D) %7B%0A   
@@ -1519,22 +1519,28 @@
 urn 
-createNewToken
+tokenHandler.encrypt
 (kno
@@ -1670,79 +1670,8 @@
  %7D;%0A
-         %7D).catch(error =%3E %7B%0A            return Promise.reject(error);%0A
     
@@ -2015,79 +2015,8 @@
 %7D);%0A
-         %7D).catch(error =%3E %7B%0A            return Promise.reject(error);%0A
     

add correct handling of tokens via the token handler