package com.castlabs.reactnative.network;

import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.castlabs.reactnative.utils.BridgeDeserializer;
import com.castlabs.reactnative.utils.DrmUtils;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import java.util.Map;

/**
 * Gives access to network modifiers.
 */
@RequiresApi(api = Build.VERSION_CODES.N)
public class NetworkModule extends ReactContextBaseJavaModule {
  public static final String REACT_CLASS = "NetworkModule";

  private final @NonNull Map<String, RequestCompleter> requestCompleterCache;
  private final @NonNull Map<String, ResponseCompleter> responseCompleterCache;

  /**
   * Initializes the player module.
   *
   * @param context the application context
   * @param requestCompleterCache the global request completer cache
   * @param responseCompleterCache the global response completer cache
   */
  public NetworkModule(
      @NonNull final ReactApplicationContext context,
      @NonNull final Map<String, RequestCompleter> requestCompleterCache,
      @NonNull final Map<String, ResponseCompleter> responseCompleterCache
  ) {
    super(context);
    this.requestCompleterCache = requestCompleterCache;
    this.responseCompleterCache = responseCompleterCache;
  }

  @Override
  @NonNull
  public String getName() {
    return REACT_CLASS;
  }

  /**
   * Completes the given request.
   *
   * @param requestId the request ID
   */
  @ReactMethod
  public void completeRequest(
      final @NonNull String requestId,
      final @Nullable String url,
      final @Nullable ReadableMap headers,
      final @Nullable String body
  ) {
    RequestCompleter requestCompleter = this.requestCompleterCache.remove(requestId);
    if (requestCompleter != null) {
      if (url == null || url.equals(DrmUtils.urlPlaceholder)) {
        Log.e (REACT_CLASS, "completeRequest: url MUST be replaced in request modifier.");
      } else {
        requestCompleter.setUrl(BridgeDeserializer.toUrl(url));
      }
      if (headers != null) {
        requestCompleter.setHeaders(BridgeDeserializer.toRequestHeaders(headers));
      }
      if (body != null) {
        requestCompleter.setBody(BridgeDeserializer.toBytes(body));
      }
      requestCompleter.complete();
    }
  }

  /**
   * Completes the given response.
   *
   * @param responseId the response ID
   */
  @ReactMethod
  public void completeResponse(
      @NonNull final String responseId,
      @Nullable final ReadableMap headers,
      @Nullable final String body
  ) {
    ResponseCompleter responseCompleter = this.responseCompleterCache.remove(responseId);
    if (responseCompleter != null) {
      if (headers != null) {
        responseCompleter.setHeaders(
            BridgeDeserializer.toResponseHeaders(headers)
        );
      }
      if (body != null) {
        responseCompleter.setBody(
            BridgeDeserializer.toBytes(body)
        );
      }
      responseCompleter.complete();
    }
  }

  @ReactMethod
  public void addListener(String eventName) {
    // https://stackoverflow.com/a/69650217
  }

  @ReactMethod
  public void removeListeners(Integer count) {
    // https://stackoverflow.com/a/69650217
  }
}
