package com.androiddev.project.ili.wishurgift.activities;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.hardware.fingerprint.FingerprintManagerCompat;

import com.android.volley.Response;
import com.androiddev.project.ili.wishurgift.FingerAuthentification.FingerprintDialog;
import com.androiddev.project.ili.wishurgift.R;
import com.androiddev.project.ili.wishurgift.api.UserApi;
import com.androiddev.project.ili.wishurgift.application.Wishurgift;
import com.androiddev.project.ili.wishurgift.model.User;
import com.google.android.material.snackbar.Snackbar;
import com.google.gson.Gson;
import com.mobsandgeeks.saripaar.ValidationError;
import com.mobsandgeeks.saripaar.Validator;
import com.mobsandgeeks.saripaar.annotation.Email;
import com.mobsandgeeks.saripaar.annotation.NotEmpty;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

public class LoginActivity extends AppCompatActivity implements View.OnClickListener, Validator.ValidationListener {

    @NotEmpty
    @Email
    private EditText mEmailView;

    @NotEmpty
    private EditText mPasswordView;

    private ProgressDialog pg;

    private View mLoginFormView;
    private Button mEmailSignInButton;
    private Gson gson = new Gson();
    Button login;
    FingerprintManagerCompat managerCompat;

    private Validator validator;

    @SuppressLint("WrongViewCast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        validator = new Validator(this);
        validator.setValidationListener(this);

        mEmailView = findViewById(R.id.email_signin);

        mPasswordView = findViewById(R.id.password_signin);
        mPasswordView.setOnEditorActionListener(
                (textView, id, keyEvent) -> {
                    if (id == R.id.login_signin || id == EditorInfo.IME_NULL) {
                        attemptLogin();
                        return true;
                    }
                    return false;
                });


        mEmailSignInButton= findViewById(R.id.login_signin);

        mEmailSignInButton.setOnClickListener(v -> {
            validator.validate(true);
        });
    }

    /**
     * Envoie les informations de connexion à l'utilisateur, connecte l'utilisateur ou affiche un message en cas d'erreur
     */
    private void attemptLogin() {
        onPreExecute();
        UserApi.login(mEmailView.getText().toString(), mPasswordView.getText().toString(), (Response.Listener<JSONObject>) response -> {
            Log.d("response", response.toString());
            try {
                Wishurgift.getSessionVariables().setToken(response.getJSONObject("data").getString("token"));
                Log.d("token", Wishurgift.getSessionVariables().getToken());
                Wishurgift.getSessionVariables().setUserConnected(gson.fromJson(response.getJSONObject("data").getJSONObject("user").toString(), User.class));
                onLoginOk();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }, error -> {
            Log.d("error","login issue " + (pg==null));
            if(pg!=null){
                pg.hide();
            }
            AlertDialog.Builder alertDialogBuilder=new AlertDialog.Builder(this);
            alertDialogBuilder.setTitle("Authentification failed");
            alertDialogBuilder.setMessage("Check your login/password or if you are connected to internet. If the error persist contact the administrator").setCancelable(false).setNeutralButton("Ok", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            AlertDialog alertDialog =alertDialogBuilder.create();
            alertDialog.show();
        });
    }


    /**
     * Indique à l'utilisateur que l'authentification est en cours
     */
    private void onPreExecute() {
        if(pg==null) {
            pg = new ProgressDialog(this, R.style.AppTheme_Dark_Dialog);
        }
        pg.setTitle("authentication in progress...");
        pg.setMessage("Please wait.");
        pg.setCancelable(false);
        pg.setIndeterminate(true);
        pg.show();

    }

    /**
     * Affiche le formulaire d'inscription
     * @param View la vue courante
     */
    public void onLoginClick(View View) {
        startActivity(new Intent(this, RegisterActivity.class));
        overridePendingTransition(R.anim.slide_in_right, R.anim.stay);

    }

    /**
     * Affiche l'activité principale à l'utilisateur une fois connecté
     */
    public void onLoginOk() {
        if(pg!=null)
            pg.dismiss();
        finish();
        startActivity(new Intent(this, AppMainActivity.class));
    }

    private void showFingerPrintDialog() {

        FingerprintDialog fragment = new FingerprintDialog();
        fragment.setContext(this);
        fragment.show(getSupportFragmentManager(), "");


    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.login_signin:
                managerCompat = FingerprintManagerCompat.from(LoginActivity.this);

                if (managerCompat.isHardwareDetected() && managerCompat.hasEnrolledFingerprints()) {
                    showFingerPrintDialog();
                } else {
                    Toast.makeText(getApplicationContext(), "Fingerprint not supported", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    public void forgotPasseword(View view) {
        startActivity(new Intent(this, ForgotPasswordActivity.class));
        overridePendingTransition(R.anim.slide_in_right, android.R.anim.slide_in_left);
    }

    @Override
    public void onValidationSucceeded() {
        attemptLogin();
    }

    @Override
    public void onValidationFailed(List<ValidationError> errors) {
        for (ValidationError error : errors) {
            View view = error.getView();
            String message = error.getCollatedErrorMessage(this);

            if (view instanceof EditText) {
                ((EditText) view).setError(message);
            } else {
                Snackbar.make(view, message, Snackbar.LENGTH_LONG).setAction(message, null).show();
            }
        }
    }
}