package com.pilloxa.backgroundjob;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.util.Log;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import javax.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;

public class ReactNativeEventStarter {
  private static final String LOG_TAG = ReactNativeEventStarter.class.getSimpleName();
  private final ReactNativeHost reactNativeHost;
  private final Context context;
  private static final String CONTEXT_TITLE_SETTING = "CONTEXT_TITLE_SETTING";
  private static final String CONTEXT_TEXT_SETTING = "CONTEXT_TEXT_SETTING";
  private static final String SETTINGS_KEY = "Background_Job_Settings";

  public ReactNativeEventStarter(@NonNull Context context) {
    this.context = context;
    reactNativeHost = ((ReactApplication) context.getApplicationContext()).getReactNativeHost();
  }

  public void trigger(@NonNull Bundle jobBundle) {
    Log.d(LOG_TAG, "trigger() called with: jobBundle = [" + jobBundle + "]");
    boolean appInForeground = Utils.isReactNativeAppInForeground(reactNativeHost);
    boolean allowExecutionInForeground = jobBundle.getBoolean("allowExecutionInForeground", false);
    SharedPreferences.Editor editor = this.context.getSharedPreferences(SETTINGS_KEY, Context.MODE_PRIVATE).edit();
    editor.putString(CONTEXT_TEXT_SETTING,jobBundle.getString("notificationText"));
    editor.putString(CONTEXT_TITLE_SETTING, jobBundle.getString("notificationTitle"));
    editor.apply();
    if (!appInForeground || allowExecutionInForeground) {
      // Will execute if the app is in background, or in forground but it has permision to do so
      MyHeadlessJsTaskService.start(context, jobBundle);
    }
  }

  public static class MyHeadlessJsTaskService extends HeadlessJsTaskService {
    private static final String LOG_TAG = MyHeadlessJsTaskService.class.getSimpleName();

    @Override
    @SuppressLint("WrongConstant")
    public void onCreate() {
      super.onCreate();

      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        Context mContext = this.getApplicationContext();
        String CHANNEL_ID = "Background job";

        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, NotificationManager.IMPORTANCE_LOW);
        ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

        SharedPreferences preferences = mContext.getSharedPreferences(SETTINGS_KEY, MODE_PRIVATE);
        String contextTitle = preferences.getString(CONTEXT_TITLE_SETTING, "Running in background...");
        String contextText = preferences.getString(CONTEXT_TEXT_SETTING, "Background job");

        Notification notification =
                new Notification.Builder(mContext, CHANNEL_ID)
                        .setContentTitle(contextTitle)
                        .setContentText(contextText)
                        .setSmallIcon(R.drawable.ic_notification)
                        .build();

        startForeground(1, notification);
      }
    }

    @Nullable @Override protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
      Log.d(LOG_TAG, "getTaskConfig() called with: intent = [" + intent + "]");
      Bundle extras = intent.getExtras();
      boolean allowExecutionInForeground = extras.getBoolean("allowExecutionInForeground", false);
      long timeout = extras.getLong("timeout", 2000);
      // For task with quick execution period additional check is required
      ReactNativeHost reactNativeHost =
          ((ReactApplication) getApplicationContext()).getReactNativeHost();
      boolean appInForeground = Utils.isReactNativeAppInForeground(reactNativeHost);
      if (appInForeground && !allowExecutionInForeground) {
        return null;
      }
      return new HeadlessJsTaskConfig(intent.getStringExtra("jobKey"), Arguments.fromBundle(extras),
          timeout, allowExecutionInForeground);
    }

    public static void start(Context context, Bundle jobBundle) {
      Log.d(LOG_TAG,
          "start() called with: context = [" + context + "], jobBundle = [" + jobBundle + "]");
      Intent starter = new Intent(context, MyHeadlessJsTaskService.class);
      starter.putExtras(jobBundle);

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(starter);
      }else{
        context.startService(starter);
      }
    }
  }
}
