package com.datarecovery.master.utils.xfile;

import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.UriPermission;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.storage.StorageVolume;
import android.provider.DocumentsContract;

import androidx.activity.ComponentActivity;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.datarecovery.master.utils.ActivityForResultUtil;
import com.datarecovery.master.utils.BoxingUtil;
import com.datarecovery.master.utils.PermissionUtil;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 这个权限申请写的不好，看怎么根据业务需求优化
 */
public class XFilePermission {

    private static final String[] EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    private static final int REQUEST_CODE_EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q = 11223;
    private static final int REQUEST_CODE_SAF_PERMISSIONS = 11224;
    private static final String documentsuiPkg = "com.google.android.documentsui";

    public static boolean hasAndroidDataPermission(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            for (String permission : EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q) {
                if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
        PackageManager packageManager = context.getPackageManager();
        try {
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(documentsuiPkg, PackageManager.MATCH_UNINSTALLED_PACKAGES);
            if (applicationInfo.targetSdkVersion >= 34) {
                return false;
            }
        } catch (PackageManager.NameNotFoundException ignore) {
        }
        List<StorageVolume> storageVolumes = XStorageManager.getReadableStorageVolumes(context);
        for (StorageVolume storageVolume : storageVolumes) {
            Uri treeUri = StorageVolumeUtil.getTreeUri(storageVolume);
            XSAFFile xFile = new XSAFFile(context, treeUri, Arrays.asList("Android", "data"));
            if (!hasPermission(context, xFile)) {
                return false;
            }
        }
        return true;
    }

    private static boolean hasPermission(Context context, XSAFFile xFile) {
        ContentResolver contentResolver = context.getContentResolver();
        List<UriPermission> persistedUriPermissions = contentResolver.getPersistedUriPermissions();
        for (UriPermission persistedUriPermission : persistedUriPermissions) {
            if (!persistedUriPermission.isReadPermission() || !persistedUriPermission.isWritePermission()) {
                continue;
            }
            Uri uri = persistedUriPermission.getUri();
            if (uri == null) {
                continue;
            }
            Uri pathUri = xFile.getPathUri();
            if (uri.toString().contains(pathUri.toString())) {
                return true;
            }
        }
        return false;
    }

    public static void requestAndroidDataPermission(ComponentActivity activity, PermissionCallback callback) {
        if (activity == null) {
            throw new RuntimeException("activity is null");
        }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            new ActivityForResultUtil<String[], Map<String, Boolean>>().startActivityForResult(activity, new ActivityResultContracts.RequestMultiplePermissions(), EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q, result -> {
                boolean permission = false;
                for (Map.Entry<String, Boolean> entry : result.entrySet()) {
                    Boolean value = entry.getValue();
                    if (BoxingUtil.boxing(value)) {
                        permission = true;
                        break;
                    }
                }
                if (permission) {
                    if (callback != null) callback.onPermissionGranted();
                } else {
                    if (callback != null) callback.onPermissionDenied();
                }
            });
        } else {
            Intent grantIntentSDMOg = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
            grantIntentSDMOg.putExtra("android.content.extra.SHOW_ADVANCED", true);
            List<StorageVolume> storageVolumes = XStorageManager.getReadableStorageVolumes(activity);
            for (StorageVolume storageVolume : storageVolumes) {
                Uri treeUri = StorageVolumeUtil.getTreeUri(storageVolume);
                XSAFFile xFile = new XSAFFile(activity, treeUri, Arrays.asList("Android", "data"));
                if (!hasPermission(activity, xFile)) {
                    grantIntentSDMOg.putExtra(DocumentsContract.EXTRA_INITIAL_URI, xFile.getDocumentUri());
                    new ActivityForResultUtil<Intent, ActivityResult>().startActivityForResult(activity, new ActivityResultContracts.StartActivityForResult(), grantIntentSDMOg, result -> {
                        Intent data = result.getData();
                        Uri uri = null;
                        if (result.getResultCode() == Activity.RESULT_OK && data != null && (uri = data.getData()) != null) {
                            activity.getContentResolver().takePersistableUriPermission(uri,
                                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                            if (callback != null) callback.onPermissionGranted();
                        } else {
                            if (callback != null) callback.onPermissionDenied();
                        }
                    });
                }
            }
        }
    }

    public static boolean onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE_SAF_PERMISSIONS) {
            if (resultCode == Activity.RESULT_OK) {
                Uri treeUri = data.getData();
                if (treeUri == null) {
                    return false;
                }
                activity.getContentResolver().takePersistableUriPermission(treeUri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                return true;
            }
            return false;
        }
        return false;
    }

    public static boolean onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == REQUEST_CODE_EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q) {
            for (int grantResult : grantResults) {
                if (grantResult != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }


    public interface PermissionCallback {
        void onPermissionGranted();

        void onPermissionDenied();
    }
}