package com.retrytech.strangerapp.activity;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowInsets;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.PickVisualMediaRequest;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.databinding.DataBindingUtil;

import com.bumptech.glide.Glide;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.Task;
import com.gun0912.tedpermission.PermissionListener;
import com.retrytech.strangerapp.R;
import com.retrytech.strangerapp.databinding.ActivityEditProfileBinding;
import com.retrytech.strangerapp.modal.User;
import com.retrytech.strangerapp.retrofit.Const;
import com.retrytech.strangerapp.retrofit.RetrofitClient;
import com.retrytech.strangerapp.utils.Compressor;
import com.retrytech.strangerapp.utils.SessionManager;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

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

public class EditProfileActivity extends AppCompatActivity {

    private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 111;
    private static final int RESULT_LOAD_IMAGE = 100;
    ActivityEditProfileBinding binding;
    SessionManager sessionManager;
    Double myLat;
    Double myLong;
    HashMap<String, RequestBody> hashMap = new HashMap<>();
    private GoogleApiClient googleApiClient;
    private boolean locationPermissionGranted = false;
    private Dialog dialog;
    private File compressFile;
    private MultipartBody.Part body;
    private ActivityResultLauncher<PickVisualMediaRequest> pickMedia;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View decorView = getWindow().getDecorView();
        decorView.setOnApplyWindowInsetsListener((v, insets) -> {
            WindowInsets defaultInsets = v.onApplyWindowInsets(insets);
            return defaultInsets.replaceSystemWindowInsets(
                    defaultInsets.getSystemWindowInsetLeft(),
                    0,
                    defaultInsets.getSystemWindowInsetRight(),
                    defaultInsets.getSystemWindowInsetBottom());
        });
        ViewCompat.requestApplyInsets(decorView);
        getWindow().setStatusBarColor(ContextCompat.getColor(this, android.R.color.transparent));
        binding = DataBindingUtil.setContentView(this, R.layout.activity_edit_profile);
        sessionManager = new SessionManager(this);

        dialog = new Dialog(this);
        View dialogueView = LayoutInflater.from(this).inflate(R.layout.item_loader, null, false);

        dialog.setContentView(dialogueView);
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, android.R.color.transparent)));
        binding.btnDone.setOnClickListener(view -> startActivity(new Intent(EditProfileActivity.this, MainActivity.class)));
        binding.etFullname.setText(sessionManager.getUser().getData().getFullname());
        binding.tvLocation.setText(sessionManager.getUser().getData().getLocation());
        Glide.with(this)
                .load(Const.ITEM_URL + sessionManager.getUser().getData().getImage())
                .circleCrop()
                .into(binding.imgProfile);


        binding.tvLocation.setOnClickListener(view -> {
            dialog.show();
            getLocationPermission();
        });
        binding.imgBack.setOnClickListener(v -> onBackPressed());
        binding.btnDone.setOnClickListener(view -> {
            if (binding.etFullname.getText().toString().isEmpty()) {
                Toast.makeText(this, "Please fill your full name", Toast.LENGTH_SHORT).show();
            } else {
                hashMap.put("fullname", toRequestBody(binding.etFullname.getText().toString()));
                if (!binding.tvLocation.getText().toString().isEmpty()) {
                    hashMap.put("location", toRequestBody(binding.tvLocation.getText().toString()));
                }
                if (compressFile != null) {
                    RequestBody requestFile =
                            RequestBody.create(compressFile, MediaType.parse("multipart/form-data"));
                    body = MultipartBody.Part.createFormData("image", compressFile.getName(), requestFile);
                }

                callApiForEditUser();

            }
        });


        PermissionListener permissionlistener = new PermissionListener() {
            @Override
            public void onPermissionGranted() {
                Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(i, RESULT_LOAD_IMAGE);
            }

            @Override
            public void onPermissionDenied(List<String> deniedPermissions) {
                Toast.makeText(EditProfileActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
            }
        };
        pickMedia = registerForActivityResult(
                new ActivityResultContracts.PickVisualMedia(),
                uri -> {
                    if (uri != null) {
                        String[] filePathColumn = {"_data"};
                        Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
                        cursor.moveToFirst();
                        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                        String picturePath = cursor.getString(columnIndex);
                        cursor.close();
                        Glide.with(this)
                                .load(new File(picturePath))
                                .circleCrop()
                                .into(binding.imgProfile);
                        File imgFile = new File(picturePath);
                        compressFile = Compressor.getDefault(this).compressToFile(imgFile);
                        Log.d("PhotoPicker", "Selected URI: " + uri);
                        // Use the selected image or video URI here
                    } else {
                        Log.d("PhotoPicker", "No media selected");
                    }
                }
        );

        // Launch picker for images and videos
        binding.imgProfile.setOnClickListener(v -> {
            pickMedia.launch(new PickVisualMediaRequest.Builder()
                    .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE)
                    .build());

        });
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
//            binding.imgProfile.setOnClickListener(view -> TedPermission.create()
//                    .setPermissionListener(permissionlistener)
//                    .setDeniedMessage("If you reject permission,you can not download the images\n\nPlease turn on permissions at [Setting] > [Permission]")
//                    .setPermissions(Manifest.permission.READ_MEDIA_IMAGES)
//                    .check());
//        } else {
//            binding.imgProfile.setOnClickListener(view -> TedPermission.create()
//                    .setPermissionListener(permissionlistener)
//                    .setDeniedMessage("If you reject permission,you can not download the images\n\nPlease turn on permissions at [Setting] > [Permission]")
//                    .setPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
//                    .check());
//        }

    }

    public RequestBody toRequestBody(String value) {
        return RequestBody.create(value, MediaType.parse("text/plain"));
    }

    private void callApiForEditUser() {
        dialog.show();
        hashMap.put("id", toRequestBody(String.valueOf(sessionManager.getUser().getData().getId())));

        Call<User> call = RetrofitClient.getService().editUser(Const.API_KEY, hashMap, body);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if (response.body() != null) {
                    User user = response.body();

                    if (user.getData() != null) {
                        Toast.makeText(EditProfileActivity.this, "Edit Profile Successful", Toast.LENGTH_SHORT).show();
                        sessionManager.saveUser(user);
                        dialog.dismiss();
                        startActivity(new Intent(EditProfileActivity.this, MainActivity.class));
                        finishAffinity();
                    }

                }
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
//
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 1000 && resultCode == RESULT_OK) {
            locationPermissionGranted = true;
            getDeviceLocation();
        } else {
            dialog.dismiss();
        }

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = {"_data"};
            Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
            Glide.with(this)
                    .load(new File(picturePath))
                    .circleCrop()
                    .into(binding.imgProfile);
            File imgFile = new File(picturePath);
            compressFile = Compressor.getDefault(this).compressToFile(imgFile);


        }
    }

    private void getLocationPermission() {
        if (ContextCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {

            initGps();
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION) {
            Log.d("TAG", "onRequestPermissionsResult: granted");
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initGps();
            } else {
                Log.d("TAG", "onRequestPermissionsResult: failedd");
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                alertDialogBuilder.setCancelable(false);
                alertDialogBuilder.setMessage("For using this app Location Permission is required");
                alertDialogBuilder.setPositiveButton("Open AppSettings", (dialog, which) -> startActivity(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                        Uri.fromParts("package", getPackageName(), null))));
                alertDialogBuilder.create();
                AlertDialog alert11 = alertDialogBuilder.create();
                alert11.show();
            }
        }
    }


    private void initGps() {
        if (googleApiClient == null) {

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30000);
            locationRequest.setFastestInterval(5000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
            builder.setAlwaysShow(true); // this is the key ingredient
            Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
            result.addOnCompleteListener(task -> {
                try {
                    LocationSettingsResponse response = task.getResult(ApiException.class);

                    Log.i("TAG", "initGps: " + response);
                    locationPermissionGranted = true;
                    getDeviceLocation();
                    // All location settings are satisfied. The client can initialize location
                    // requests here.
                } catch (ApiException exception) {
                    Log.v(" Failed ", String.valueOf(exception.getStatusCode()));

                    switch (exception.getStatusCode()) {

                        case 6:
                            ResolvableApiException resolvable = (ResolvableApiException) exception;
                            try {
                                resolvable.startResolutionForResult(this, 1000);
                            } catch (IntentSender.SendIntentException e) {
                                e.printStackTrace();
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            break;

                        default:
                    }
                }
            });
        }
    }

    private void getDeviceLocation() {
        /*
         * Get the best and most recent location of the device, which may be null in rare
         * cases when a location is not available.
         */
        try {
            if (locationPermissionGranted) {
                LocationManager locationManager = (LocationManager)
                        getSystemService(Context.LOCATION_SERVICE);
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, new LocationListener() {
                            @Override
                            public void onLocationChanged(Location location) {
                                if (location != null) {
                                    Log.d("TAG", "onLocationChanged: " + location.getLatitude());

                                    myLat = location.getLatitude();
                                    myLong = location.getLongitude();

                                    Geocoder geocoder = new Geocoder(EditProfileActivity.this, Locale.getDefault());
                                    List<Address> addresses = null;
                                    try {
                                        addresses = geocoder.getFromLocation(myLat, myLong, 1);
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                    String cityName = addresses.get(0).getLocality();
                                    String countryName = addresses.get(0).getCountryName();

                                    binding.tvLocation.setText(cityName + ", " + countryName);
                                    dialog.dismiss();
                                }
                            }

                            @Override
                            public void onProviderEnabled(@NonNull String provider) {
//
                            }

                            @Override
                            public void onProviderDisabled(@NonNull String provider) {
//
                            }

                            @Override
                            public void onStatusChanged(String provider, int status, Bundle extras) {
//
                            }
                        }

                );
            } else {
                Toast.makeText(this, "Can't find your location", Toast.LENGTH_SHORT).show();
            }

        } catch (SecurityException e) {
            Log.e("Exception: %s", e.getMessage(), e);
        }

    }
}