package org.deke.risk.riskahead.helper;


import android.app.NotificationManager;
import android.app.PendingIntent;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.*;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.google.android.gms.maps.model.LatLng;

import org.deke.risk.riskahead.MapsActivity;
import org.deke.risk.riskahead.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by denni on 06.01.2016.
 */
public class NotificationService extends Service {

    private final static String TAG = NotificationService.class.getSimpleName();
    private final static String EXTRA_MESSAGE = "org.deke.risk.riskahead.MESSAGE";

    Handler mNotifyHandler  = new Handler();
    NotificationManager mNotificationManager;

    private LatLng myPosition;
    private boolean notifyEnabled = true;
    private int radius = 15;
    private int pollFrequency = 10;

    public SessionManager session;
    public HashMap<String, String> user;

    public NotificationService() {
        super();
    }

    @Override
    public void onCreate(){
        Log.d(TAG,"Service Created. Starting notification task...");
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        session = new SessionManager(getApplicationContext());
        user = session.getUserDetails();

        mNotifyTask.run();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    Runnable mNotifyTask = new Runnable() {
        @Override
        public void run() {
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

            myPosition = session.getLocation();
            radius = session.getNotificationRadius();
            pollFrequency = session.getNotificationPollFreq() * 1000; //TODO add minutes
            notifyEnabled = session.getNotificationEnabled();

            Log.d(this.toString(), "Run Notification Task. Notifications enabled = "+notifyEnabled);

            if ((myPosition != null) && (myPosition.latitude != 0.0) && (myPosition.longitude != 0.0)) {

                String lastNotificationTime = "";

                if (session.getLastNotification().equals("")) {
                    lastNotificationTime = user.get(SessionManager.KEY_LASTLOGIN_AT);
                } else {
                    lastNotificationTime = session.getLastNotification();
                }

                Log.d(this.toString(), "Lookup location with position: " + myPosition + " Radius: "+radius+" PollFrequency: "+pollFrequency+" lastNotifyTime: " + lastNotificationTime);

                StringRequest strReq = getStringRequestIncidentsFromAreaAndTime(myPosition.latitude, myPosition.longitude, radius, lastNotificationTime);
                String tag_string_req = "req_incidents";
                AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
            }

            mNotifyHandler.postDelayed(mNotifyTask, pollFrequency);
        }
    };

    private StringRequest getStringRequestIncidentsFromAreaAndTime(final Double latitude, final Double longitude, final int radius, final String time) {
        return new StringRequest(Request.Method.POST, AppConfig.URL_DEFAULT, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Incident notifications: " + response);

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    if (!error) {
                        JSONArray notification = jObj.getJSONArray("msg");

                        sentNotification(notification);
                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Log.e(TAG, "Error getting incident notification (server returned error): " + errorMsg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error getting incident notification: " + error.getMessage());
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("tag", "getincidentsinareaandtime");
                params.put("uid", user.get(SessionManager.KEY_UID));
                params.put("token", user.get(SessionManager.TOKEN));
                params.put("latitude", Double.toString(latitude));
                params.put("longitude", Double.toString(longitude));
                params.put("radius", Integer.toString(radius));
                params.put("time", "'"+time+"'");
                return params;
            }
        };
    }

    private void sentNotification(JSONArray notification) {
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(getApplicationContext())
                        .setSmallIcon(R.drawable.logo_riskahead_header)
                        .setContentTitle("New incidents reported in your area!")
                        .setContentText(notification.length() + " new incidents near your last location. Watch out!");




        Intent resultIntent = new Intent(this, MapsActivity.class);

        try {
            resultIntent.putExtra(EXTRA_MESSAGE, notification.getJSONObject(notification.length()-1).getDouble("latitude")+":"+notification.getJSONObject(notification.length()-1).getDouble("longitude"));
        } catch (JSONException e) {
            e.printStackTrace();
        }

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(MapsActivity.class);

        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(
                        0,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);

        int mId = 1;
        mNotificationManager.notify(mId, mBuilder.build());

        session.setLastNotification(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()));

    }

}
