text: import Controller from '@ember/controller';
  import RSVP from 'rsvp';
  import {
      VersionMismatchError,
      isVersionMismatchError
  } from 'ghost-admin/services/ajax';
  import {alias} from '@ember/object/computed';
  import {isArray as isEmberArray} from '@ember/array';
  import {inject as service} from '@ember/service';
  import {task} from 'ember-concurrency';
  
  export default Controller.extend({
      ajax: service(),
      config: service(),
      ghostPaths: service(),
      notifications: service(),
      session: service(),
      settings: service(),
  
      flowErrors: '',
      profileImage: null,
  
      signupDetails: alias('model'),
  
      actions: {
          validate(property) {
              return this.signupDetails.validate({property});
          },
  
          setImage(image) {
              this.set('profileImage', image);
          }
      },
  
      authenticate: task(function* (authStrategy, authentication) {
          try {
              let authResult = yield this.get('session')
                  .authenticate(authStrategy, ...authentication);
              let promises = [];
  
              promises.pushObject(this.get('settings').fetch());
              promises.pushObject(this.get('config').fetchPrivate());
  
              // fetch settings and private config for synchronous access
              yield RSVP.all(promises);
  
              return authResult;
          } catch (error) {
              if (error && error.payload && error.payload.errors) {
                  // we don't get back an ember-data/ember-ajax error object
                  // back so we need to pass in a null status in order to
                  // test against the payload
                  if (isVersionMismatchError(null, error)) {
                      let versionMismatchError = new VersionMismatchError(error);
                      return this.get('notifications').showAPIError(versionMismatchError);
                  }
  
                  error.payload.errors.forEach((err) => {
                      err.message = err.message.htmlSafe();
                  });
  
                  this.set('flowErrors', error.payload.errors[0].message.string);
  
                  if (error.payload.errors[0].message.string.match(/user with that email/)) {
                      this.get('signupDetails.errors').add('email', '');
                  }
  
                  if (error.payload.errors[0].message.string.match(/password is incorrect/)) {
                      this.get('signupDetails.errors').add('password', '');
                  }
              } else {
                  // Connection errors don't return proper status message, only req.body
                  this.get('notifications').showAlert('There was a problem on the server.', {type: 'error', key: 'session.authenticate.failed'});
                  throw error;
              }
          }
      }).drop(),
  
      signup: task(function* () {
          let setupProperties = ['name', 'email', 'password', 'token'];
          let notifications = this.get('notifications');
  
          this.set('flowErrors', '');
          this.get('signupDetails.hasValidated').addObjects(setupProperties);
  
          try {
              yield this.signupDetails.validate();
              yield this._completeInvitation();
  
              try {
                  yield this._authenticateWithPassword();
                  yield this.get('_sendImage').perform();
              } catch (error) {
                  notifications.showAPIError(error, {key: 'signup.complete'});
              }
          } catch (error) {
              // ValidationEngine throws undefined
              if (!error) {
                  this.set('flowErrors', 'Please fill out the form to complete your sign-up');
                  return false;
              }
  
              if (error && error.payload && error.payload.errors && isEmberArray(error.payload.errors)) {
                  if (isVersionMismatchError(error)) {
                      notifications.showAPIError(error);
                  }
                  this.set('flowErrors', error.payload.errors[0].message);
              } else {
                  notifications.showAPIError(error, {key: 'signup.complete'});
              }
          }
      }).drop(),
  
      _completeInvitation() {
          let authUrl = this.get('ghostPaths.url').api('authentication', 'invitation');
          let signupDetails = this.get('signupDetails');
  
          return this.get('ajax').post(authUrl, {
              dataType: 'json',
              data: {
                  invitation: [{
                      name: signupDetails.get('name'),
                      email: signupDetails.get('email'),
                      password: signupDetails.get('password'),
                      token: signupDetails.get('token')
                  }]
              }
          });
      },
  
      _authenticateWithPassword() {
          let email = this.get('signupDetails.email');
          let password = this.get('signupDetails.password');
  
          return this.get('session')
              .authenticate('authenticator:oauth2', email, password);
      },
  
      _sendImage: task(function* () {
          let formData = new FormData();
          let imageFile = this.get('profileImage');
          let uploadUrl = this.get('ghostPaths.url').api('uploads');
  
          if (imageFile) {
              formData.append('uploadimage', imageFile, imageFile.name);
  
              let user = yield this.get('session.user');
              let response = yield this.get('ajax').post(uploadUrl, {
                  data: formData,
                  processData: false,
                  contentType: false,
                  dataType: 'text'
              });
  
              let imageUrl = JSON.parse(response);
              let usersUrl = this.get('ghostPaths.url').api('users', user.id.toString());
  
              user.profile_image = imageUrl;
  
              return yield this.get('ajax').put(usersUrl, {
                  data: {
                      users: [user]
                  }
              });
          }
      })
  });
  