package com.diampark.test;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.method.PasswordTransformationMethod;
import android.util.Base64;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.diampark.test.Class.MyFileManager;
import com.diampark.test.Class.Pop;
import com.diampark.test.Class.SuiviConcentration;
import com.diampark.test.Fragment.PhonationFragment;
import com.diampark.test.Fragment.SuiviFragment;
import com.diampark.test.Fragment.TremorFragment;
import com.diampark.test.Fragment.VocalFragment;
import com.diampark.test.Fragment.SettingsFragment;
import com.diampark.test.Interface.StateDialogInterface;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.hsalf.smilerating.SmileRating;

import org.vosk.Model;
import org.w3c.dom.Text;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.diampark.test.Fragment.BottomNavigationFragment;

import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class MainActivity extends AppCompatActivity implements NavigationBarView.OnItemSelectedListener {

    public Model model;
    public Integer state = 0;
    public String androidUniqueId = "";
    private static final String SHARED_PREFS = "sharedPrefs";
    private static final String KEY = "DeviceUniqueId";
    private static final String KEY_suvi = "UserSuivi";
    private static final String KEY_Pref = "SendPref";
    private BottomNavigationView bottomNavigationView;
    private Integer currentFrag;
    public Boolean accord_partage = false;
    public TextView helpDesc;
    public SuiviConcentration currentSuivi;

    public MainActivity() {
        super(R.layout.activity_bottom_bar);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        Gson gson = new Gson();
        Intent i = getIntent();
        String s = i.getStringExtra("model");
        this.model = gson.fromJson(s, Model.class);
        bottomNavigationView = findViewById(R.id.bottom_navigation);
        currentFrag = 0;
        getSuiviIfExist();
        checkIfHashCreated();
        checkIfPrefStored();
        configureBottomView();
        bottomNavigationView.setSelectedItemId(R.id.page_1);
        helpDesc = findViewById(R.id.help_text);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        getMenuInflater().inflate(R.menu.help_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case R.id.action_settings:
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.frame, new SettingsFragment())
                        .addToBackStack(null)
                        .commit();
                return true;

            case R.id.action_send:
                Intent send_intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
                send_intent.setType("text/plain");
                send_intent.putExtra(Intent.EXTRA_SUBJECT, "Test multiple attachments");
                String[] to = {"auguste.paoli@polytechnique.edu"};
                send_intent.putExtra(Intent.EXTRA_EMAIL, to);
                send_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                send_intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                //  intent.putExtra(Intent.EXTRA_TEXT, message);
                send_intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM,
                        new MyFileManager().getSessionsUris(this));
                startActivity(send_intent);
                return true;

            case R.id.action_help:
                Intent intent = new Intent(MainActivity.this, Pop.class);

                intent.putExtra("currentFrag", currentFrag);

                startActivity(intent);
                return true;
        }
        return true;
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onBackPressed() {
        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 0) {
            fm.popBackStack();
        } else {
            super.onBackPressed();
        }
    }

    private void configureBottomView() {
        bottomNavigationView.setOnItemSelectedListener(this);
    }

    public void stateShowDialog(StateDialogInterface stateDialogInterface) {
        final androidx.appcompat.app.AlertDialog.Builder popDialog = new AlertDialog.Builder(this);

        LinearLayout linearLayout = new LinearLayout(this);
        final SmileRating rating = new SmileRating(this);

        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        rating.setScaleX((float) 0.9);
        rating.setScaleY((float) 0.9);
        rating.setLayoutParams(lp);

        //add ratingBar to linearLayout
        linearLayout.addView(rating);

        popDialog.setTitle("Comment vous sentez vous ? Notez votre état :");

        popDialog.setView(linearLayout);

        popDialog.setPositiveButton(android.R.string.ok,
                (dialog, which) -> {
                    state = rating.getRating();
                    dialog.dismiss();
                    stateDialogInterface.call();
                })

                .setNegativeButton("Cancel",
                        (dialog, id) -> {
                            dialog.cancel();
                            stateDialogInterface.cancel();
                        });

        popDialog.create();
        popDialog.setCancelable(false);
        popDialog.show();
    }

    public void askSendPermission(Context context) {
        final androidx.appcompat.app.AlertDialog.Builder popDialog = new AlertDialog.Builder(context);

        LinearLayout linearLayout = new LinearLayout(context);
        final TextView question = new TextView(context);

        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );

        question.setLayoutParams(lp);


        question.setText("DiamPark n'est pas une application médicale. " +
                "Elle n'a pas pour objectif d'émettre des diagnostics, " +
                "mais plutôt de récolter des données sur la maladie de Parkinson, " +
                "afin de mieux la connaître et donc de mieux l'appréhender.");

        linearLayout.addView(question);

        popDialog.setTitle("Souhaitez-vous partager vos données avec DiamPark ?");

        popDialog.setView(linearLayout);

        popDialog.setPositiveButton("oui",
                (dialog, which) -> {
                    MainActivity activity = ((MainActivity) context);
                    activity.accord_partage = true;
                    storePreference();
                    dialog.dismiss();
                })

                .setNegativeButton("non",
                        (dialog, id) -> {
                            MainActivity activity = ((MainActivity) context);
                            activity.accord_partage = false;
                            storePreference();
                            dialog.cancel();
                        });

        popDialog.create();
        popDialog.setCancelable(false);
        popDialog.show();
    }

    private void askAuthentification(Context context) {
        android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(context);

        builder.setCancelable(false);
        builder.setTitle("Pour accéder à l'application vous devez vous authentifier :");
        builder.setPositiveButton("Se connecter",
                (dialog, which) -> {
                    askLogin(this);
                });
        builder.setNegativeButton("S'inscrire",
                (dialog, which) -> {
                    askRegister(this);
                });
        builder.create().show();
    }

    private void askRegister(Context context) {
        final androidx.appcompat.app.AlertDialog.Builder popDialog = new AlertDialog.Builder(context);
        final LinearLayout layout = new LinearLayout(context);

        final EditText pseudo = new EditText(context);
        final EditText password = new EditText(context);
        final EditText confirm = new EditText(context);
        final TextView askConfirm = new TextView(context);
        final TextView askPseudo = new TextView(context);
        final TextView askPassword = new TextView(context);


        askPseudo.setText("Choisissez un pseudo :");
        askPseudo.setTextSize(20);
        askPseudo.setTextColor(Color.BLACK);
        askPseudo.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        askPassword.setText("Choisissez un mot de passe :");
        askPassword.setTextSize(20);
        askPassword.setTextColor(Color.BLACK);
        askPassword.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));

        layout.addView(askPseudo);
        layout.addView(pseudo);
        pseudo.setHint("pseudo");
        pseudo.setWidth(1000);
        password.setSingleLine();
        password.setHint("mot de passe");
        password.setWidth(1000);
        layout.addView(askPassword);
        password.setTransformationMethod(new PasswordTransformationMethod());
        layout.addView(password);
        layout.setPadding(50, 0, 0, 0);
        layout.setOrientation(LinearLayout.VERTICAL);
        askConfirm.setText("Confirmez votre mot de passe :");
        askConfirm.setTextSize(20);
        askConfirm.setTextColor(Color.BLACK);
        askConfirm.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        layout.addView(askConfirm);
        confirm.setHint("mot de passe");
        confirm.setTransformationMethod(new PasswordTransformationMethod());
        layout.addView(confirm);
        popDialog.setView(layout);

        popDialog.setPositiveButton("S'inscrire",
                (dialog, which) -> {
                    JsonObject body = new JsonObject();
                    String userPassword = password.getText().toString();
                    String userPseudo = pseudo.getText().toString();

                    if (userPassword != confirm.getText().toString()) {
                        popDialog.setMessage("Les mots de passes ne sont pas les mêmes");
                        dialog.cancel();
                    }
                    if (userPseudo.length() < 5) {
                        popDialog.setMessage("Le mot de passe est trop court (minimum 5 caractères)");
                        dialog.cancel();
                    }

                    try {
                        body.addProperty("pseudo", generate_hash(userPseudo));
                    } catch (NoSuchAlgorithmException e) {
                        Log.i("Error in hash of pseudo", e.toString());
                    }
                    body.addProperty("password", userPassword);
                });
        popDialog.setNegativeButton("Annuler",
                (dialog, which) -> {
                    askAuthentification(this);
                });
        popDialog.create();
        popDialog.setCancelable(false);
        popDialog.show();
    }

    protected Callback tmpCallback = new Callback() {
        @Override
        public void success(Object o, Response response) {
            Log.d("Sucess", response.toString());
        }

        @Override
        public void failure(RetrofitError error) {
            Log.d("Fail", error.toString());
        }
    };

    private void askLogin(Context context) {
        final androidx.appcompat.app.AlertDialog.Builder popDialog = new AlertDialog.Builder(context);
        final LinearLayout layout = new LinearLayout(context);

        final EditText pseudo = new EditText(context);
        final EditText password = new EditText(context);
        final TextView askPseudo = new TextView(context);
        final TextView askPassword = new TextView(context);

        askPseudo.setText("Pseudo :");
        askPseudo.setTextSize(20);
        askPseudo.setTextColor(Color.BLACK);
        askPseudo.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        askPassword.setText("Mot de passe :");
        askPassword.setTextSize(20);
        askPassword.setTextColor(Color.BLACK);
        askPassword.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));

        layout.addView(askPseudo);
        layout.addView(pseudo);
        layout.setPadding(50, 0, 0, 0);
        pseudo.setHint("pseudo");
        pseudo.setWidth(1000);
        password.setSingleLine();
        password.setHint("mot de passe");
        password.setWidth(1000);
        layout.addView(askPassword);
        password.setTransformationMethod(new PasswordTransformationMethod());
        layout.addView(password);
        layout.setOrientation(LinearLayout.VERTICAL);
        popDialog.setView(layout);

        popDialog.setPositiveButton("Se connecter",
                (dialog, which) -> {
                    JsonObject body = new JsonObject();
                    String userPseudo = pseudo.getText().toString();
                    String userPassword = password.getText().toString();
                    try {
                        body.addProperty("pseudo", generate_hash(userPseudo));
                    } catch (NoSuchAlgorithmException e) {
                        Log.i("error in hash of pseudo", e.toString());
                    }
                    body.addProperty("mot de passe", userPassword);
                    Log.i("body", body.toString());
                    new BottomNavigationFragment.Post(body, BottomNavigationFragment.METHODE.LOGIN, tmpCallback).start();
                });
        popDialog.setNegativeButton("Annuler",
                (dialog, which) -> {
                    askAuthentification(this);
                });
        popDialog.create();
        popDialog.setCancelable(false);
        popDialog.show();
    }

    private void getSuiviIfExist() {
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        String suiviObject = sharedPreferences.getString(KEY_suvi, "");

        if (!suiviObject.equals("")) {
            Gson gson = new Gson();
            currentSuivi = gson.fromJson(suiviObject, SuiviConcentration.class);
        } else {
            currentSuivi = new SuiviConcentration();
        }
    }

    public void StoreSuivi(SuiviConcentration suivi) {
        currentSuivi = suivi;
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(suivi);
        editor.putString(KEY_suvi, json);
        editor.apply();
    }

    private void createHash(String pseudo) {
        try {
            androidUniqueId = generate_hash(pseudo);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(KEY, androidUniqueId);
        editor.apply();
    }

    public String generate_hash(String mobile_ID) throws NoSuchAlgorithmException {
        String string = "ah38r-3!çéàn:de23UO";

        byte[] salt = string.getBytes(StandardCharsets.UTF_8);

        MessageDigest md = MessageDigest.getInstance("SHA-512");
        md.update(salt);

        String str = mobile_ID;
        StringBuilder strb = new StringBuilder(str);
        str = strb.reverse().toString();

        byte[] hashedPassword = md.digest(str.getBytes(StandardCharsets.UTF_8));

        return Base64.encodeToString(hashedPassword, Base64.DEFAULT);
    }

    private void checkIfHashCreated() {
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        String android_Unique = sharedPreferences.getString(KEY, "");
        if (android_Unique.equals(""))
            askAuthentification(this);
        else
            androidUniqueId = android_Unique;
    }

    private void checkIfPrefStored() {
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        int partage = sharedPreferences.getInt(KEY_Pref, 0);

        if (partage == 2) {
            accord_partage = false;
        } else if (partage == 1)
            accord_partage = true;
        else {
            askSendPermission(this);
        }
    }

    private void storePreference() {
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        if (accord_partage)
            editor.putInt(KEY_Pref, 1);
        else
            editor.putInt(KEY_Pref, 2);
        editor.apply();
    }

    public void popupStartSession(Context context, String question, String[] answers, StateDialogInterface stateDialogInterface) {
        android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(context);

        TextView title_of_dialog = new TextView(getApplicationContext());
        title_of_dialog.setHeight(150);
        title_of_dialog.setBackgroundColor(Color.BLACK);
        title_of_dialog.setText(question);
        title_of_dialog.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
        title_of_dialog.setTextColor(Color.WHITE);
        title_of_dialog.setGravity(Gravity.CENTER);

        builder.setCustomTitle(title_of_dialog);
        builder.setItems(new CharSequence[]
                        {"Normal: " + answers[0], "\nMinime: " + answers[1], "\nLéger: " + answers[2],
                                "\nModéré: " + answers[3], "\nSèvére: " + answers[4]},
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case 0:
                                state = 0;
                                break;
                            case 1:
                                state = 1;
                                break;
                            case 2:
                                state = 2;
                                break;
                            case 3:
                                state = 3;
                                break;
                            case 4:
                                state = 4;
                                break;
                        }
                        stateDialogInterface.call();
                    }
                });
        builder.create().show();
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.page_1:
                if (currentFrag != 1)
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.frame, new PhonationFragment())
                            .commit();
                currentFrag = 1;
                return true;
            case R.id.page_2:
                if (currentFrag != 2)
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.frame, new TremorFragment())
                            .commit();
                currentFrag = 2;
                return true;
            case R.id.page_3:
                if (currentFrag != 3)
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.frame, new VocalFragment())
                            .commit();
                currentFrag = 3;
                return true;
            case R.id.page_4:
                if (currentFrag != 4)
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.frame, new SuiviFragment())
                            .commit();
                currentFrag = 4;
                return true;
        }
        return false;
    }
}