package com.transistorsoft.cordova.backgroundfetch;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.netsyms.apps.Mobile.MainActivity;
import com.netsyms.apps.Mobile.R;
import com.transistorsoft.tsbackgroundfetch.BackgroundFetch;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class BackgroundFetchHeadlessTask implements HeadlessTask {

    private static final String PREFS_NAME = "NativeStorage";
    private static final String KEY = "accounts";
    private static String shownNotifications = "";
    public final String NOTIFICATION_CHANNEL_ID = "background-channel-id";

    public static String getValue(Context context, String key, String defaultValue) {
        SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE);
        return settings.getString(key, defaultValue);
    }

    /**
     * https://stackoverflow.com/a/34691486
     *
     * @param urlString
     * @return
     * @throws IOException
     */
    public static String getStringFromURL(String urlString) throws IOException {
        HttpURLConnection urlConnection = null;
        URL url = new URL(urlString);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.setReadTimeout(10000 /* milliseconds */);
        urlConnection.setConnectTimeout(15000 /* milliseconds */);
        urlConnection.setDoOutput(true);
        urlConnection.connect();

        BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
        StringBuilder sb = new StringBuilder();

        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line + "\n");
        }
        br.close();

        String jsonString = sb.toString();
        return jsonString;
    }

    @Override
    public void onFetch(Context context) {
        Log.d(BackgroundFetch.TAG, "Notification Poller:  onFetch");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                String accountjson = getValue(context, KEY, null).replaceAll("\\\\", "");
                accountjson = accountjson.substring(1, accountjson.length() - 1);
                //Log.d(BackgroundFetch.TAG, "Notification Poller:  Account JSON: " + accountjson);
                try {
                    JSONArray accounts = new JSONArray(accountjson);

                    for (int i = 0; i < accounts.length(); i++) {
                        try {
                            JSONObject acct = accounts.getJSONObject(i);
                            Log.d(BackgroundFetch.TAG, "Notification Poller:  Account " + i + " URL: " + acct.getString("syncurl"));
                            String notificationString = getStringFromURL(acct.getString("syncurl") + "?key=" + acct.getString("key") + "&username=" + acct.getString("username") + "&action=checknotifications");
                            //Log.d(BackgroundFetch.TAG, "Notification Poller:  Account " + i + " JSON: " + notificationString);
                            JSONArray notifications = new JSONObject(notificationString).getJSONArray("notifications");
                            Log.d(BackgroundFetch.TAG, "Notification Poller:  Account " + i + " JSON parsed: " + notifications.length() + " notifications");
                            for (int j = 0; j < notifications.length(); j++) {
                                JSONObject notif = notifications.getJSONObject(j);

                                Log.d(BackgroundFetch.TAG, "Notification Poller:  Procesing notification ID " + notif.getString("id") + " with title " + notif.getString("title"));

                                if (notif.getBoolean("seen") || shownNotifications.contains("|" + i + ":" + notif.getString("id") + "|")) {
                                    continue;
                                }

                                Intent intent = new Intent(context, MainActivity.class);
                                PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

                                NotificationCompat.Builder b = new NotificationCompat.Builder(context);

                                b.setAutoCancel(true)
                                        .setDefaults(Notification.DEFAULT_ALL)
                                        .setSmallIcon(R.drawable.ic_notification)
                                        .setContentTitle(notif.getString("title"))
                                        .setContentText(notif.getString("content"))
                                        .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                                        .setContentIntent(contentIntent)
                                        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                                        .setVisibility(Notification.VISIBILITY_PRIVATE);

                                // Create alternate notification for lockscreen
                                NotificationCompat.Builder lockb = new NotificationCompat.Builder(context);
                                if (notif.getBoolean("sensitive") == true) {
                                    lockb
                                            .setSmallIcon(R.drawable.ic_notification)
                                            .setContentTitle("Contents hidden")
                                            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
                                } else {
                                    lockb
                                            .setSmallIcon(R.drawable.ic_notification)
                                            .setContentTitle(notif.getString("title"))
                                            .setContentText(notif.getString("content"))
                                            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
                                }

                                b.setPublicVersion(lockb.build());

                                NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                    CharSequence name = "Background Notifications";
                                    int importance = NotificationManager.IMPORTANCE_DEFAULT;
                                    NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
                                    channel.enableLights(true);
                                    channel.enableVibration(true);
                                    channel.setLightColor(Color.rgb(33, 150, 243));
                                    // Register the channel with the system; you can't change the importance
                                    // or other notification behaviors after this
                                    b.setChannelId(NOTIFICATION_CHANNEL_ID);
                                    notificationManager.createNotificationChannel(channel);
                                }


                                notificationManager.notify(Integer.parseInt(notif.getString("id")), b.build());

                                Log.d(BackgroundFetch.TAG, "Notification Poller:  Shown notification " + notif.getString("id"));

                                shownNotifications += "|" + i + ":" + notif.getString("id") + "|";
                            }
                        } catch (Exception e) {
                            Log.d(BackgroundFetch.TAG, "Notification Poller:  Exception: " + e.getMessage());
                            Log.d(BackgroundFetch.TAG, "Notification Poller:  Stack trace: " + Log.getStackTraceString(e));
                        }
                    }
                } catch (Exception e) {
                    Log.d(BackgroundFetch.TAG, "Notification Poller:  Exception: " + e.getMessage());
                    Log.d(BackgroundFetch.TAG, "Notification Poller:  Stack trace: " + Log.getStackTraceString(e));
                } finally {
                    BackgroundFetch.getInstance(context).finish();
                }
            }
        }
        );
        thread.start();
    }
}
