
const Rx = require('rx');
const Promise = require('bluebird');
const UserService = require('../services/UserService');

module.exports = function(Client) {
  // disable default remote methods
  Client.disableRemoteMethodByName('prototype.__count__accessTokens');
  Client.disableRemoteMethodByName('prototype.__get__accessTokens');
  Client.disableRemoteMethodByName('prototype.__create__accessTokens');
  Client.disableRemoteMethodByName('prototype.__delete__accessTokens');
  Client.disableRemoteMethodByName('prototype.__destroyById__accessTokens');
  Client.disableRemoteMethodByName('prototype.__findById__accessTokens');
  Client.disableRemoteMethodByName('prototype.__updateById__accessTokens');

  Client.disableRemoteMethodByName('prototype.__delete__addresses');

  Client.new = function(data, cb) {
    const userService = UserService(Client);

    Promise.coroutine(function *() {
      // prepare data
      const input = userService.prepare(data, 'client');

      // persist obj in the db
      const user = yield userService.persist(input);

      // login
      const tokenInfo = yield userService.login(
        data.email,
        data.password,
        'client'
      );

      // send email verification
      userService.verify(user);

      const ttl = tokenInfo.ttl;
      const token = tokenInfo.id;
      const {id, realm, firstName, lastName, email} = user;

      cb(null, id, realm, firstName, lastName, email, token, ttl);
    })().catch(err => cb(err, null));
  };

  Client.remoteMethod('new',
    {
      description: 'Create a new instance of the model and persist ' +
        'it into the data source.',
      status: 201,
      errorStatus: 400,
      notes: `Sample request : <br/>
      {
        "first_name": "foo",
        "last_name": "bar",
        "email": "foo.bar@baz.com",
        "password": "Pa$$w0rd!!!"
      }`,
      accepts: [
        {
          arg: 'data',
          type: 'any',
          required: true,
          description: 'Should be application/json.',
          http: {source: 'body'},
        },
      ],
      // only this fields will be returned
      returns: [
        {arg: 'id', type: 'string'},
        {arg: 'realm', type: 'string'},
        {arg: 'first_name', type: 'string'},
        {arg: 'last_name', type: 'string'},
        {arg: 'email', type: 'string'},
        {arg: 'token', type: 'string'},
        {arg: 'ttl', type: 'number'},
      ],
      http: {
        path: '/create',
        verb: 'post',
        status: 201,
        errorStatus: 400,
      },
    }
  );

  Client.beforeRemote('new', function(ctx, unused, next) {
    next();
  });

  Client.afterRemote('new', function(ctx, remoteMethodOutput, next) {
    remoteMethodOutput.createdAt = new Date();
    remoteMethodOutput.updatedAt = new Date();
    next();
  });

  Client.afterRemoteError('new', function(ctx, next) {
    if (!ctx.error.details) ctx.error.details = {};
    ctx.error.details.info = 'intercepted by a hook';
    // next(new Error('Overwritten error.'));
    next();
  });

  Client.observe('before save', function(ctx, next) {
    if (ctx.isNewInstance) {
      // do something
    }
    next();
  });
};
