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

import static com.app.simplitend.welcome.welcomepatient.fragments.register.ReActivateFragment.CG_STATUS_KEY;
import static com.app.simplitend.welcome.welcomepatient.fragments.register.ReActivateFragment.CG_XID_KEY;
import static com.app.simplitend.welcome.welcomepatient.fragments.register.ReActivateFragment.IS_CAREGIVER_KEY;
import static com.app.simplitend.welcome.welcomepatient.fragments.register.ReActivateFragment.TOKEN_KEY;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Patterns;
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.NavOptions;
import androidx.navigation.Navigation;

import com.onesignal.OneSignal;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.EditTextErrorRemover;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.caregiverdashboard.activities.deactivateacc.AccountPresenter;
import com.app.simplitend.patient_dashboard.DashBoardActivity;
import com.app.simplitend.databinding.SignInFragmentBinding;
import com.app.simplitend.welcome.welcomepatient.mvvm.WelcomeContracts;
import com.app.simplitend.welcome.welcomepatient.mvvm.WelcomeViewModel;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;

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

import okhttp3.MediaType;
import okhttp3.RequestBody;

public class SignInFragment extends Fragment implements WelcomeContracts.RegisterPatientContract {

    // view binding
    protected SignInFragmentBinding binding;

    // view model
    private WelcomeViewModel welcomeViewModel;

    private ProgressDialog progressDialog;

    public SignInFragment(){
        // required empty constructor
    }

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

        welcomeViewModel = new ViewModelProvider(requireActivity()).get(WelcomeViewModel.class);

        initViews();

        clickEvents();

        return binding.getRoot();
    }

    private void initViews() {
        progressDialog = new ProgressDialog(requireContext());

        new EditTextErrorRemover(
                binding.email,
                binding.pin
        );

        binding.pin.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (editable.toString().length() == 4){
                    AppUtil.closeKeyboard(requireActivity());
                }
            }
        });

    }

    private void clickEvents() {

        binding.forgotPin.setOnClickListener(v ->
                Navigation.findNavController(v).navigate(R.id.action_signInFragment_to_forgotPinFragment));

        binding.signInBtn.setOnClickListener(v -> {
            try {
                if (allOkay()){
                    signIn();
                }
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(requireContext(), "Something went wrong", Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void signIn() throws Exception {
        progressDialog.setTitle("Please wait...");
        progressDialog.setMessage("while we sign you in.");
        progressDialog.setCancelable(false);
        progressDialog.show();

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

        RequestBody email_body = RequestBody.create(binding.email.getText().toString().trim(), MediaType.parse("text/plain"));
        body.put("email", email_body);

        RequestBody pin_body = RequestBody.create(Objects.requireNonNull(binding.pin.getText()).toString().trim(), MediaType.parse("text/plain"));
        body.put("pin", pin_body);

        RequestBody timezone_body = RequestBody.create(AppUtil.getTimeZone(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("timezone", timezone_body);

        String sub_id = OneSignal.getUser().getPushSubscription().getId();

        if (sub_id != null){
            RequestBody one_signal_player_id_body = RequestBody.create(sub_id, MediaType.parse("text/plain;charset=utf-8") );
            body.put("one_signal_player_id", one_signal_player_id_body);
        }

        welcomeViewModel.loginPatient(body, this);
    }

    private boolean allOkay() throws Exception{
        boolean allOkay = true;

        if (binding.email.getText().toString().trim().isEmpty()){
            allOkay = false;
            binding.email.setError("Required");
        }else if (!Patterns.EMAIL_ADDRESS.matcher(binding.email.getText().toString().trim()).matches()){
            allOkay = false;
            binding.email.setError("Invalid email");
        }

        if (Objects.requireNonNull(binding.pin.getText()).toString().trim().isEmpty()){
            allOkay = false;
            Toast.makeText(requireContext(), "Enter your security pin.", Toast.LENGTH_SHORT).show();
        }else if (binding.pin.getText().toString().trim().length() != 4){
            allOkay = false;
            Toast.makeText(requireContext(), "Enter a valid pin.", Toast.LENGTH_SHORT).show();
        }

        return allOkay;
    }

    private void gotoReActivateScreen(String cg_status, String token, int cg_xid){
        NavOptions navOptions = new NavOptions.Builder()
                .setPopUpTo(R.id.welcomeFragment, true)
                .build();

        Bundle bundle = new Bundle();

        bundle.putString(CG_STATUS_KEY, cg_status);
        bundle.putBoolean(IS_CAREGIVER_KEY, false);
        bundle.putInt(CG_XID_KEY, cg_xid);
        bundle.putString(TOKEN_KEY, token);

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

    @Override
    public void onResponse(PatientData patientResult, String token) {
        // caching user data
        PatientDataCache.setPatientData(patientResult);
        AppUtil.savePatientData(token, patientResult.patientId, requireContext(), true);

        progressDialog.dismiss();

        if (!patientResult.caregiver_status.equals(AccountPresenter.ACC_ACTIVE_STR)){
            // account is not active

            gotoReActivateScreen(patientResult.caregiver_status,
                    AppUtil.getPatientToken(requireContext()), -1);

            return;
        }

        progressDialog.setMessage("Almost there...");

        progressDialog.dismiss();

        Toast.makeText(requireContext(), "Log in successful.", Toast.LENGTH_SHORT).show();

        if (patientResult.isCareGiverConnectedWithPatient == 1 && patientResult.isCaregiverTakeSubscription == 1){
            // connected to caregiver
            // thus, sending it to dashboard
            Intent intent = new Intent(requireActivity(), DashBoardActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            requireActivity().finish();
        } else if (patientResult.isCareGiverLink == 1){
            gotoProfileProgress();
        }else{
            // no patient data or no caregiver contact yet added thus sending to contact list
            gotoContactList();
        }
    }

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

        AppUtil.showAlert(requireContext(),
                getString(R.string.something_went_wrong),
                message,
                getString(R.string.ok),
                ((dialog, which) -> {
                    dialog.dismiss();
                }), null, null);
    }

    private void gotoProfileProgress(){
        NavOptions navOptions = new NavOptions.Builder()
                .setPopUpTo(R.id.welcomeFragment, true)
                .build();

        Navigation.findNavController(binding.getRoot())
                .navigate(R.id.action_signInFragment_to_profileProgressFragment, null, navOptions);
    }

    private void gotoContactList(){
        NavOptions navOptions = new NavOptions.Builder()
                .setPopUpTo(R.id.welcomeFragment, true)
                .build();

        Navigation.findNavController(binding.getRoot())
                .navigate(R.id.action_signInFragment_to_createContactFragment, null, navOptions);
    }

}