package com.kickstarter.ui.intents;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.kickstarter.libs.utils.ObjectUtils;
import com.kickstarter.services.ApiClientType;
import com.kickstarter.services.DiscoveryParams;
import com.kickstarter.ui.IntentKey;
import com.trello.rxlifecycle.ActivityEvent;
import com.trello.rxlifecycle.RxLifecycle;

import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.functions.Action1;

public final class DiscoveryIntentAction extends IntentAction {
  private final ApiClientType client;

  public DiscoveryIntentAction(final @NonNull Action1<DiscoveryParams> initializer,
    final @NonNull Observable<ActivityEvent> lifecycle, final @NonNull ApiClientType client) {
    this.client = client;

    intent
      .compose(RxLifecycle.bindActivity(lifecycle))
      .map(this::uri)
      .filter(ObjectUtils::isNotNull)
      .map(DiscoveryParams::fromUri)
      .flatMap(this::fromUri)
      .subscribe(initializer);

    intent
      .compose(RxLifecycle.bindActivity(lifecycle))
      .map(this::params)
      .filter(ObjectUtils::isNotNull)
      .subscribe(initializer);
  }

  private @Nullable DiscoveryParams params(final @NonNull Intent intent) {
    return intent.getParcelableExtra(IntentKey.DISCOVERY_PARAMS);
  }

  private @NonNull Observable<DiscoveryParams> fromUri(final @NonNull DiscoveryParams params) {
    return Observable.zip(paramBuilders(params), builders -> {
      DiscoveryParams.Builder builder = DiscoveryParams.builder();

      for (final Object object : builders) {
        final DiscoveryParams.Builder b = (DiscoveryParams.Builder) object;
        builder = builder.mergeWith(b);
      }

      return builder.build();
    });
  }

  private @NonNull List<Observable<DiscoveryParams.Builder>> paramBuilders(final @NonNull DiscoveryParams params) {
    final List<Observable<DiscoveryParams.Builder>> paramBuilders = new ArrayList<>();

    paramBuilders.add(Observable.just(params.toBuilder()));

    final String categoryParam = params.categoryParam();
    if (categoryParam != null) {
      paramBuilders.add(
        client
          .fetchCategory(categoryParam)
          .map(c -> DiscoveryParams.builder().category(c))
      );
    }

    final String locationParam = params.locationParam();
    if (locationParam != null) {
      paramBuilders.add(
        client
          .fetchLocation(locationParam)
          .map(l -> DiscoveryParams.builder().location(l))
      );
    }

    return paramBuilders;
  }
}

@@ -196,16 +196,96 @@
 tUtils;%0A
+import com.kickstarter.models.Category;%0Aimport com.kickstarter.models.Location;%0A
 import c
@@ -1216,16 +1216,24 @@
 his::par
+celedPar
 ams)%0A   
@@ -1342,16 +1342,24 @@
 rams par
+celedPar
 ams(fina
@@ -1449,32 +1449,176 @@
 Y_PARAMS);%0A  %7D%0A%0A
+  /**%0A   * Returns params where category and location params have been converted into %7B@link Category%7D%0A   * and %7B@link Location%7D objects.%0A   */%0A
   private @NonNu

Add javadoc