package uprrp.tania.fragments;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;

import java.util.Objects;
import java.util.Observable;
import java.util.Observer;

import uprrp.tania.GlobalValues;
import uprrp.tania.R;
import uprrp.tania.utils.URLEventListener;
import uprrp.tania.activities.GettingStartedActivity;
import uprrp.tania.networking.SendWithdrawal;

public class WithdrawFragment extends Fragment implements Observer {

    private static final String TAG = "WithdrawFragment";
    private View thisFragment;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        // Constructor
        thisFragment = inflater.inflate(R.layout.fragment_withdrawal, container, false);

        // Listen for device token changes
        this.startObservingGlobals();

        // Disable interaction initially while token is being fetched
        if(GlobalValues.getInstance().getDeviceToken() == null) {
            disableInteractionTemporarily();
        } else {
            enableInteraction();
        }

        // Change all caps text to normal capitalization and add onClick listener
        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
        withdrawButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
        withdrawButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                promptConfirmation();
            }
        });

        return thisFragment;

    }

    private void disableInteractionTemporarily() {
        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
        final TextView withdrawTextView = thisFragment.findViewById(R.id.withdrawText);

        withdrawButton.setEnabled(false);
        withdrawTextView.setText(R.string.loadingText);
    }

    private void disableInteraction() {
        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
        final TextView withdrawTextView = thisFragment.findViewById(R.id.withdrawText);

        withdrawButton.setEnabled(false);
        withdrawTextView.setText(R.string.tokenErrorText);
    }

    private void enableInteraction() {
        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
        final TextView withdrawTextView = thisFragment.findViewById(R.id.withdrawText);

        withdrawButton.setEnabled(true);
        withdrawTextView.setText(R.string.withdrawDescriptionText);
    }

    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
    private void startObservingGlobals() {
        GlobalValues.getInstance().addObserver(this);
    }

    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
    @Override
    public void update(Observable observable, Object o) {
        if(observable instanceof GlobalValues) {
            if(o instanceof GlobalValues.ValueKey) {
                if(((GlobalValues.ValueKey) o).getKey() == GlobalValues.ValueName.DEVICE_TOKEN) {
                    if(GlobalValues.getInstance().getDeviceToken() == null) {
                        disableInteraction();
                    } else {
                        enableInteraction();
                    }
                }
            }
        }
    }

    private void promptConfirmation() {
        AlertDialog.Builder builder = new AlertDialog.Builder(Objects.requireNonNull(getContext()));
        builder.setCancelable(true);
        builder.setTitle("WITHDRAWING");
        builder.setMessage("Are you absolutely sure you want to withdraw from the project?");
        builder.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                sendWithdrawalRequest();
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d(TAG, "Cancelled withdrawal!");
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    private void sendWithdrawalRequest() {

        // Initiate progress dialog
        // TODO: find substitute for this deprecated dialog box
        final ProgressDialog progressDialog = ProgressDialog.show(getContext(),
                "Withdrawing",
                "This shouldn't take long");

        // Send withdrawal request to server
        SendWithdrawal sendWithdrawalTask = new SendWithdrawal(new URLEventListener() {
            @Override
            public void onSuccess() {

                progressDialog.dismiss();
                Context context = getContext();

                // Change system preferences to begin in GettingStartedActivity by default
                SharedPreferences prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = prefs.edit();
                editor.putBoolean("needsToRegister", true);
                editor.apply();

                // Start GettingStartedActivity with a success message
                Intent intent = new Intent(context, GettingStartedActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
                Toast.makeText(context.getApplicationContext(), "Successfully withdrawn!", Toast.LENGTH_LONG).show();

            }

            @Override
            public void onFailure(Exception e) {
                progressDialog.dismiss();
                Toast.makeText(getContext(), "Oops! Something went wrong...", Toast.LENGTH_LONG).show();
                Log.e(TAG, "Error occurred while sending withdrawal request to server...");
                e.printStackTrace();
            }
        });

        // Start task
        sendWithdrawalTask.execute(GlobalValues.getInstance().getDeviceToken());

        // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
        /*
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                progressDialog.dismiss();
                if(true) { // Imitate success
                    Context context = getContext();
                    Intent intent = new Intent(context, GettingStartedActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intent);
                    Toast.makeText(context.getApplicationContext(), "Successfully withdrawn!", Toast.LENGTH_LONG).show();
                } else { // Imitate failure
                    Toast.makeText(getContext(), "Oops! Something went wrong...", Toast.LENGTH_LONG).show();
                }
            }
        }, 5000);
        */
        // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)

    }

}
