package com.datarecovery.master.utils;

import android.os.Build;
import android.text.TextUtils;
import android.view.Gravity;

import androidx.activity.ComponentActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

import com.atmob.common.runtime.ContextUtil;
import com.datarecovery.master.R;
import com.datarecovery.master.data.repositories.AccountRepository;
import com.datarecovery.master.dialog.PermissionDialog;
import com.datarecovery.master.module.login.LoginActivity;
import com.datarecovery.master.utils.xfile.XFilePermission;

import atmob.reactivex.rxjava3.annotations.NonNull;
import atmob.reactivex.rxjava3.core.Single;
import atmob.reactivex.rxjava3.core.SingleObserver;
import atmob.reactivex.rxjava3.core.SingleSource;
import atmob.reactivex.rxjava3.disposables.Disposable;
import atmob.reactivex.rxjava3.functions.Function;
import atmob.rxjava.utils.RxJavaUtil;

public class FilePermissionHelper {

    Disposable disposable;

    public void requestDataFilePermission(ComponentActivity activity, String reportId, NextStepCallback stepCallback) {
        Single.just(Build.VERSION.SDK_INT)
                .flatMap(sdkInt -> {
                    if (TextUtils.isEmpty(AccountRepository.token)) {
                        return (SingleSource<Integer>) observer -> activity.runOnUiThread(() -> {
                            PermissionDialog loginDialog = new PermissionDialog(activity);
                            loginDialog.setDialogContent(R.string.dialog_no_login)
                                    .setDialogTitle(R.string.dialog_no_login_title)
                                    .setOnDialogClickListener(new PermissionDialog.OnDialogClickListener() {
                                        @Override
                                        public void onClickSure() {
                                            LoginActivity.start(activity, reportId);
                                            activity.getLifecycle().addObserver(new LifecycleEventObserver() {
                                                @Override
                                                public void onStateChanged(@androidx.annotation.NonNull LifecycleOwner lifecycleOwner, @androidx.annotation.NonNull Lifecycle.Event event) {
                                                    if (event == Lifecycle.Event.ON_RESUME) {
                                                        if (!TextUtils.isEmpty(AccountRepository.token)) {
                                                            loginDialog.dismiss();
                                                            activity.getLifecycle().removeObserver(this);
                                                            observer.onSuccess(sdkInt);
                                                        }
                                                    } else if (event == Lifecycle.Event.ON_DESTROY) {
                                                        activity.getLifecycle().removeObserver(this);
                                                    }
                                                }
                                            });
                                        }

                                        @Override
                                        public void onClickCancel() {
                                            observer.onError(new CancelException());
                                        }
                                    });
                            loginDialog.show();
                        });
                    } else {
                        return Single.just(sdkInt);
                    }
                })
                .flatMap((Function<Integer, SingleSource<Integer>>) sdkInt -> {
                    //判断是否有所有文件权限
                    boolean result = PermissionUtil.hasFilePermission();
                    if (!result) {
                        return (SingleSource<Integer>) observer -> activity.runOnUiThread(() -> {
                            PermissionDialog requestManageDialog = new PermissionDialog(activity);
                            requestManageDialog.setDialogTitle(R.string.request_manage_permission_title)
                                    .setDialogContent(R.string.request_manage_permission_content)
                                    .setTitleGravity(Gravity.START)
                                    .setContentGravity(Gravity.START)
                                    .setSureText(R.string.teaching_limit)
                                    .setOnDialogClickListener(new PermissionDialog.OnDialogClickListener() {
                                        @Override
                                        public void onClickSure() {
                                            PermissionUtil.requestWriteStoragePermission(activity, new PermissionUtil.PermissionCallback() {
                                                @Override
                                                public void onPermissionGranted() {
                                                    requestManageDialog.dismiss();
                                                    observer.onSuccess(sdkInt);
                                                }

                                                @Override
                                                public void onPermissionDenied() {

                                                }
                                            });
                                        }

                                        @Override
                                        public void onClickCancel() {
                                            observer.onError(new CancelException());
                                        }
                                    });
                            requestManageDialog.show();
                        });
                    } else {
                        return Single.just(sdkInt);
                    }
                })
                .flatMap((Function<Integer, SingleSource<Integer>>) sdkInt -> {
                    if (sdkInt >= Build.VERSION_CODES.TIRAMISU) {
                        return Single.just(sdkInt);
                    }
                    boolean dataFolder = XFilePermission.hasAndroidDataPermission(ContextUtil.getContext());
                    if (!dataFolder) {
                        return observer -> activity.runOnUiThread(() -> {
                            PermissionDialog requestAndroidDataDialog = new PermissionDialog(activity);
                            requestAndroidDataDialog.setDialogTitle(R.string.request_android_data_permission_title)
                                    .setDialogContent(R.string.request_android_data_permission_content)
                                    .setCancelText(R.string.wait_moment)
                                    .setSureText(R.string.teaching_limit)
                                    .setOnDialogClickListener(new PermissionDialog.OnDialogClickListener() {
                                        @Override
                                        public void onClickSure() {
                                            XFilePermission.requestAndroidDataPermission(activity, new XFilePermission.PermissionCallback() {
                                                @Override
                                                public void onPermissionGranted() {
                                                    requestAndroidDataDialog.dismiss();
                                                    observer.onSuccess(sdkInt);
                                                }

                                                @Override
                                                public void onPermissionDenied() {

                                                }
                                            });
                                        }

                                        @Override
                                        public void onClickCancel() {
                                            observer.onError(new CancelException());
                                        }
                                    });
                            requestAndroidDataDialog.show();
                        });
                    } else {
                        return Single.just(sdkInt);
                    }
                })
                .compose(RxJavaUtil.SingleSchedule.io2Main())
                .subscribe(new SingleObserver<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        disposable = d;
                    }

                    @Override
                    public void onSuccess(@NonNull Integer sdkInt) {
                        if (stepCallback != null) stepCallback.onNextStep();
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        if (e instanceof CancelException) {
                            if (stepCallback != null) stepCallback.onCancel();
                        }
                    }
                });
        activity.getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@androidx.annotation.NonNull LifecycleOwner lifecycleOwner, @androidx.annotation.NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    if (disposable != null && !disposable.isDisposed()) {
                        disposable.dispose();
                    }
                    activity.getLifecycle().removeObserver(this);
                }
            }
        });
    }

    public interface NextStepCallback {
        void onNextStep();

        void onCancel();
    }

    private static class CancelException extends Exception {
    }
}
