package com.eveningoutpost.dexdrip;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.eveningoutpost.dexdrip.Models.JoH;
import com.eveningoutpost.dexdrip.UtilityModels.NotificationChannels;
import com.eveningoutpost.dexdrip.UtilityModels.Notifications;
import com.eveningoutpost.dexdrip.UtilityModels.Pref;
import com.eveningoutpost.dexdrip.UtilityModels.XdripNotificationCompat;
import com.eveningoutpost.dexdrip.utils.PowerStateReceiver;
import com.eveningoutpost.dexdrip.utils.Preferences;
import com.eveningoutpost.dexdrip.utils.WebAppHelper;

/**
 * Created by jamorham on 17/02/2016.
 */
public class ParakeetHelper {

    private static final String TAG = "jamorham parakeethelp";
    private static boolean waiting_for_parakeet = false;
    public static boolean parakeet_not_checking_in = true; // default no information
    private static long wait_timestamp = 0;
    private static final double PARAKEET_ALERT_MISSING_MINUTES = 60;
    private static long highest_timestamp = 0;
    private static long highest_parakeet_timestamp = -1;

    public static String getParakeetURL(Context context) {
        String my_receivers = PreferenceManager.getDefaultSharedPreferences(context).getString("wifi_recievers_addresses", "").trim();
        if (my_receivers.equals("")) return null;

        String[] hosts = my_receivers.split(",");
        if (hosts.length == 0) return null;

        for (String host : hosts) {
            host = host.trim();
            if ((host.startsWith("http://") || host.startsWith("https://")) && (host.contains("/json.get") || host.contains("Parakeet"))) {
                return host;
            }
        }
        return null;
    }

    public static boolean isParakeetCheckingIn()
    {
        return !parakeet_not_checking_in;
    }

    private static int parakeetMinutesSinceCheckin()
    {
        return (int)((JoH.ts()-highest_parakeet_timestamp)/60000);
    }

    public static String parakeetStatusString()
    {
        if (isParakeetCheckingIn())
        {
            return "Parakeet seen "+parakeetMinutesSinceCheckin()+" mins ago";
        } else {
            return "Parakeet no data";
        }
    }


    public static String getParakeetSetupURL(Context context) {
        String url = getParakeetURL(context);
        if (url == null) return null;
        return url.replace("/json.get", "/setcode/2");
    }

    // put parakeet in to setup mode on next checkin
    public static void parakeetSetupMode(Context context) {

        String url = getParakeetSetupURL(context);

        if (url == null) {
            toast(context, "Can't find parakeet app engine URL!");
            return;
        }
        new WebAppHelper(new ParakeetHelper.ServiceCallback()).executeOnExecutor(xdrip.executor, url);
    }

    public static void checkParakeetNotifications(long timestamp, String geo_location) {
        Log.d(TAG, "CheckParakeetNotifications: " + timestamp + " / " + geo_location + " not checking in? " + parakeet_not_checking_in);
        if (waiting_for_parakeet) {
            Log.d(TAG, "checkParakeetNotifications:" + waiting_for_parakeet + " " + timestamp + " vs " + wait_timestamp);
            if (timestamp > wait_timestamp) {
                Log.d(TAG, "sending notification");
                sendNotification("The parakeet has connected to the web service.",
                        "Parakeet has connected!");
                waiting_for_parakeet = false;
                if (!PreferenceManager.getDefaultSharedPreferences(xdrip.getAppContext()).getBoolean("parakeet_first_run_done", false)) {
                    PreferenceManager.getDefaultSharedPreferences(xdrip.getAppContext()).edit().putBoolean("parakeet_first_run_done", true).apply();
                }
            }
        } else {
            // look at any record which looks newer than we have considered so far

                // ignore everything except parakeet sourced datums
                if ((timestamp > highest_parakeet_timestamp) && (!geo_location.equals("-15,-15"))) {
                highest_parakeet_timestamp=timestamp;
                }
                    final int minutes_since = (int) ((JoH.ts() - highest_parakeet_timestamp) / (1000 * 60));
                    if (highest_parakeet_timestamp>0) Log.d(TAG, "Not waiting for parakeet Minutes since: " + minutes_since);


                    if (!parakeet_not_checking_in) {
                        if ((minutes_since > PARAKEET_ALERT_MISSING_MINUTES) && (highest_parakeet_timestamp > 0)) {
                            if (timestamp >= highest_timestamp) {
                                parakeet_not_checking_in = true;
                                Log.i(TAG, "Parakeet missing for: " + minutes_since + " mins");
                                sendNotification("The parakeet has not connected > " + minutes_since + " mins",
                                        "Parakeet missing");
                                // TODO some more sophisticated persisting notification
                            }
                        }
                    } else {
                        if (timestamp < highest_parakeet_timestamp) Log.d(TAG,"Timestamp less than highest");
                        if ((timestamp >= highest_parakeet_timestamp) && (minutes_since < PARAKEET_ALERT_MISSING_MINUTES)
                                && (!geo_location.equals("-15,-15"))) {
                            Log.d(TAG, "Parakeet now checking in: " + minutes_since + " mins ago");
                            parakeet_not_checking_in = false;
                            cancelParakeetMissingNotification();
                        }
                    }

                    if (timestamp > highest_timestamp) {
                        highest_timestamp = timestamp;
                    }

            }

    }

    public static void notifyOnNextCheckin(boolean always) {
        if ((always) || (!PreferenceManager.getDefaultSharedPreferences(xdrip.getAppContext()).getBoolean("parakeet_first_run_done", false))) {
            waiting_for_parakeet = true;
            wait_timestamp = System.currentTimeMillis();
        }
        }

    public static void toast(Context context, final String msg) {
        try {
            Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
            Log.d(TAG, "toast: " + msg);
        } catch (Exception e) {
            Log.d(TAG, "Couldn't display toast: " + msg + " / " + e.toString());
        }
    }


    private static void sendNotification(String body, String title) {
        if (Pref.getBooleanDefaultFalse("parakeet_status_alerts")) {
            Intent intent = new Intent(xdrip.getAppContext(), Home.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(xdrip.getAppContext(), 0 /* Request code */, intent,
                    PendingIntent.FLAG_ONE_SHOT);

            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder =  new NotificationCompat.Builder(xdrip.getAppContext(), NotificationChannels.PARAKEET_STATUS_CHANNEL)
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(xdrip.getAppContext().getResources(), R.drawable.jamorham_parakeet_marker))
                    .setContentTitle(title)
                    .setContentText(body)
                    .setAutoCancel(true)
                 //   .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

            if (!((PowerStateReceiver.is_power_connected()) && (Pref.getBooleanDefaultFalse("parakeet_charge_silent"))))
            {
                notificationBuilder.setSound(defaultSoundUri);
            }

            NotificationManager notificationManager =
                    (NotificationManager) xdrip.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);

            notificationManager.cancel(Notifications.parakeetMissingId);
            notificationManager.notify(Notifications.parakeetMissingId, XdripNotificationCompat.build(notificationBuilder));
        } else {
            Log.d(TAG, "Not sending parakeet notification as they are disabled: " + body);
        }
    }

    private static void cancelParakeetMissingNotification()
    {
        NotificationManager notificationManager =
                (NotificationManager) xdrip.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(Notifications.parakeetMissingId);
    }

    public static boolean isRealParakeetDevice() {
        return (!parakeet_not_checking_in);
    }

    public static class ServiceCallback implements Preferences.OnServiceTaskCompleted {
        @Override
        public void onTaskCompleted(byte[] result) {
            try {
                String string_result = new String(result, "UTF-8");
                if (string_result.startsWith("OK")) {
                    notifyOnNextCheckin(true);
                    String[] results = string_result.split(" ");
                    if (results[1].contains("0")) {
                        toast(xdrip.getAppContext(), "Parakeet code sent! Now waiting..");
                    } else {
                        toast(xdrip.getAppContext(), "Parakeet code sent! Code: " + results[1]);
                    }
                } else {
                    toast(xdrip.getAppContext(), "Error - is app engine receiver recent enough?");
                }

            } catch (Exception e) {
                Log.e(TAG, "Got error in web helper callback: " + e.toString());
            }
        }
    }

}