package com.diampark.test.Fragment;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.diampark.test.Class.MyFileManager;
import com.diampark.test.Class.UserTremorSession;
import com.diampark.test.Class.calcul_PSD;
import com.diampark.test.Interface.StateDialogInterface;
import com.diampark.test.MainActivity;
import com.diampark.test.R;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import java.io.File;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class TremorFragment extends BottomNavigationFragment implements SensorEventListener, StateDialogInterface {

    private final static String modalite = "tremor";
    private SensorManager sensorManager;
    private Context myContext;
    private String userHash = "";
    private SensorEventListener c;
    private ProgressBar pb;
    private Button b;
    private UserTremorSession userTremorSession;
    private int ifPressed = 0;
    private TextView textView;
    private float ax = 0;
    private float ay = 0;
    private float az = 0;
    private MainActivity mActivity;
    double[] fenetre = {3.5f, 12f};
    double[] tabX = new double[500];
    double[] tabY = new double[500];
    double[] tabZ = new double[500];
    int nb = 0;

    public TremorFragment() {
        super(R.layout.fragment_tremor);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        myContext = this.getContext();

        pb = view.findViewById(R.id.progressBar);
        b = view.findViewById(R.id.button);
        textView = view.findViewById(R.id.res);

        c = this;

        mActivity = (MainActivity) getActivity();

        if (mActivity != null) {
            userHash = mActivity.androidUniqueId;
            sensorManager = (SensorManager) mActivity.getSystemService(Context.SENSOR_SERVICE);
            sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
        }

        b.setOnClickListener(v -> {
            if (mActivity != null && ifPressed == 0) {
                String[] answers = {"Pas du tout. Je n’ai pas de tremblement.", "Un tremblement survient, mais ne me " +
                        "cause pas de problème dans mes activités.", "Un tremblement me cause des problèmes, mais " +
                        "seulement dans un petit nombre d’activités.", "Un tremblement me cause des problèmes dans " +
                        "beaucoup de mes activités quotidiennes.", "Un tremblement me cause des problèmes avec la plupart ou toutes mes activités."};
                mActivity.popupStartSession(myContext, "Au cours de la semaine précédente, avez-vous eu " +
                        "habituellement des tremblements ?", answers, this);
            }
            ifPressed = 1;
        });

    }

    private void startSensor() {
        Timer timer = new Timer();
        Handler handler = new Handler();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (nb < 500) {
                    tabX[nb] = ax;
                    tabY[nb] = ay;
                    tabZ[nb] = az;
                    nb++;
                }
            }
        }, 0, 10);

        handler.postDelayed(() -> {
            timer.cancel();
            sensorManager.unregisterListener(c, sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY));
            getResult();
            pb.setVisibility(View.INVISIBLE);
            b.setVisibility(View.VISIBLE);
            writeResult();
            nb = 0;
        }, 5500);
    }

    private void writeResult() {
        userTremorSession.setDate(Calendar.getInstance().getTime());
        userTremorSession.setHashUser(userHash);
        userTremorSession.setState(mActivity.state);
        userTremorSession.setLevo(mActivity.currentSuivi.concentration());

        String allTab = getTabToString(tabX);
        allTab += getTabToString(tabY);
        allTab += getTabToString(tabZ);

        if (mActivity.accord_partage) {
            JsonObject body = new JsonObject();
            body.addProperty("HashCodeUser", userHash);
            body.addProperty("Modalite", modalite);
            body.addProperty("JSON_resultats", new Gson().toJson(new Gson().toJson(userTremorSession)));
            body.addProperty("Fichier_de_sortie", allTab);
            body.addProperty("JSON_levo", new Gson().toJson(new SuiviToPost(mActivity.currentSuivi)));
            new Post(body, METHODE.POSTDATA, tmpCallback).start();
        }

        new MyFileManager().writePerfOnInternalStorage(myContext,
                new Gson().toJson(userTremorSession), MyFileManager.directoryTremorName, MyFileManager.fileTremorBaseName);
        userTremorSession = null;
    }


    private String getTabToString(double[] tab) {
        List<Double> list1 = new ArrayList<>();
        for (double t : tab) {
            list1.add(t);
        }
        return list1.toString();
    }

    private void getResult() {
        saveTab();
        showResult(calcul_PSD.calcul_Qs(tabX, tabY, tabZ, 100, fenetre));
    }

    private void showResult(double[] tuple) {
        userTremorSession.setQ1(tuple[0]);
        userTremorSession.setQ2(tuple[1]);
        if (mActivity.accord_partage) {
            textView.setText("Session terminée ! L'importance de vos tremblements est de " + new DecimalFormat("##.#").format(tuple[1] * 100) + "%\n" + "Vos données ont bien été envoyées à DiamPark !");
        } else {
            textView.setText("Session terminée ! L'importance de vos tremblements est de " + new DecimalFormat("##.#").format(tuple[1] * 100) + "%\n");
        }
    }

    private void saveTab() {
        File dir = new MyFileManager().getCacheFileDir(myContext, MyFileManager.directoryTremorName);

        String perf = allTabToString();

        if (dir != null) {
            File tabFile = new MyFileManager().getNewFileText(myContext,
                    MyFileManager.directoryTremorName, MyFileManager.fileTabTremorBaseName);
            userTremorSession.setFileName(tabFile.getName());
            try {
                FileWriter writer = new FileWriter(tabFile, false);
                writer.append(perf);
                writer.flush();
                writer.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private String tabToString(double[] tab, String tabName) {
        int i = 0;
        String res = tabName + " : [";
        while (i < 500) {
            res += tab[i] + ",";
            i++;
        }
        res += "]";
        return res;
    }

    private String allTabToString() {
        return tabToString(tabX, "TabX") +
                tabToString(tabY, "TabY") +
                tabToString(tabZ, "TabZ");
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            ax = event.values[0];
            ay = event.values[1];
            az = event.values[2];
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
    }

    @Override
    public void call() {
        textView.setText("");
        ifPressed = 0;
        b.setVisibility(View.GONE);
        userTremorSession = new UserTremorSession();
        startSensor();
        pb.setVisibility(View.VISIBLE);
    }

    @Override
    public void cancel() {

    }
}
