package org.deke.risk.riskahead;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.beardedhen.androidbootstrap.BootstrapLabel;

import org.deke.risk.riskahead.helper.AppConfig;
import org.deke.risk.riskahead.helper.AppController;
import org.deke.risk.riskahead.helper.BaseActivity;
import org.deke.risk.riskahead.helper.IncidentReport;
import org.deke.risk.riskahead.helper.SessionManager;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class ViewReportActivity extends BaseActivity {

    private final static String mActivityTitle = "ViewReport";
    private final static String TAG = ViewReportActivity.class.getSimpleName();

    private EditText txtIncidentCategory;
    private EditText txtIncidentSubCategory;
    private EditText txtPosition;
    private EditText txtTime;
    private EditText txtSuspect;
    private EditText txtWeapons;
    private EditText txtNumOfSuspects;
    private EditText txtVictim;
    private EditText txtVictimOrigin;
    private EditText txtSuspectTransport;
    private EditText txtVictimAffiliation;
    private EditText txtSuspectRecognition;
    private EditText txtEtcEtc;


    private BootstrapLabel scorelabel;
    private IncidentReport incident;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userHasToBeLoggedIn();

        txtIncidentCategory = (EditText) findViewById(R.id.txt_viewreport_incidentcategory);
        txtIncidentSubCategory = (EditText) findViewById(R.id.txt_viewreport_incidentsubcategory);
        txtPosition = (EditText) findViewById(R.id.txt_viewreport_position);
        txtTime = (EditText) findViewById(R.id.txt_viewreport_time);
        scorelabel = (BootstrapLabel) findViewById(R.id.txt_viewreport_points);
        txtSuspect = (EditText) findViewById(R.id.txt_viewreport_suspect);
        txtWeapons = (EditText) findViewById(R.id.txt_viewreport_suspectweapon);
        txtNumOfSuspects = (EditText) findViewById(R.id.txt_viewreport_suspectcount);
        txtVictim = (EditText) findViewById(R.id.txt_viewreport_victim);
        txtVictimOrigin = (EditText) findViewById(R.id.txt_viewreport_victimorigin);
        txtSuspectTransport = (EditText) findViewById(R.id.txt_viewreport_suspecttransport);
        txtVictimAffiliation = (EditText) findViewById(R.id.txt_viewreport_victimaff);
        txtSuspectRecognition = (EditText) findViewById(R.id.txt_viewreport_suspectrecon);
        txtEtcEtc = (EditText) findViewById(R.id.txt_viewreport_etcetc);

        Intent intent = getIntent();
        final Integer id = intent.getIntExtra(BaseActivity.EXTRA_MESSAGE, 0);
        getIncident(id);

        findViewById(R.id.btn_viewreport_upvote).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                makeUpvote(id);
            }
        });

        findViewById(R.id.btn_viewreport_downvote).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                makeDownvote(id);
            }
        });

        findViewById(R.id.btn_viewreport_delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(ViewReportActivity.this)
                        .setTitle("Delete incident")
                        .setMessage("Do you really want to delete this incident?")
                        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                deleteReport(id);
                            }
                        })
                        .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                //do nothing
                            }
                        })
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();

            }
        });
    }

    private void deleteReport(Integer uid) {
        deleteIncident(uid);
    }

    @Override
    protected int getLayoutResourceId() {
        return R.layout.activity_view_report;
    }

    @Override
    protected String getActivityName() {
        return mActivityTitle;
    }

    public void getIncident(Integer uid) {
        String tag_string_req = "getincidentwithpositionfromid";
        StringRequest strReq = getStringRequestGetIncidentWithPositionFromID(uid);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    public void deleteIncident(Integer uid) {
        String tag_string_req = "deactivateIncident";
        StringRequest strReq = getStringRequestDeleteIncident(uid);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private StringRequest getStringRequestDeleteIncident(final Integer incidentid) {
        showDialog();
        return new StringRequest(Request.Method.POST, AppConfig.URL_DEFAULT, new Response.Listener<String>() {

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

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

                    if (!error) {
                        showMessage("Incident deleted");
                        gotoProfileActivity();
                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Log.e(TAG, "Error deleting incident (Server returned error): " + errorMsg);
                        showMessage(errorMsg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error deleting incident: " + error.getMessage());
                showMessage(getString(R.string.errormsg_couldnotretrieve));
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting parameters to login url
                Map<String, String> params = new HashMap<>();
                params.put("tag", "deactivateincident");
                params.put("uid", user.get(SessionManager.KEY_UID));
                params.put("token", user.get(SessionManager.TOKEN));
                params.put("incidentid", incidentid.toString());


                return params;
            }
        };
    }

    private StringRequest getStringRequestGetIncidentWithPositionFromID(final Integer incidentid) {
    showDialog();
        return new StringRequest(Request.Method.POST, AppConfig.URL_DEFAULT, new Response.Listener<String>() {

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

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

                    if (!error) {
                        JSONObject jIncident = jObj.getJSONObject("msg");
                        initReport(new IncidentReport(jIncident));

                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Log.e(TAG, "Error get incident (Server returned error): " + errorMsg);
                        showMessage(errorMsg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error get incident: " + error.getMessage());
                showMessage(getString(R.string.errormsg_couldnotretrieve));
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting parameters to login url
                Map<String, String> params = new HashMap<>();
                params.put("tag", "getincidentfromincidentid");
                params.put("uid", user.get(SessionManager.KEY_UID));
                params.put("token", user.get(SessionManager.TOKEN));
                params.put("incidentid", incidentid.toString());


                return params;
            }

        };
    }

    private String checkIfTextEmptyAndReturnString(String input){
        String formattedString = "Keine Angaben";

        if(input.trim().length() > 0){
            formattedString = input;
        }

        return formattedString;
    }

    private void initReport(IncidentReport incident) {
        Context tmpContext = getApplicationContext();

        scorelabel.setText(Integer.toString(incident.getVotedScore()));
        txtIncidentCategory.setText(incident.getIncidentCategoryName(tmpContext));
        txtIncidentSubCategory.setText(checkIfTextEmptyAndReturnString(incident.getIncidentSubCategoryName(tmpContext)));
        txtTime.setText(checkIfTextEmptyAndReturnString(incident.getTimeString(tmpContext)));
        txtSuspect.setText(checkIfTextEmptyAndReturnString(incident.getSuspectString(tmpContext)));
        txtWeapons.setText(checkIfTextEmptyAndReturnString(incident.getSuspectWeaponsString(tmpContext)));
        txtNumOfSuspects.setText(checkIfTextEmptyAndReturnString(incident.getSuspectNoOfString(tmpContext)));
        txtVictim.setText(checkIfTextEmptyAndReturnString(incident.getVictimString(tmpContext)));
        txtVictimOrigin.setText(checkIfTextEmptyAndReturnString(incident.getVictimOriginString(tmpContext)));
        txtSuspectTransport.setText(checkIfTextEmptyAndReturnString(incident.getSuspectTransportString(tmpContext)));
        txtVictimAffiliation.setText(checkIfTextEmptyAndReturnString(incident.getVictimAffiliationString(tmpContext)));
        txtSuspectRecognition.setText(checkIfTextEmptyAndReturnString(incident.getSuspectRecognitionString(tmpContext)));
        txtEtcEtc.setText(checkIfTextEmptyAndReturnString(incident.getEtcOthersCategory()));

        this.incident = incident;

        Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());

        try {
            List<Address> addressList = geocoder.getFromLocation(incident.getPosition().latitude,incident.getPosition().longitude, 1);
            if (addressList != null && addressList.size() > 0) {
                Address address = addressList.get(0);
                StringBuilder sb = new StringBuilder();

                for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                    if(address.getAddressLine(i) != null) sb.append(address.getAddressLine(i)).append("\n");
                }

                if(address.getCountryName() != null) sb.append(address.getCountryName());

                txtPosition.setText(sb.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        final String latitude = Double.toString(incident.getPosition().latitude);
        final String longitude = Double.toString(incident.getPosition().longitude);

        findViewById(R.id.btn_viewreport_position).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                gotoMapActivity(latitude + ":" + longitude);
            }
        });

        String uid = user.get(SessionManager.KEY_UID);
        if(incident.getFidFromUser() != Integer.valueOf(uid)){
            findViewById(R.id.layoutFooter).setVisibility(View.GONE);
        }
    }

    public void makeUpvote(Integer incidentid) {
        if(user.get(SessionManager.KEY_UID).equals(Integer.toString(incident.getFidFromUser()))){
            showMessage("You can not vote your own incidents");
        }else {
            String tag_string_req = "addvote";
            StringRequest strReq = getStringRequestAddVote(incidentid, "1");
            AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
        }
    }

    public void makeDownvote(Integer incidentid) {
        if(user.get(SessionManager.KEY_UID).equals(Integer.toString(incident.getFidFromUser()))){
            showMessage("You can not vote your own incidents");
        }else {
            String tag_string_req = "addvote";
            StringRequest strReq = getStringRequestAddVote(incidentid, "2");
            AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
        }
    }

    private StringRequest getStringRequestAddVote(final Integer incidentid, final String votetype) {
        return new StringRequest(Request.Method.POST, AppConfig.URL_DEFAULT, new Response.Listener<String>() {

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

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

                    if (!error) {
                        showMessage("Voted! Score updated.");
                        JSONObject jPoints = jObj.getJSONObject("points");

                        scorelabel.setText(Integer.toString(jPoints.getInt("upvoted")-jPoints.getInt("downvoted")));
                        showAd();
                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Log.e(TAG, "Error voting incident (Server returned error): " + errorMsg);
                        showMessage(errorMsg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error voting incident: " + error.getMessage());
                showMessage(getString(R.string.errormsg_couldnotretrieve));
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("tag", "addvote");
                params.put("uid", user.get(SessionManager.KEY_UID));
                params.put("token", user.get(SessionManager.TOKEN));
                params.put("incidentid", incidentid.toString());
                params.put("votetype", votetype);

                return params;
            }
        };
    }

}
