package cpm.com.gskmtorange.password;

import static com.google.android.gms.location.LocationRequest.Builder.IMPLICIT_MIN_UPDATE_INTERVAL;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.Priority;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cpm.com.gskmtorange.GetterSetter.PD_CONFIGURATION;
import cpm.com.gskmtorange.LoginActivity;
import cpm.com.gskmtorange.MainActivity;
import cpm.com.gskmtorange.R;
import cpm.com.gskmtorange.autoupdate.AutoUpdateActivity;
import cpm.com.gskmtorange.blurlockview.BlurLockView;
import cpm.com.gskmtorange.blurlockview.Password;
import cpm.com.gskmtorange.constant.CommonFunctions;
import cpm.com.gskmtorange.constant.CommonString;
import cpm.com.gskmtorange.constant.CommonUtils;
import cpm.com.gskmtorange.xmlGetterSetter.FailureGetterSetter;
import cpm.com.gskmtorange.xmlGetterSetter.LoginGetterSetter;
import cpm.com.gskmtorange.xmlHandlers.XMLHandlers;

public class MPinActivity extends AppCompatActivity implements BlurLockView.OnPasswordInputListener, BlurLockView.OnLeftButtonClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    BlurLockView blurLockView;
    ImageView imageView1;
    String pin = "";
    boolean IS_PASSWORD_CHECK;
    private SharedPreferences preferences = null;
    private SharedPreferences.Editor editor = null;
    String userId, password, app_ver;
    int eventType;
    LoginGetterSetter lgs = null;
    static int counter = 1;
    //  Trace myTrace;
    private int versionCode;

    private static final int MY_PERMISSIONS_REQUEST_CAMERA = 10;
    private static final int MY_PERMISSIONS_REQUEST_LOCATION = 11;
    private static final int MY_PERMISSIONS_REQUEST_STORAGE_READ = 12;
    private static final int MY_PERMISSIONS_REQUEST_STORAGE_WRITE = 14;

    private static final int PERMISSION_ALL = 99;

    GoogleApiClient mGoogleApiClient;
    private static int UPDATE_INTERVAL = 200; // 5 sec
    private static int FATEST_INTERVAL = 100; // 1 sec
    private static int DISPLACEMENT = 1; // 10 meters
    private static final int REQUEST_LOCATION = 1;
    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
    private Location mLastLocation;
    private LocationRequest mLocationRequest;
    private Context context;

    //New Location Changes
    private FusedLocationProviderClient fusedLocationProviderClient;
    LocationRequest locationRequest;

    double lat = 0.0;
    double lon = 0.0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_mpin);
        context = this;
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        IS_PASSWORD_CHECK = getIntent().getBooleanExtra(CommonString.IS_PASSWORD_CHECK, false);
        imageView1 = (ImageView) findViewById(R.id.image_1);
        blurLockView = (BlurLockView) findViewById(R.id.blurlockview);
        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        editor = preferences.edit();
        //USK
        CommonFunctions.updateLangResources(context, preferences.getString(CommonString.KEY_LANGUAGE, ""));

        try {
            app_ver = String.valueOf(getPackageManager().getPackageInfo(getPackageName(), 0).versionName);

            // login_version.setText("Parinaam Version " + app_ver);
        } catch (PackageManager.NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Set the view that need to be blurred
        blurLockView.setBlurredView(imageView1);

        // Set the password
        if (IS_PASSWORD_CHECK) {
            //preferences = PreferenceManager.getDefaultSharedPreferences(this);
            String mpin = preferences.getString(CommonString.MPIN, null);
            blurLockView.setCorrectPassword(mpin);
            blurLockView.setLeftButton(getString(R.string.forget_mpin));
            blurLockView.setTitle(getString(R.string.pls_enter_four_digit_mpin));
        } else {
            blurLockView.setCorrectPassword("abcd");
            blurLockView.setLeftButton(getString(R.string.set_mpin));
            blurLockView.setTitle(getString(R.string.pls_set_four_digit_mpin));
        }

        blurLockView.setIs_Password_Check_Mode(IS_PASSWORD_CHECK);


        blurLockView.setRightButton(getString(R.string.clear));
        blurLockView.setTypeface(getTypeface());
        blurLockView.setOnLeftButtonClickListener(this);
        blurLockView.setOnPasswordInputListener(this);
        blurLockView.setType(Password.NUMBER, true);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show());
        checkAndRequestPermissions();
    }

    private void checkAndRequestPermissions() {
        int CAMERA = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        int ACCESS_NETWORK_STATE = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE);
        int ACCESS_COARSE_LOCATION = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
        int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        int READ_PHONE_STATE = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
        List<String> listPermissionsNeeded = new ArrayList<>();

        if (CAMERA != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.CAMERA);
        }

        if (ACCESS_NETWORK_STATE != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.ACCESS_NETWORK_STATE);
        }
        if (ACCESS_COARSE_LOCATION != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        }
        if (locationPermission != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }

        if (READ_PHONE_STATE != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
        }

        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), PERMISSION_ALL);
        }

        if (checkPlayServices()) {
            // Building the GoogleApi client
            buildGoogleApiClient();
            createLocationRequest();
        }

        // Create an instance of GoogleAPIClient.
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(context).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.d("", "Permission callback called-------");

        if (checkPlayServices()) {
            // Building the GoogleApi client
            buildGoogleApiClient();
            createLocationRequest();
        }

        // Create an instance of GoogleAPIClient.
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        }
        if (requestCode == PERMISSION_ALL) {
            Map<String, Integer> perms = new HashMap<>();
            // Initialize the map with both permissions
            perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.ACCESS_NETWORK_STATE, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.ACCESS_COARSE_LOCATION, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.READ_PHONE_STATE, PackageManager.PERMISSION_GRANTED);
            // Fill with actual results from user
            if (grantResults.length > 0) {
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);
                // Check for both permissions//
                if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.ACCESS_NETWORK_STATE) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
                    //  imeiNumbers = imei.getDeviceImei();
                    Log.d("", "sms & location services permission granted");
                    // process the normal flow
                    //else any one or both the permissions are not granted
                } else {
                    Log.d("", "Some permissions are not granted ask again ");
                    //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
//                        // shouldShowRequestPermissionRationale will return true
                    //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
                    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_NETWORK_STATE) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {
                        showDialogOK("Location,Photos,media,file,manage phone calls and Camera Services Permission required for this app", (dialog, which) -> {
                            switch (which) {
                                case DialogInterface.BUTTON_POSITIVE:
                                    checkAndRequestPermissions();
                                    break;
                                case DialogInterface.BUTTON_NEGATIVE:
                                    // proceed with logic by disabling the related features or quit the app.
                                    Intent startMain = new Intent(Intent.ACTION_MAIN);
                                    startMain.addCategory(Intent.CATEGORY_HOME);
                                    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(startMain);
                                    break;
                            }
                        });
                    }
                }
            }
        }

    }

    private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
        new androidx.appcompat.app.AlertDialog.Builder(this).setMessage(message).setPositiveButton("OK", okListener).setNegativeButton("Cancel", okListener).create().show();
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();

        }
        checkgpsEnableDevice();

        locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 100000).setWaitForAccurateLocation(false).setMinUpdateIntervalMillis(IMPLICIT_MIN_UPDATE_INTERVAL).setMaxUpdateDelayMillis(1000).build();


        LocationCallback locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(@NonNull LocationResult locationResult) {
                //Showing the latitude, longitude and accuracy on the home screen.
                for (Location location : locationResult.getLocations()) {
                    lat = location.getLatitude();
                    lon = location.getLongitude();
                }
            }
        };
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MPinActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 1);
            ActivityCompat.requestPermissions(MPinActivity.this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION}, 2);
        }
        fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());

    }

    private Password getPasswordType() {
        if ("PASSWORD_NUMBER".equals(getIntent().getStringExtra("PASSWORD_TYPE")))
            return Password.NUMBER;
        else if ("PASSWORD_NUMBER".equals(getIntent().getStringExtra("PASSWORD_TYPE")))
            return Password.TEXT;
        return Password.NUMBER;
    }

    private Typeface getTypeface() {
        if ("SAN".equals(getIntent().getStringExtra("TYPEFACE")))
            return Typeface.createFromAsset(getAssets(), "fonts/San Francisco Regular.ttf");
        else if ("DEFAULT".equals(getIntent().getStringExtra("TYPEFACE"))) return Typeface.DEFAULT;
        return Typeface.DEFAULT;
    }

    @Override
    public void correct(String inputPassword) {

        if (IS_PASSWORD_CHECK) {
            userId = preferences.getString(CommonString.KEY_USERNAME, "");
            password = preferences.getString(CommonString.KEY_PASSWORD, "");

            new AuthenticateTask().execute();
        } else {
            Toast.makeText(this, "Correct", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void incorrect(String inputPassword) {

        if (IS_PASSWORD_CHECK) {

            int incorrect_times = blurLockView.getIncorrectInputTimes();
            if (++incorrect_times >= 3) {
                /*Toast.makeText(this,
                        R.string.error_incorrect_password,
                        Toast.LENGTH_SHORT).show();*/

                Snackbar snackbar = Snackbar.make(blurLockView, R.string.incorrect_mpin_limit_reached, Snackbar.LENGTH_INDEFINITE);
                View view = snackbar.getView();
                snackbar.setAction(R.string.reset, v -> {
                    editor.putString(CommonString.MPIN, null);
                    editor.commit();
                    Intent in = new Intent(context, LoginActivity.class);
                    startActivity(in);
                    finish();
                });
                snackbar.setActionTextColor(Color.GREEN);
                snackbar.show();
            } else {
                int count = 3 - incorrect_times;
                String attemt_str;
                if (count == 1) {
                    attemt_str = ". Attempt left - " + count;
                } else {
                    attemt_str = ". Attempts left - " + count;
                }

                String msg = getString(R.string.error_incorrect_pin) + attemt_str;
                Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
            }
        } else {
            pin = inputPassword;
        }

    }

    @Override
    public void input(String inputPassword) {
        pin = inputPassword;
    }

    @Override
    public void clear(String remainingPassword) {
        pin = remainingPassword;
    }


    @Override
    public void onClick() {

        if (IS_PASSWORD_CHECK) {

            Snackbar snackbar = Snackbar.make(blurLockView, R.string.need_to_reset_mpin, Snackbar.LENGTH_INDEFINITE);
            View view = snackbar.getView();
                /*TextView tv = (TextView)view.findViewById(android.support.design.R.id.snackbar_text);
                tv.setTextColor(Color.RED);*/
            snackbar.setAction(R.string.reset, new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    editor.putString(CommonString.MPIN, null);

                    editor.commit();

                    finish();
                    Intent in = new Intent(context, LoginActivity.class);
                    startActivity(in);

                }
            });
            snackbar.setActionTextColor(Color.GREEN);
            snackbar.show();
        } else {
            if (pin.length() == 4) {

                editor.putString(CommonString.MPIN, pin);

                editor.commit();

                Intent in = new Intent(context, MainActivity.class);

                startActivity(in);

                finish();
            } else {
                Toast.makeText(context, "Please fill four digit MPin", Toast.LENGTH_SHORT).show();
            }
        }

    }

    private class AuthenticateTask extends AsyncTask<Void, Void, String> {
        private Dialog dialog;

        @Override
        protected void onPreExecute() {

            super.onPreExecute();

            dialog = new Dialog(MPinActivity.this);
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
            dialog.setContentView(R.layout.progress_layout);

            Window window = dialog.getWindow();
            WindowManager.LayoutParams wlp = window.getAttributes();

            wlp.gravity = Gravity.CENTER;
            //wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
            window.setAttributes(wlp);

            dialog.setCancelable(false);

            if (!dialog.isShowing()) {
                dialog.show();
            }
        }

        @Override
        protected String doInBackground(Void... params) {
            try {
                versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
                String userauth_xml = "[DATA]" + "[USER_DATA][USER_ID]" + userId + "[/USER_ID]" + "[PASSWORD]" + password + "[/PASSWORD]" + "[IN_TIME]" + CommonFunctions.getCurrentTimeWithLanguage(context) + "[/IN_TIME]" + "[LATITUDE]" + lat + "[/LATITUDE]" + "[LONGITUDE]" + lon + "[/LONGITUDE]" + "[APP_VERSION]" + app_ver + "[/APP_VERSION]" + "[ATT_MODE]OnLine[/ATT_MODE]" + "[NETWORK_STATUS]" + "LoginStatus" + "[/NETWORK_STATUS]" + "[/USER_DATA][/DATA]";
                SoapObject request = new SoapObject(CommonString.NAMESPACE, CommonString.METHOD_LOGIN);
                request.addProperty("onXML", userauth_xml);
                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                envelope.dotNet = true;
                envelope.setOutputSoapObject(request);
                HttpTransportSE androidHttpTransport = new HttpTransportSE(CommonString.URL);
                androidHttpTransport.call(CommonString.SOAP_ACTION_LOGIN, envelope);
                Object result = (Object) envelope.getResponse();

                if (result.toString().equalsIgnoreCase(CommonString.KEY_FAILURE)) {
                    runOnUiThread(() -> showAlert(CommonString.MESSAGE_FAILURE));
                } else if (result.toString().equalsIgnoreCase(CommonString.KEY_FALSE)) {
                    runOnUiThread(() -> showAlert(CommonString.MESSAGE_FALSE));
                } else if (result.toString().equalsIgnoreCase(CommonString.KEY_CHANGED)) {
                    runOnUiThread(() -> showAlert(CommonString.MESSAGE_CHANGED));
                } else {
                    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                    factory.setNamespaceAware(true);
                    XmlPullParser xpp = factory.newPullParser();
                    xpp.setInput(new StringReader(result.toString()));
                    xpp.next();
                    eventType = xpp.getEventType();
                    final FailureGetterSetter failureGetterSetter = XMLHandlers.failureXMLHandler(xpp, eventType);
                    if (failureGetterSetter.getStatus().equalsIgnoreCase(CommonString.KEY_FAILURE)) {
                        runOnUiThread(() -> {
                            // TODO Auto-generated method stub
                            showAlert(CommonString.METHOD_LOGIN + failureGetterSetter.getErrorMsg());
                        });
                    } else {

                        try {
                            // For String source
                            xpp.setInput(new StringReader(result.toString()));
                            xpp.next();
                            eventType = xpp.getEventType();
                            lgs = XMLHandlers.loginXMLHandler(xpp, eventType);
                            //PD_CONFIGURATION
                            request = new SoapObject(CommonString.NAMESPACE, CommonString.METHOD_NAME_UNIVERSAL_DOWNLOAD);
                            request.addProperty("UserName", userId);
                            request.addProperty("Type", "PD_CONFIGURATION");
                            request.addProperty("cultureid", "1");
                            envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                            envelope.dotNet = true;
                            envelope.setOutputSoapObject(request);
                            androidHttpTransport = new HttpTransportSE(CommonString.URL);
                            androidHttpTransport.call(CommonString.SOAP_ACTION_UNIVERSAL, envelope);
                            result = envelope.getResponse();
                            xpp.setInput(new StringReader(result.toString()));
                            xpp.next();
                            eventType = xpp.getEventType();
                            PD_CONFIGURATION pdConfiguration = XMLHandlers.PDConfigXMLHandler(xpp);
                            Log.e("PD_CONFIGURATION_RESULT", result.toString());
                            // PUT IN PREFERENCES
                            if (pdConfiguration.getPROJECT_ID() != null && !pdConfiguration.getPROJECT_ID().isEmpty()) {
                                editor.putString(CommonString.KEY_PD_PROJECT_Id, pdConfiguration.getPROJECT_ID().get(0));
                                editor.putString(CommonString.KEY_PD_USER_Id, pdConfiguration.getUSER_ID().get(0));
                            } else {
                                return CommonString.KEY_FAILURE;
                            }

                        } catch (XmlPullParserException | IOException e) {
                            e.fillInStackTrace();
                        }
                        // PUT IN PREFERENCES
                        editor.putString(CommonString.KEY_USERNAME, userId);
                        editor.putString(CommonString.KEY_PASSWORD, password);
                        editor.putString(CommonString.KEY_VERSION, lgs.getAPP_VERSION());
                        editor.putString(CommonString.KEY_PATH, lgs.getAPP_PATH());
                        editor.putString(CommonString.KEY_DATE, lgs.getCURRENTDATE());
                        editor.putString(CommonString.KEY_COUNTRY_ID, lgs.getCOUNTRY_ID());
                        editor.commit();
                        setDataFromSharedPreferences(lgs);
                        Bundle bundle = new Bundle();
                        bundle.putString(FirebaseAnalytics.Param.ITEM_ID, userId);
                        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, CommonString.KEY_LOGIN_DATA);
                        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "Data");
                        bundle.putString(CommonString.KEY_LANGUAGE, preferences.getString(CommonString.KEY_LANGUAGE, ""));
                        return CommonString.KEY_SUCCESS;
                    }
                }

                return "";

            } catch (MalformedURLException e) {
                runOnUiThread(() -> showAlert(CommonString.MESSAGE_EXCEPTION));
            } catch (IOException e) {
                counter++;
                runOnUiThread(() -> {
                    // TODO Auto-generated method stub
                    if (counter < 3) {
                        new AuthenticateTask().execute();
                    } else {
                        showAlert(getString(R.string.nonetwork));
                        counter = 1;
                    }
                });
            } catch (Exception e) {
                runOnUiThread(() -> showAlert(CommonString.MESSAGE_EXCEPTION));
            }

            return "";
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (result.equalsIgnoreCase(CommonString.KEY_SUCCESS)) {
                initializePDSDK(context, preferences.getString(CommonString.KEY_PD_PROJECT_Id, ""), preferences.getString(CommonString.KEY_PD_USER_Id, "").isEmpty() ? userId : preferences.getString(CommonString.KEY_PD_USER_Id, ""));
                if (preferences.getString(CommonString.KEY_VERSION, "").equals(Integer.toString(versionCode))) {
                    setLanguageDataFromSharedPreferences();
                    Intent in = new Intent(context, MainActivity.class);
                    in.putExtra(CommonString.IS_PASSWORD_CHECK, false);
                    startActivity(in);
                    finish();
                } else {
                    Intent intent = new Intent(getBaseContext(), AutoUpdateActivity.class);
                    intent.putExtra(CommonString.KEY_PATH, preferences.getString(CommonString.KEY_PATH, ""));
                    startActivity(intent);
                    finish();
                }
            }

            dialog.dismiss();
        }

    }

    ArrayList<String> language, culture_id, notice_url;
    LoginGetterSetter login_data;

    private void setLanguageDataFromSharedPreferences() {
        Gson gson = new Gson();
        login_data = new LoginGetterSetter();
        String jsonPreferences = preferences.getString(CommonString.KEY_LOOGIN_PREF, "");
        Type type = new TypeToken<LoginGetterSetter>() {
        }.getType();
        login_data = gson.fromJson(jsonPreferences, type);
        language = login_data.getCULTURE_NAME();
        culture_id = login_data.getCULTURE_ID();
        notice_url = login_data.getNOTICE_URL();
        String lang = preferences.getString(CommonString.KEY_LANGUAGE, "");
        if (!language.isEmpty()) {
            for (int i = 0; i < language.size(); i++) {
                if (lang.equals(language.get(i))) {
                    editor.putString(CommonString.KEY_LANGUAGE, language.get(i));
                    editor.putString(CommonString.KEY_CULTURE_ID, culture_id.get(i));
                    editor.putString(CommonString.KEY_NOTICE_BOARD_LINK, notice_url.get(i));
                    editor.commit();
                    break;
                }
            }
        }
    }

    public void showAlert(String str) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MPinActivity.this);
        builder.setTitle("Parinaam");
        builder.setMessage(str).setCancelable(false).setPositiveButton("OK", (dialog, id) -> {
            finish();
        });
        AlertDialog alert = builder.create();
        alert.show();
    }


    private void setDataFromSharedPreferences(LoginGetterSetter lgs) {
        Gson gson = new Gson();
        String jsonCurProduct = gson.toJson(lgs);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(CommonString.KEY_LOOGIN_PREF, jsonCurProduct);
        editor.apply();
    }

    //permission and location related
    void checkAppPermission(String permission, int requestCode) {
        boolean permission_flag = false;
        // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(MPinActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {

            // Permission is not granted
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(MPinActivity.this, permission)) {
                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
                showOnPermissiondenied(Manifest.permission.CAMERA, MY_PERMISSIONS_REQUEST_CAMERA, 1);
            } else {
                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(MPinActivity.this, new String[]{permission}, requestCode);

                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        } else {
            // Permission has already been granted
            if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA) {
                checkAppPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, MY_PERMISSIONS_REQUEST_STORAGE_WRITE);
            } else if (requestCode == MY_PERMISSIONS_REQUEST_STORAGE_WRITE) {
                checkAppPermission(Manifest.permission.READ_EXTERNAL_STORAGE, MY_PERMISSIONS_REQUEST_STORAGE_READ);
            } else if (requestCode == MY_PERMISSIONS_REQUEST_STORAGE_READ) {
                checkAppPermission(Manifest.permission.ACCESS_FINE_LOCATION, MY_PERMISSIONS_REQUEST_LOCATION);
            } else {

                // Create a Folder for Images

                File file = new File(Environment.getExternalStorageDirectory(), ".GSK_MT_ORANGE_IMAGES");
                if (!file.isDirectory()) {
                    file.mkdir();
                }
                File file_planogram = new File(Environment.getExternalStorageDirectory(), "GSK_MT_ORANGE_Planogram_Images");
                if (!file_planogram.isDirectory()) {
                    file_planogram.mkdir();
                }

                if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }

                if (checkPlayServices()) {
                    // Building the GoogleApi client
                    buildGoogleApiClient();

                    createLocationRequest();
                }

                // Create an instance of GoogleAPIClient.
                if (mGoogleApiClient == null) {
                    mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
                }

                //attemptLogin();
            }

        }
    }

    void showOnPermissiondenied(final String permissionsRequired, final int request_code, final int check) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MPinActivity.this);
        builder.setTitle("Need Multiple Permissions");
        builder.setMessage("This app needs Camera, Storage and Location permissions.");
        builder.setPositiveButton("Grant", (dialog, which) -> {
            dialog.cancel();
            if (check == 0) {
                checkAppPermission(permissionsRequired, request_code);
            } else {
                ActivityCompat.requestPermissions(MPinActivity.this, new String[]{permissionsRequired}, request_code);
            }
        });

        builder.show();
    }

    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Toast.makeText(context, getResources().getString(R.string.notsuppoted), Toast.LENGTH_LONG).show();
                finish();
            }
            return false;
        }
        return true;
    }

    protected synchronized void buildGoogleApiClient() {
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(context).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        }
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FATEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }

    }


    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

    protected void onStart() {
        super.onStart();
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

    private boolean checkgpsEnableDevice() {
        boolean flag = true;
        if (!hasGPSDevice(context)) {
            Toast.makeText(context, "Gps not Supported", Toast.LENGTH_SHORT).show();
        }
        final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(context)) {
            enableLoc();
            flag = false;
        } else if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(context)) {
            flag = true;
        }
        return flag;
    }

    private boolean hasGPSDevice(Context context) {
        final LocationManager mgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        if (mgr == null) return false;
        final List<String> providers = mgr.getAllProviders();
        if (providers == null) return false;
        return providers.contains(LocationManager.GPS_PROVIDER);
    }

    private void enableLoc() {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);
        if (mGoogleApiClient != null) {
            PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult((Activity) context, REQUEST_LOCATION);
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            }
                            break;
                    }
                }
            });
        }
    }

    private void initializePDSDK(Context context, String projectId, String _userId) {
        CommonUtils.INSTANCE.initializePDSDK(context, projectId, _userId);
    }
}
