package com.app.simplitend.welcome.welcomecg.fragments;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;

import com.bumptech.glide.Glide;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.databinding.CgCheckEmailFragmentBinding;
import com.app.simplitend.welcome.welcomecg.WelcomeContracts;
import com.app.simplitend.welcome.welcomecg.mvvm.CgForgotPwdResult;
import com.app.simplitend.welcome.welcomecg.mvvm.CgWelcomeViewModel;

import java.util.HashMap;
import java.util.Map;

public class CgCheckEmailFragment extends Fragment implements WelcomeContracts.ForgotPwdSentCodeCallback,
        WelcomeContracts.VerifyForgotOTP {

    protected CgCheckEmailFragmentBinding binding;

    public static final String FORGOT_EMAIL = "forgot_mail";
    public static final String CG_USER_XID = "cg_user_xid";

    private String mEmail, mUserXid;

    private CgWelcomeViewModel viewModel;

    private ProgressDialog progressDialog;

    public CgCheckEmailFragment() {
        // required
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = CgCheckEmailFragmentBinding.inflate(inflater, container, false);

        viewModel = new ViewModelProvider(requireActivity()).get(CgWelcomeViewModel.class);

        initViews();

        clickEvents();

        return binding.getRoot();
    }

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

        if (bundle == null ||
                bundle.getString(FORGOT_EMAIL, null) == null ||
                bundle.getString(CG_USER_XID, null) == null) {
            // no data received
            Navigation.findNavController(binding.getRoot()).popBackStack();
            Toast.makeText(requireContext(), "Something went wrong.", Toast.LENGTH_SHORT).show();
            return;
        }

        mEmail = bundle.getString(FORGOT_EMAIL);
        mUserXid = bundle.getString(CG_USER_XID);

        binding.emailAt.setVisibility(View.VISIBLE);
        try {
            binding.email.setText(encodeEmail(mEmail));
        } catch (Exception e) {
            binding.email.setText(mEmail);
        }

    }

    private void clickEvents() {

        binding.backBtn.setOnClickListener(view -> {
            requireActivity().onBackPressed();
        });

        binding.submit.setOnClickListener(view -> {
            if (checkOTPInputs()){
                verifyOTP();
            }else{
                Toast.makeText(requireContext(), "Enter PIN received on your email.", Toast.LENGTH_SHORT).show();
            }
        });

        binding.resendOtp.setOnClickListener(v -> {
            if (mEmail == null) return;

            progressDialog.setTitle("Please wait...");
            progressDialog.setMessage("while we resend you an OTP.");
            progressDialog.setCancelable(false);
            progressDialog.show();

            viewModel.sendForgotCodeEmail(mEmail, this);
        });
    }

    public String encodeEmail(String email) throws Exception{
        String[] arr = email.split("@");
        String email_name = arr[0];

        StringBuilder encoded_email = new StringBuilder();

        for (int i = 0; i<email_name.length()-1; i++){
            encoded_email.append("*");
        }

        encoded_email.append(email_name.charAt(email_name.length()-1));

        return encoded_email + "@" + arr[1];
    }

    private void verifyOTP() {
        progressDialog.setTitle("Please wait");
        progressDialog.setMessage("while we verify your OTP.");
        progressDialog.setCancelable(false);
        progressDialog.show();

        Map<String, String> body = new HashMap<>();

        body.put("otp_code", getOTPFromInputs());

        body.put("user_id", mUserXid);

        viewModel.verifyForgotOTP(body, this);
    }

    private void initViews() {

        progressDialog = new ProgressDialog(requireContext());

        // showing gif
        Glide.with(binding.image)
                .asGif()
                .load(R.raw.email_sending_anim)
                .placeholder(R.drawable.forgot_pin_email_img)
                .into(binding.image);

        initOTPBoxes();

    }

    private String getOTPFromInputs() {
        return binding.otp1.getText().toString() +
                binding.otp2.getText().toString() +
                binding.otp3.getText().toString() +
                binding.otp4.getText().toString();
    }

    /*
       setting text change listener for every edit text for otp
    */
    private void initOTPBoxes() {

        binding.otp1.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!s.toString().trim().isEmpty()) {
                    binding.otp2.requestFocus();
                    if (checkOTPInputs()) {
                        AppUtil.closeKeyboard(requireActivity());
                    }
                }

                // check if all otp boxes are filled

            }
        });

        binding.otp2.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!s.toString().trim().isEmpty()) {
                    binding.otp3.requestFocus();
                    if (checkOTPInputs()) {
                        AppUtil.closeKeyboard(requireActivity());
                    }
                } else {
                    binding.otp1.requestFocus();
                }

                // check if all otp boxes are filled

            }
        });

        binding.otp3.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!s.toString().trim().isEmpty()) {
                    binding.otp4.requestFocus();
                    if (checkOTPInputs()) {
                        AppUtil.closeKeyboard(requireActivity());
                    }
                } else {
                    binding.otp2.requestFocus();
                }

                // check if all otp boxes are filled

            }
        });

        binding.otp4.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!s.toString().trim().isEmpty()) {
                    // last otp inserted
                    AppUtil.closeKeyboard(getActivity());
                } else {
                    binding.otp3.requestFocus();
                }

                // check if all otp boxes are filled

            }
        });

    }

    public boolean checkOTPInputs() {

        if (binding.otp3.getText().toString().trim().length() != 1) {
            return false;
        } else if (binding.otp2.getText().toString().trim().length() != 1) {
            return false;
        } else if (binding.otp3.getText().toString().trim().length() != 1) {
            return false;
        } else if (binding.otp4.getText().toString().trim().length() != 1) {
            return false;
        }

        return true;
    }

    // otp send callback
    @Override
    public void onEmailSentSuccess(CgForgotPwdResult result) {
        progressDialog.dismiss();

        Toast.makeText(requireContext(), "OTP resent successfully.", Toast.LENGTH_SHORT).show();

        clearInputs();
    }

    private void clearInputs() {
        binding.otp1.setText(null);
        binding.otp2.setText(null);
        binding.otp3.setText(null);
        binding.otp4.setText(null);

        binding.otp1.requestFocus();
    }

    @Override
    public void onEmailSentFailed(Throwable t, String message) {
        progressDialog.dismiss();

        Toast.makeText(requireContext(), "Couldn't resend OTP.", Toast.LENGTH_SHORT).show();
    }

    // verify otp callback


    @Override
    public void onOTPVerified() {
        Bundle bundle = new Bundle();
        bundle.putString(FORGOT_EMAIL, mEmail);

        progressDialog.dismiss();

        Toast.makeText(requireContext(), "OTP verification successful.", Toast.LENGTH_SHORT).show();

        Navigation.findNavController(binding.getRoot())
                .navigate(R.id.action_cgCheckEmailFragment_to_cgChangePwdFragment, bundle);
    }

    @Override
    public void onOTPVerificationFailed(Throwable t, String message) {
        progressDialog.dismiss();

        Toast.makeText(requireContext(), "" + message, Toast.LENGTH_SHORT).show();
    }
}
