package app.jigrajs.plugins.localnotifications;

import android.content.Context;
import android.content.SharedPreferences;
import com.getjigra.JSObject;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.JSONException;

/**
 * Class used to abstract storage for notification data
 */
public class NotificationStorage {

  // Key for private preferences
  private static final String NOTIFICATION_STORE_ID = "NOTIFICATION_STORE";

  // Key used to save action types
  private static final String ACTION_TYPES_ID = "ACTION_TYPE_STORE";

  private static final String ID_KEY = "notificationIds";

  private Context context;

  public NotificationStorage(Context context) {
    this.context = context;
  }

  /**
   * Persist the id of currently scheduled notification
   */
  public void appendNotifications(List<LocalNotification> localNotifications) {
    SharedPreferences storage = getStorage(NOTIFICATION_STORE_ID);
    SharedPreferences.Editor editor = storage.edit();
    for (LocalNotification request : localNotifications) {
      if (request.isScheduled()) {
        String key = request.getId().toString();
        editor.putString(key, request.getSource());
      }
    }
    editor.apply();
  }

  public List<String> getSavedNotificationIds() {
    SharedPreferences storage = getStorage(NOTIFICATION_STORE_ID);
    Map<String, ?> all = storage.getAll();
    if (all != null) {
      return new ArrayList<>(all.keySet());
    }
    return new ArrayList<>();
  }

  public List<LocalNotification> getSavedNotifications() {
    SharedPreferences storage = getStorage(NOTIFICATION_STORE_ID);
    Map<String, ?> all = storage.getAll();
    if (all != null) {
      ArrayList<LocalNotification> notifications = new ArrayList<>();
      for (String key : all.keySet()) {
        String notificationString = (String) all.get(key);
        JSObject jsNotification = getNotificationFromJSONString(
          notificationString
        );
        if (jsNotification != null) {
          try {
            LocalNotification notification = LocalNotification.buildNotificationFromJSObject(
              jsNotification
            );
            notifications.add(notification);
          } catch (ParseException ex) {}
        }
      }

      return notifications;
    }

    return new ArrayList<>();
  }

  public JSObject getNotificationFromJSONString(String notificationString) {
    if (notificationString == null) {
      return null;
    }

    JSObject jsNotification;
    try {
      jsNotification = new JSObject(notificationString);
    } catch (JSONException ex) {
      return null;
    }

    return jsNotification;
  }

  public JSObject getSavedNotificationAsJSObject(String key) {
    SharedPreferences storage = getStorage(NOTIFICATION_STORE_ID);
    String notificationString;
    try {
      notificationString = storage.getString(key, null);
    } catch (ClassCastException ex) {
      return null;
    }

    if (notificationString == null) {
      return null;
    }

    JSObject jsNotification;
    try {
      jsNotification = new JSObject(notificationString);
    } catch (JSONException ex) {
      return null;
    }

    return jsNotification;
  }

  public LocalNotification getSavedNotification(String key) {
    JSObject jsNotification = getSavedNotificationAsJSObject(key);
    if (jsNotification == null) {
      return null;
    }

    LocalNotification notification;
    try {
      notification =
        LocalNotification.buildNotificationFromJSObject(jsNotification);
    } catch (ParseException ex) {
      return null;
    }

    return notification;
  }

  /**
   * Remove the stored notifications
   */
  public void deleteNotification(String id) {
    SharedPreferences.Editor editor = getStorage(NOTIFICATION_STORE_ID).edit();
    editor.remove(id);
    editor.apply();
  }

  /**
   * Shared private preferences for the application.
   */
  private SharedPreferences getStorage(String key) {
    return context.getSharedPreferences(key, Context.MODE_PRIVATE);
  }

  /**
   * Writes new action types (actions that being displayed in notification) to storage.
   * Write will override previous data.
   *
   * @param typesMap - map with groupId and actionArray assigned to group
   */
  public void writeActionGroup(Map<String, NotificationAction[]> typesMap) {
    Set<String> typesIds = typesMap.keySet();
    for (String id : typesIds) {
      SharedPreferences.Editor editor = getStorage(ACTION_TYPES_ID + id).edit();
      editor.clear();
      NotificationAction[] notificationActions = typesMap.get(id);
      editor.putInt("count", notificationActions.length);
      for (int i = 0; i < notificationActions.length; i++) {
        editor.putString("id" + i, notificationActions[i].getId());
        editor.putString("title" + i, notificationActions[i].getTitle());
        editor.putBoolean("input" + i, notificationActions[i].isInput());
      }
      editor.apply();
    }
  }

  /**
   * Retrieve array of notification actions per ActionTypeId
   *
   * @param forId - id of the group
   */
  public NotificationAction[] getActionGroup(String forId) {
    SharedPreferences storage = getStorage(ACTION_TYPES_ID + forId);
    int count = storage.getInt("count", 0);
    NotificationAction[] actions = new NotificationAction[count];
    for (int i = 0; i < count; i++) {
      String id = storage.getString("id" + i, "");
      String title = storage.getString("title" + i, "");
      Boolean input = storage.getBoolean("input" + i, false);
      actions[i] = new NotificationAction(id, title, input);
    }
    return actions;
  }
}
