import Component from 'ember-component';
import { bool } from 'ember-computed';
import layout from '../../templates/components/nypr-accounts/basic-card';
import RSVP from 'rsvp';
import Changeset from 'ember-changeset';
import lookupValidator from 'ember-changeset-validations';
import makeValidations from 'nypr-account-settings/validators/nypr-accounts/basic-card';
import getOwner from 'ember-owner/get';

export default Component.extend({
  layout,
  tagName: '',
  isShowingModal: bool('resolveModal'),
  user: {},
  
  init() {
    this._super(...arguments);
    let config = getOwner(this).resolveRegistration('config:environment');
    let validations = makeValidations({usernamePath: config.wnycAuthAPI});
    
    let user = this.get('user');
    let changeset = new Changeset(user, lookupValidator(validations), validations);
    this.changeset = changeset;
  },

  emailRequirement() {
    return new RSVP.Promise((resolve, reject) => {
      // resolved by verifyPassword
      // setting resolveModal shows the modal
      this.setProperties({
        resolveModal: resolve,
        rejectModal: reject
      });
    });
  },
  
  rollbackEmailField(changeset) {
    // work around to rollback specific fields
    let snapshot = changeset.snapshot();
    changeset.rollback();
    delete snapshot.changes.email;
    delete snapshot.changes.confirmEmail;
    changeset.restore(snapshot);
  },
  
  commit(changeset) {
    let notifyEmail = changeset.get('change.email');
    return changeset.save().then(() => {
      this.set('isEditing', false);
      if (notifyEmail && this.attrs.emailUpdated) {
        this.attrs.emailUpdated();
      }
    });
  },

  actions: {
    save(changeset) {
      let stepOne;
      let verifyEmail = changeset.get('change.email');

      if (verifyEmail) {
        // defer validating preferredUsername b/c it incurs a UI delay due to 
        // waiting on a network call
        stepOne = RSVP.all([
          changeset.validate('givenName'),
          changeset.validate('familyName'),
          changeset.validate('email'),
          changeset.validate('confirmEmail'),
        ]);
      } else {
        // if email hasn't changed, no point verifying it
        stepOne = RSVP.all([
          changeset.validate('givenName'),
          changeset.validate('familyName'),
          changeset.validate('preferredUsername'),
        ]);
      }

      return stepOne.then(() => {
        if (verifyEmail && changeset.get('isValid')) {
          return this.emailRequirement()
            .then(() => {
              // now that the modal has passed, validate the username
              return changeset.validate('preferredUsername')
                .then(() => {
                  if (changeset.get('isValid')) {
                    return this.commit(changeset);
                  } else {
                    // something's wrong, probably the preferredUsername
                    this.closeModal();
                  }
                });
            })
            .catch(() => this.rollbackEmailField(changeset));
        } else if (changeset.get('isValid')) {
          // if we're not doing the verify email, flow, just commit the changeset
          return this.commit(changeset);
        }
      });
    },
    
    rollback(changeset) {
      changeset.rollback();
      this.set('isEditing', false);
    },

    verifyPassword() {
      let password = this.get('password');
      this.attrs.authenticate(password)
        .then(this.get('resolveModal'))
        .catch(this.get('rejectModal'))
        .finally(() => {
          this.setProperties({
            resolveModal: null,
            rejectModal: null,
            password: null
          });
        });
    },
    closeModal() {
      this.get('rejectModal')();
      this.setProperties({
        resolveModal: null,
        rejectModal: null,
        password: null
      });
    }
  }
});

@@ -400,16 +400,86 @@
 er/get';
+%0Aimport get from 'ember-metal/get';%0Aimport set from 'ember-metal/set';
 %0A%0Aexport
@@ -798,25 +798,26 @@
  user = 
-this.get(
+get(this, 
 'user');
@@ -1509,32 +1509,36 @@
 t notifyEmail = 
+get(
 changeset.get('c
@@ -1522,37 +1522,34 @@
  = get(changeset
-.get(
+, 
 'change.email');
@@ -1592,33 +1592,34 @@
  =%3E %7B%0A      
-this.set(
+set(this, 
 'isEditing',
@@ -1718,24 +1718,187 @@
 ();%0A      %7D%0A
+    %7D)%0A    .catch((%7B errors %7D) =%3E %7B%0A      if (errors.values === 'preferred_username') %7B%0A        changeset.pushErrors('preferredUsername', errors.message);%0A      %7D%0A
     %7D);%0A  %7D,
@@ -1977,16 +1977,20 @@
 Email = 
+get(
 changese
@@ -1990,21 +1990,18 @@
 hangeset
-.get(
+, 
 'change.
@@ -2686,16 +2686,20 @@
 mail && 
+get(
 changese
@@ -2691,37 +2691,34 @@
 && get(changeset
-.get(
+, 
 'isValid')) %7B%0A  
@@ -2960,24 +2960,28 @@
          if 
+(get
 (changeset.g
@@ -2970,37 +2970,34 @@
 f (get(changeset
-.get(
+, 
 'isValid')) %7B%0A  
@@ -3319,16 +3319,20 @@
 else if 
+(get
 (changes
@@ -3333,21 +3333,18 @@
 hangeset
-.get(
+, 
 'isValid
@@ -3397,17 +3397,16 @@
 fy email
-,
  flow, j
@@ -3567,17 +3567,18 @@
     
-this.set(
+set(this, 
 'isE
@@ -3646,25 +3646,26 @@
 sword = 
-this.get(
+get(this, 
 'passwor
@@ -3723,25 +3723,26 @@
   .then(
-this.get(
+get(this, 
 'resolve
@@ -3765,25 +3765,26 @@
  .catch(
-this.get(
+get(this, 
 'rejectM
@@ -3999,17 +3999,18 @@
     
-this.get(
+get(this, 
 'rej

use generic getter and setters