/*************************************************************
 * By: Coralys Cubero Rivera
 * Date: 2019
 *************************************************************/

package uprrp.tania;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatButton;
import androidx.fragment.app.Fragment;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import org.json.JSONException;
import org.json.JSONObject;
import org.researchstack.backbone.StorageAccess;
import org.researchstack.backbone.answerformat.AnswerFormat;
import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
import org.researchstack.backbone.answerformat.TextAnswerFormat;
import org.researchstack.backbone.model.Choice;
import org.researchstack.backbone.result.StepResult;
import org.researchstack.backbone.result.TaskResult;
import org.researchstack.backbone.step.InstructionStep;
import org.researchstack.backbone.step.QuestionStep;
import org.researchstack.backbone.step.Step;
import org.researchstack.backbone.task.OrderedTask;
import org.researchstack.backbone.ui.ViewTaskActivity;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class AssessmentsFragment extends Fragment {

    //This variables came from the sample app provided to explain the use of Research Stack
    private static final int REQUEST_SURVEY = 1;
    private static final String INSTRUCTION = "identifier";
    private static final String SAMPLE_SURVEY = "sample_assessment";

    //Our variables
    private JSONObject serverJSON;
    private String TAG = "Assessments Fragment";
    private String id_subquestionnair;
    private String device_token;



    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_assessments, container, false);

        //Let's get the device's token
        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
            @Override
            public void onSuccess(InstanceIdResult instanceIdResult) {
                device_token = instanceIdResult.getToken();
            }
        });

        //When the fragment is created we want to fetch the current assessment
        //to be taken by the user if there is one available
//        FetchAssessment jsonServer = new FetchAssessment(getContext(), new URLEventListener<String>() {
//            @Override
//            public void onSuccess(String result) throws JSONException {
//                serverJSON = new JSONObject(result);
//                Log.d(TAG, serverJSON.toString());
//            }
//
//            @Override
//            public void onFailure(Exception e) {
//                Log.d("ERROR", e.toString());
//                Toast.makeText(getContext(), "Can't reach surveys at the moment!", Toast.LENGTH_LONG).show();
//            }
//
//        });
//
//        jsonServer.execute();

        // Launches the assessment that is available for the user
        AppCompatButton surveyButton = view.findViewById(R.id.survey_button);
        surveyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    FetchAssessment jsonServer = new FetchAssessment(getContext(), new URLEventListener<String>() {
                        @Override
                        public void onSuccess(String result) throws JSONException {
                            serverJSON = new JSONObject(result);
                            Log.d(TAG, serverJSON.toString());
                            launchSurvey();
                        }

                        @Override
                        public void onFailure(Exception e) {
                            Log.d("ERROR", e.toString());
                            Toast.makeText(getContext(), "Can't reach surveys at the moment!", Toast.LENGTH_LONG).show();
                        }

                    });
                    URL url = new URL("https://tania.uprrp.edu/getSubQ2.php?tk="+ device_token);

                    jsonServer.execute(url);

//                    launchSurvey();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


        return view;

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == REQUEST_SURVEY && resultCode == Activity.RESULT_OK)
        {
            processSurveyResult((TaskResult) data.getSerializableExtra(ViewTaskActivity.EXTRA_TASK_RESULT));
        }
    }

    private void launchSurvey() {

        /*
        This function uses the JSON that contains the assessment received from the server and builds
        the survey with the Research Stack instruments.
         */

        String description;
        int amount_questions;
        String id_type;
        String premise;
        String max_text;
        String min_text;
        int max_value;

        String id_question;


        if (serverJSON != null) {

            GsonBuilder builder = new GsonBuilder();
            builder.setPrettyPrinting();

            Gson gson = builder.create();
            GenerateQuestionnair questionnair = gson.fromJson(serverJSON.toString(), GenerateQuestionnair.class);

            id_subquestionnair = questionnair.getId_subquestionnair();
            description = questionnair.getDescription();
            amount_questions = questionnair.getAmount_of_questions();

            JsonParser jsonParser = new JsonParser();
            JsonElement rootNode = jsonParser.parse(serverJSON.toString());

            if (rootNode.isJsonObject()) {
                JsonObject jsonDetails = rootNode.getAsJsonObject();
                JsonArray preguntas = jsonDetails.getAsJsonArray("preguntas");

                List<QuestionStep> taniaQuestions = new ArrayList<>();
                List<Step> allSteps = new ArrayList<>();

                InstructionStep instructionStep = new InstructionStep(INSTRUCTION,
                        "TANIA",
                        description);
                instructionStep.setStepTitle(R.string.survey);
                allSteps.add(0, instructionStep);

                for (int k = 0; k < amount_questions; k++) {

                    JsonObject singleQuestion = preguntas.get(k).getAsJsonObject();
                    max_value = singleQuestion.get("max_val").getAsInt();
                    max_text = singleQuestion.get("max_text").getAsString();
                    min_text = singleQuestion.get("min_text").getAsString();
                    premise = singleQuestion.get("premise").getAsString();
                    id_type = singleQuestion.get("id_type").getAsString();
                    id_question = singleQuestion.get("id_question").getAsString();
                    Log.d("id_type", id_type);
                    switch (id_type) {
                        case "1":
                            Choice[] choices = new Choice[max_value];
                            for (int m = 0; m < max_value; m++) {
                                if (m == 0) {
                                    //choices[m] = new Choice<>("" + (m + 1) + " - " + m+1 + "", m + 1);
                                    choices[m] = new Choice<>(Integer.toString(m + 1)+" "+min_text, m + 1);
                                } else if (m == max_value - 1) {
                                    //choices[m] = new Choice<>("" + (m + 1) + " - " + max_value + "", m + 1);
                                    choices[m] = new Choice<>(Integer.toString(m + 1)+" "+max_text, m + 1);
                                } else {
                                    choices[m] = new Choice<>(Integer.toString(m + 1), m + 1);
                                }
                            }

                            taniaQuestions.add(k, new QuestionStep(id_question));
                            taniaQuestions.get(k).setStepTitle(R.string.survey);
                            taniaQuestions.get(k).setTitle(premise);

                            AnswerFormat multiFormat = new ChoiceAnswerFormat(AnswerFormat.ChoiceAnswerStyle.SingleChoice, choices);
                            taniaQuestions.get(k).setAnswerFormat(multiFormat);
                            taniaQuestions.get(k).setOptional(false);
                            allSteps.add(taniaQuestions.get(k));
                            break;

                        case "2":
                            Log.d("id_type2", id_type);
                            TextAnswerFormat format = new TextAnswerFormat();

                            taniaQuestions.add(k, new QuestionStep(id_question));
                            taniaQuestions.get(k).setStepTitle(R.string.survey);
                            taniaQuestions.get(k).setTitle(premise);

//                            AnswerFormat multiFormat = new ChoiceAnswerFormat(AnswerFormat.ChoiceAnswerStyle.SingleChoice, choices);
//                            TextAnswerFormat formatText = new TextAnswerFormat(20);
                            taniaQuestions.get(k).setAnswerFormat(format);
                            taniaQuestions.get(k).setOptional(false);
                            allSteps.add(taniaQuestions.get(k));


                    }
                }

                // Create a task wrapping the steps.
                OrderedTask task = new OrderedTask(SAMPLE_SURVEY, allSteps);

                // Create an activity using the task and set a delegate.
                Intent intent = ViewTaskActivity.newIntent(getContext(), task);
                startActivityForResult(intent, REQUEST_SURVEY);
            }
        }

        else {
            Toast.makeText(getContext(), "There are no surveys at the moment!", Toast.LENGTH_LONG).show();
        }
    }

    private void processSurveyResult(TaskResult result) {
        StorageAccess.getInstance().getAppDatabase().saveTaskResult(result);

        try {
            sendSurveyInfo();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendSurveyInfo() {
        /* This function gets the survey's results and organizes them into a JSON Object that we will
        be sending to the app's server.
         */

        TaskResult taskResult = StorageAccess.getInstance()
                .getAppDatabase()
                .loadLatestTaskResult(SAMPLE_SURVEY);

        JSONObject surveyResults = new JSONObject();

        try {

            surveyResults.put("os", "Android");

            JSONObject data = new JSONObject();
            data.put("id_subquestionnair", id_subquestionnair);
            data.put("token", device_token);

            for (String id : taskResult.getResults().keySet()) {
                JSONObject preguntas = new JSONObject();
                StepResult stepResult = taskResult.getStepResult(id);

                preguntas.accumulate("id_question", id);
                preguntas.accumulate("start_datetime", taskResult.getStartDate().toString());
                preguntas.accumulate("question_answer", stepResult.getResult().toString());
                preguntas.accumulate("end_datetime", taskResult.getEndDate().toString());
                data.accumulate("preguntas", preguntas.toString());
            }

            surveyResults.put("data", data.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Log.d("DEBUG", surveyResults.toString());
        new SendAnswersToServer().execute(surveyResults.toString());

    }


}
