package de.sebse.fuplanner.services.GoogleAuth;

import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.FragmentActivity;

import static android.app.Activity.RESULT_OK;

/**
 * Created by Sebastian on 06.11.2017.
 */

public class GoogleAuth {
    // https://developers.google.com/identity/smartlock-passwords/android/retrieve-credentials

    private static final String TAG = "GoogleAuth";
    private final FragmentActivity activity;
    private GoogleApiClient mCredentialsClient;

    public GoogleAuth(FragmentActivity activity) {
        this.activity = activity;
    }

    public void connect(final ConnectedListener listener) {
        if (!this.isAvailable()) {
            Log.d(TAG, "STATUS: Google auth not available!");
            listener.connected();
            return;
        }
        this.mCredentialsClient = getClient(new GoogleApiClient.ConnectionCallbacks() {
            @Override
            public void onConnected(@Nullable Bundle bundle) {
                listener.connected();
            }

            @Override
            public void onConnectionSuspended(int i) {
            }
        }, new GoogleApiClient.OnConnectionFailedListener() {
            @Override
            public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

            }
        });
    }




    public void getLoginState(final CredentialsListener credentialsListener) {
        if (!this.isAvailable()) {
            Log.d(TAG, "STATUS: Google auth not available!");
            credentialsListener.onCredentials(null);
            return;
        }
        CredentialRequest mCredentialRequest = new CredentialRequest.Builder()
                .setPasswordLoginSupported(true)
                .build();

        Auth.CredentialsApi.request(this.mCredentialsClient, mCredentialRequest).setResultCallback(
            new ResultCallback<CredentialRequestResult>() {
                @Override
                public void onResult(@NonNull CredentialRequestResult credentialRequestResult) {
                    if (credentialRequestResult.getStatus().isSuccess()) {
                        // See "Handle successful credential requests"
                        Credential credential = credentialRequestResult.getCredential();
                        credentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
                    } else {
                        // See "Handle unsuccessful and incomplete credential requests"
                        credentialsListener.onCredentials(null);
                    }
                }
            }
        );
    }

    public void setLoginState(String username, String password) {
        if (!this.isAvailable()) {
            Log.d(TAG, "STATUS: Google auth not available!");
            Toast.makeText(activity, "Google auth not available!", Toast.LENGTH_SHORT).show();
            return;
        }
        Credential credential = new Credential.Builder(username)
            .setPassword(password)
            .build();




        Auth.CredentialsApi.save(mCredentialsClient, credential).setResultCallback(
            new ResultCallback<Status>() {
                @Override
                public void onResult(@NonNull Status status) {
                    if (status.isSuccess()) {
                        Log.d(TAG, "SAVE: OK");
                        Toast.makeText(activity, "Credentials saved", Toast.LENGTH_SHORT).show();
                    } else {
                        if (status.hasResolution()) {
                            // Try to resolve the save request. This will prompt the user if
                            // the credential is new.
                            try {
                                status.startResolutionForResult(activity, RequestCode.RC_SAVE);
                            } catch (IntentSender.SendIntentException e) {
                                // Could not resolve the request
                                Log.e(TAG, "STATUS: Failed to send resolution.", e);
                                Toast.makeText(activity, "Save failed", Toast.LENGTH_SHORT).show();
                            }
                        } else {
                            // Request has no resolution
                            Toast.makeText(activity, "Save failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            }
        );
    }

    public void deleteLoginState(String username, String password) {
        if (!this.isAvailable()) {
            Log.d(TAG, "STATUS: Google auth not available!");
            return;
        }
        Credential credential = new Credential.Builder(username)
            .setPassword(password)
            .build();
        Auth.CredentialsApi.delete(mCredentialsClient, credential).setResultCallback(
            new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        // Credential was deleted successfully
                    }
                }
            }
        );
    }


    private boolean isAvailable() {
        return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this.activity) == ConnectionResult.SUCCESS;
    }

    private GoogleApiClient getClient(@NonNull GoogleApiClient.ConnectionCallbacks connectionCallbacks, @NonNull GoogleApiClient.OnConnectionFailedListener failedListener) {
        return new GoogleApiClient.Builder(this.activity)
                .addConnectionCallbacks(connectionCallbacks)
                .enableAutoManage(this.activity, failedListener)
                .addApi(Auth.CREDENTIALS_API)
                .build();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RequestCode.RC_SAVE) {
            if (resultCode == RESULT_OK) {
                Log.d(TAG, "SAVE: OK");
                Toast.makeText(activity, "Credentials saved", Toast.LENGTH_SHORT).show();
            } else {
                Log.e(TAG, "SAVE: Canceled by user");
            }
        }
    }

}
