package com.kickstarter.viewmodels;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Pair;

import com.kickstarter.libs.CurrentUserType;
import com.kickstarter.libs.Environment;
import com.kickstarter.libs.ViewModel;
import com.kickstarter.libs.rx.transformers.Transformers;
import com.kickstarter.libs.utils.I18nUtils;
import com.kickstarter.libs.utils.ListUtils;
import com.kickstarter.models.Location;
import com.kickstarter.models.User;
import com.kickstarter.services.ApiClientType;
import com.kickstarter.ui.activities.SettingsActivity;
import com.kickstarter.viewmodels.errors.SettingsViewModelErrors;
import com.kickstarter.viewmodels.inputs.SettingsViewModelInputs;
import com.kickstarter.viewmodels.outputs.SettingsViewModelOutputs;

import rx.Observable;
import rx.subjects.BehaviorSubject;
import rx.subjects.PublishSubject;

public class SettingsViewModel extends ViewModel<SettingsActivity> implements SettingsViewModelInputs,
  SettingsViewModelErrors, SettingsViewModelOutputs {

  // INPUTS
  private final PublishSubject<Void> contactEmailClicked = PublishSubject.create();
  private final PublishSubject<Pair<Boolean, String>> newsletterInput = PublishSubject.create();
  private final PublishSubject<User> userInput = PublishSubject.create();
  public void logoutClicked() {
    showConfirmLogoutPrompt.onNext(true);
  }
  public void closeLogoutConfirmationClicked() {
    showConfirmLogoutPrompt.onNext(false);
  }
  private final PublishSubject<Void> confirmLogoutClicked = PublishSubject.create();
  @Override
  public void confirmLogoutClicked() {
    confirmLogoutClicked.onNext(null);
  }

  // OUTPUTS
  private final PublishSubject<String> sendNewsletterConfirmation = PublishSubject.create();
  public Observable<String> sendNewsletterConfirmation() {
    return sendNewsletterConfirmation;
  }
  private final PublishSubject<Void> updateSuccess = PublishSubject.create();
  public final Observable<Void> updateSuccess() {
    return updateSuccess;
  }
  private final BehaviorSubject<User> userOutput = BehaviorSubject.create();
  public Observable<User> user() {
    return userOutput;
  }
  private final BehaviorSubject<Boolean> showConfirmLogoutPrompt = BehaviorSubject.create();
  public Observable<Boolean> showConfirmLogoutPrompt() {
    return showConfirmLogoutPrompt;
  }
  private final BehaviorSubject<Void> logout = BehaviorSubject.create();
  @Override
  public Observable<Void> logout() {
    return logout;
  }
  // ERRORS
  private final PublishSubject<Throwable> unableToSavePreferenceError = PublishSubject.create();
  public final Observable<String> unableToSavePreferenceError() {
    return unableToSavePreferenceError
      .takeUntil(updateSuccess)
      .map(__ -> null);
  }

  public final SettingsViewModelInputs inputs = this;
  public final SettingsViewModelOutputs outputs = this;
  public final SettingsViewModelErrors errors = this;

  private final ApiClientType client;
  private final CurrentUserType currentUser;

  @Override
  public void contactEmailClicked() {
    this.contactEmailClicked.onNext(null);
  }

  @Override
  public void notifyMobileOfFollower(final boolean b) {
    userInput.onNext(userOutput.getValue().toBuilder().notifyMobileOfFollower(b).build());
  }

  @Override
  public void notifyMobileOfFriendActivity(final boolean b) {
    userInput.onNext(userOutput.getValue().toBuilder().notifyMobileOfFriendActivity(b).build());
  }

  @Override
  public void notifyMobileOfUpdates(final boolean b) {
    userInput.onNext(userOutput.getValue().toBuilder().notifyMobileOfUpdates(b).build());
  }

  @Override
  public void notifyOfFollower(final boolean b) {
    userInput.onNext(userOutput.getValue().toBuilder().notifyOfFollower(b).build());
  }

  @Override
  public void notifyOfFriendActivity(final boolean b) {
    userInput.onNext(userOutput.getValue().toBuilder().notifyOfFriendActivity(b).build());
  }

  @Override
  public void notifyOfUpdates(final boolean b) {
    userInput.onNext(userOutput.getValue().toBuilder().notifyOfUpdates(b).build());
  }

  @Override
  public void sendHappeningNewsletter(final boolean checked, final @NonNull String name) {
    userInput.onNext(userOutput.getValue().toBuilder().happeningNewsletter(checked).build());
    newsletterInput.onNext(new Pair<>(checked, name));
  }

  @Override
  public void sendPromoNewsletter(final boolean checked, final @NonNull String name) {
    userInput.onNext(userOutput.getValue().toBuilder().promoNewsletter(checked).build());
    newsletterInput.onNext(new Pair<>(checked, name));
  }

  @Override
  public void sendWeeklyNewsletter(final boolean checked, final @NonNull String name) {
    userInput.onNext(userOutput.getValue().toBuilder().weeklyNewsletter(checked).build());
    newsletterInput.onNext(new Pair<>(checked, name));
  }

  public SettingsViewModel(final @NonNull Environment environment) {
    super(environment);

    client = environment.apiClient();
    currentUser = environment.currentUser();

    client.fetchCurrentUser()
      .retry(2)
      .compose(Transformers.neverError())
      .compose(bindToLifecycle())
      .subscribe(currentUser::refresh);

    currentUser.observable()
      .take(1)
      .compose(bindToLifecycle())
      .subscribe(userOutput::onNext);

    userInput
      .concatMap(this::updateSettings)
      .compose(bindToLifecycle())
      .subscribe(this::success);

    userInput
      .compose(bindToLifecycle())
      .subscribe(userOutput);

    userOutput
      .window(2, 1)
      .flatMap(Observable::toList)
      .map(ListUtils::first)
      .compose(Transformers.takeWhen(unableToSavePreferenceError))
      .compose(bindToLifecycle())
      .subscribe(userOutput);

    currentUser.observable()
      .compose(Transformers.takePairWhen(newsletterInput))
      .filter(us -> requiresDoubleOptIn(us.first, us.second.first))
      .map(us -> us.second.second)
      .compose(bindToLifecycle())
      .subscribe(sendNewsletterConfirmation);


    contactEmailClicked
      .compose(bindToLifecycle())
      .subscribe(__ -> koala.trackContactEmailClicked());

    newsletterInput
      .map(bs -> bs.first)
      .compose(bindToLifecycle())
      .subscribe(koala::trackNewsletterToggle);

    confirmLogoutClicked
      .compose(bindToLifecycle())
      .subscribe(__ -> {
        koala.trackLogout();
        logout.onNext(null);
      });

    koala.trackSettingsView();
  }

  private boolean requiresDoubleOptIn(final @NonNull User user, final boolean checked) {
    final Location location = user.location();
    return location != null && I18nUtils.isCountryGermany(location.country()) && checked;
  }

  private void success(final @NonNull User user) {
    currentUser.refresh(user);
    this.updateSuccess.onNext(null);
  }

  private Observable<User> updateSettings(final @NonNull User user) {
    return client.updateUserSettings(user)
      .compose(Transformers.pipeErrorsTo(unableToSavePreferenceError));
  }
}

@@ -49,136 +49,34 @@
 oid.
-content.Context;%0Aimport android.os.Bundle;%0Aimport android.support.annotation.NonNull;%0Aimport android.support.annotation.Nullable
+support.annotation.NonNull
 ;%0Aim
@@ -5973,17 +5973,16 @@
 tion);%0A%0A
-%0A
     cont

Remove unused imports