const get = require('lodash/get');
const joinUrl = require('url-join');
const {
  createInvitationRequest,
  handleInvitationResponse,
  messages,
  checkWalletVersion,
  beforeInvitationRequest,
} = require('@abtnode/auth/lib/auth');
const logger = require('@abtnode/logger')(require('../../package.json').name);

module.exports = function createRoutes(node, authenticator, login, opts) {
  return {
    action: 'invite',

    onStart: async ({ extraParams, req }) => {
      const { locale = 'en', inviteId } = extraParams;
      const teamDid = req.headers['x-blocklet-did'];

      await beforeInvitationRequest({ node, teamDid, locale, inviteId });
    },

    claims: {
      profile: async ({ extraParams, context }) => {
        const { locale } = extraParams;

        const config = await context.request.getServiceConfig();
        const profileFields = get(config, 'profileFields');

        return {
          fields: profileFields || ['fullName', 'avatar'],
          description: messages.description[locale],
        };
      },

      signature: async ({ extraParams, context: { request, abtwallet } }) => {
        const { locale, inviteId } = extraParams;
        checkWalletVersion({ abtwallet, locale });
        const nodeInfo = await request.getNodeInfo();
        const teamDid = request.headers['x-blocklet-did'];

        return createInvitationRequest({
          node,
          nodeInfo,
          teamDid,
          inviteId,
          locale,
        });
      },
    },

    onAuth: async ({ claims, userDid, userPk, token, storage, extraParams, req, baseUrl }) => {
      const { locale, inviteId } = extraParams;
      const nodeInfo = await req.getNodeInfo();
      const teamDid = req.headers['x-blocklet-did'];
      const statusEndpointBaseUrl = joinUrl(baseUrl, opts.prefix);
      const endpoint = baseUrl;

      const { passport, response, role } = await handleInvitationResponse({
        node,
        nodeInfo,
        teamDid,
        userDid,
        userPk,
        inviteId,
        locale,
        claims,
        statusEndpointBaseUrl,
        endpoint,
      });

      // Generate new session token that client can save to localStorage
      const loginToken = await login(userDid, { passport, role });
      await storage.update(token, { did: userDid, loginToken });
      logger.info('login.success', { userDid });

      return response;
    },
  };
};
