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

import static com.app.simplitend.welcome.welcomecg.fragments.CgConnectFragment.CAREGIVER_EMAIL;
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.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
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.navigation.NavOptions;
import androidx.navigation.Navigation;

import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.caregiverdashboard.activities.CaregiverDashActivity;
import com.app.simplitend.caregiverdashboard.activities.deactivateacc.AccountPresenter;
import com.app.simplitend.databinding.SplashFragmentBinding;
import com.app.simplitend.patient_dashboard.DashBoardActivity;
import com.app.simplitend.patientprofile.PatientProfileAPIService;
import com.app.simplitend.patientprofile.ProfileContracts;
import com.app.simplitend.welcome.welcomecg.WelcomeApiService;
import com.app.simplitend.welcome.welcomecg.WelcomeContracts;
import com.app.simplitend.welcome.welcomecg.fragments.CgAuthActivity;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
import com.onesignal.OneSignal;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class SplashFragment extends Fragment
        implements ProfileContracts.ProfileProgressCallback,
        WelcomeContracts.CgGetUserDataCallback {

    // view binding
    protected SplashFragmentBinding binding;

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

        binding.retry.setOnClickListener(v -> {
            checkIfAhyUser();
        });

        return binding.getRoot();
    }

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

    private void checkIfAhyUser() {
        binding.retry.setVisibility(View.GONE);
        binding.loadAnim.setVisibility(View.VISIBLE);

        String patient_token = AppUtil.getPatientToken(requireContext());
        String cg_token = AppUtil.getCgToken(requireContext());
        boolean is_patient_logged_in = AppUtil.isPatientLoggedIn(requireContext());

        if (patient_token != null && !patient_token.isEmpty() && is_patient_logged_in){
            // user is already logged in as PATIENT
            // thus, checking if the logged in PATIENT has already added CAREGIVER

            PatientProfileAPIService apiService = RetrofitHelper.getRetrofit().create(PatientProfileAPIService.class);

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

            apiService.getUsrProfileProgress("Bearer " + patient_token, sub_id, AppUtil.getTimeZone())
                    .enqueue(new Callback<CallResponse<PatientData>>() {
                        @Override
                        public void onResponse(Call<CallResponse<PatientData>> call, Response<CallResponse<PatientData>> response) {
                            if (response.body() != null) {
                                if (response.body().status != 200 || response.body().result == null) {
                                    onProfileProgressFetchFailed(new Exception(), response.body().message);
                                    return;
                                }

                                onProfileProgressFetched(response.body().result);
                            } else {
                                sessionExpired();
                            }
                        }

                        @Override
                        public void onFailure(Call<CallResponse<PatientData>> call, Throwable t) {
                            onProfileProgressFetchFailed(new Exception(), "Please try again later.");
                        }
                    });

        }else if (cg_token != null){

            WelcomeApiService welcomeApiService = RetrofitHelper.getRetrofit().create(WelcomeApiService.class);

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

            welcomeApiService.getCgUserData("Bearer " + cg_token, sub_id)
                    .enqueue(new Callback<CallResponse<CareGiverData>>() {
                        @Override
                        public void onResponse(Call<CallResponse<CareGiverData>> call, Response<CallResponse<CareGiverData>> response) {
                            if (response.body() != null) {
                                if (response.body().status != 200 || response.body().result == null) {
                                    onCgDataFetchFailed(new Exception(), response.body().message);
                                    return;
                                }

                                onCgDataFetched(response.body().result);
                            } else {
                                sessionExpired();
                            }
                        }

                        @Override
                        public void onFailure(Call<CallResponse<CareGiverData>> call, Throwable t) {
                            onCgDataFetchFailed(new Exception(), "Please try again later.");
                        }
                    });

        }else{
            // no user has logged in
            gotoWelcomeFragment();
        }
    }

    private void sessionExpired(){
        binding.retry.setVisibility(View.VISIBLE);
        binding.loadAnim.setVisibility(View.GONE);

        new AlertDialog.Builder(requireContext())
                .setTitle("Session Expired")
                .setMessage("Your login session has expired.\nPlease login again.")
                .setCancelable(true)
                .setPositiveButton("OKAY", (dialogInterface, i) -> {
                    AppUtil.patientSignOut(requireContext());
                    AppUtil.cgSignOut(requireContext());

                    gotoWelcomeFragment();
                })
                .show();
    }

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

        Bundle bundle = new Bundle();

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

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

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

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

    public void gotoWelcomeFragment(){
        NavOptions navOptions = new NavOptions.Builder()
                .setPopUpTo(R.id.splashFragment, true)
                .build();

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

    private void gotoPatientDashBoard() {
        Intent intent = new Intent(requireActivity(), DashBoardActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        requireActivity().finish();
    }

    private void gotoCgAuthScreen(){
        Intent intent = new Intent(requireActivity(), CgAuthActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        requireActivity().finish();
    }

    private void gotoCgDashBoard(){
        Intent intent = new Intent(requireActivity(), CaregiverDashActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        requireActivity().finish();
    }

    // get cg user data callback
    @Override
    public void onCgDataFetched(CareGiverData careGiverData) {
        // caching data
        CaregiverDataCache.setCareGiverData(careGiverData);

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

            gotoReActivateScreen(careGiverData.caregiver_status, AppUtil.getCgToken(requireContext()),
                    careGiverData.caregiver_xid, true);

            return;
        }

        binding.retry.setVisibility(View.GONE);
        binding.loadAnim.setVisibility(View.GONE);

        if (careGiverData.isPatientAndCareGiverConnected == 1){
            // patient is linked with the caregiver
            int cg_security = AppUtil.getWantSecurityFlag(requireContext());

            if (cg_security == AppUtil.NOT_ASKED_CG_SECURITY || cg_security == AppUtil.CG_SECURITY_NEEDED){
                // user want their app to be secure
                gotoCgAuthScreen();
            }else{
                // user does not want the security
                gotoCgDashBoard();
            }

        }else{
            // patient is not linked with the caregiver
            // thus, sending it to the cg connect screen
            NavOptions navOptions = new NavOptions.Builder()
                    .setPopUpTo(R.id.splashFragment, true)
                    .build();

            Bundle bundle = new Bundle();
            bundle.putString(CAREGIVER_EMAIL, careGiverData.email);

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

    }

    @Override
    public void onCgDataFetchFailed(Throwable t, String message) {
        Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();

        binding.retry.setVisibility(View.VISIBLE);
        binding.loadAnim.setVisibility(View.GONE);
    }

    // get patient user data callback
    @Override
    public void onProfileProgressFetched(PatientData patientData) {
        // caching data
        PatientDataCache.setPatientData(patientData);

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

            if (!patientData.caregiver_status.equals(AccountPresenter.DEFAULT_ACTIVE_STATUS)) {
                // account is in default state

                gotoReActivateScreen(patientData.caregiver_status,
                        AppUtil.getPatientToken(requireContext()),
                        -1, false);
                return;
            }
        }

        binding.retry.setVisibility(View.GONE);
        binding.loadAnim.setVisibility(View.GONE);

        if (patientData.isCareGiverConnectedWithPatient == 1 && patientData.isCaregiverTakeSubscription == 1){
            // go to dashboard
            gotoPatientDashBoard();
        }else if (patientData.isCareGiverLink == 1){
            // user has already added caregiver as a contact
            // thus, sending it to dashboard
            gotoPatientProfileProgress();
        }else{
            // user has not added caregiver contact.
            // thus, sending it to contact list to add caregiver contact.
            NavOptions navOptions = new NavOptions.Builder()
                    .setPopUpTo(R.id.splashFragment, true)
                    .build();

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

    @Override
    public void onProfileProgressFetchFailed(Throwable t, String message) {

        Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();

        binding.retry.setVisibility(View.VISIBLE);
        binding.loadAnim.setVisibility(View.GONE);
    }
}