package com.gh.common.util;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.constant.Config;
import com.gh.common.filter.RegionSetting;
import com.gh.gamecenter.R;
import com.gh.gamecenter.ShellActivity;
import com.gh.gamecenter.SuggestionActivity;
import com.gh.gamecenter.adapter.ReportReasonAdapter;
import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder;
import com.gh.gamecenter.common.base.TrackableDialog;
import com.gh.gamecenter.common.callback.CancelListener;
import com.gh.gamecenter.common.callback.ConfirmListener;
import com.gh.gamecenter.common.callback.SimpleCallback;
import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.view.CustomLinkMovementMethod;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.common.view.FixLinearLayoutManager;
import com.gh.gamecenter.common.view.LimitHeightLinearLayout;
import com.gh.gamecenter.common.view.MaxHeightNestedScrollView;
import com.gh.gamecenter.common.view.VerticalItemDecoration;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.EmptyCallback;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.SpanBuilder;
import com.gh.gamecenter.core.utils.StringUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.DialogBindPhoneBinding;
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
import com.gh.gamecenter.databinding.DialogPackageParseErrorBinding;
import com.gh.gamecenter.databinding.DialogReceiveLibaoSuccessBinding;
import com.gh.gamecenter.databinding.DialogRelievePhoneBinding;
import com.gh.gamecenter.databinding.DialogReportReasonBinding;
import com.gh.gamecenter.databinding.DialogWechatReserveSuccessBinding;
import com.gh.gamecenter.databinding.ImprintContentItemBinding;
import com.gh.gamecenter.databinding.PrivacyItemBinding;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.BadgeEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.PermissionsEntity;
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SimpleGameEntity;
import com.gh.gamecenter.entity.TrackableEntity;
import com.gh.gamecenter.login.entity.Badge;
import com.gh.gamecenter.setting.SettingBridge;
import com.gh.gamecenter.suggest.SuggestType;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Utils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import kotlin.Unit;
import kotlin.jvm.functions.Function0;

public class DialogUtils {

    public static Dialog showWaitDialog(Context context, String msg) {
        context = checkDialogContext(context);

        Dialog dialog = new Dialog(context);
        View view = View.inflate(context, R.layout.set_wait_dialog, null);
        TextView message = view.findViewById(R.id.set_wait_message);
        message.setText(msg);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(view);
        dialog.setCanceledOnTouchOutside(false);
        dialog.getWindow().setBackgroundDrawableResource(R.drawable.background_shape_white_radius_8);
        WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
        layoutParams.width = DisplayUtils.dip2px(160);
        dialog.getWindow().setAttributes(layoutParams);
        dialog.show();
        return dialog;
    }

    public static void showInstallHintDialog(Context context, final ConfirmListener cmListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context);

        View view = View.inflate(context, R.layout.dialog_install_hint, null);

        // 标题
        TextView alertdialog_title = view.findViewById(R.id.installhint_title);
        alertdialog_title.setText("重要提示");
        Spanned content = Html.fromHtml("如果您使用的是" + "<font color=\"#ff0000\">华为</font>" + "或" +
                "<font color=\"#ff0000\">OPPO</font>" + "手机，安装游戏时请选择“" +
                "<font color=\"#ff0000\">继续安装</font>" +
                "”（记住不要选择“官方推荐”或“软件商店安装”）");
        // 内容
        TextView alertdialog_content = view.findViewById(R.id.installhint_content);
        alertdialog_content.setText(content);

        // 确定按钮
        TextView installhint_confirm = view.findViewById(R.id.installhint_confirm);
        installhint_confirm.setText("知道了");

        final ImageView installhint_unselect = view.findViewById(R.id.installhint_unselect);
        final ImageView installhint_select = view.findViewById(R.id.installhint_select);

        LinearLayout installhint_unselect_ll = view.findViewById(R.id.installhint_unselect_ll);

        installhint_unselect_ll.setOnClickListener(v -> {
            if (installhint_unselect.getVisibility() == View.GONE) {
                installhint_unselect.setVisibility(View.VISIBLE);
                installhint_select.setVisibility(View.GONE);
            } else {
                installhint_unselect.setVisibility(View.GONE);
                installhint_select.setVisibility(View.VISIBLE);
            }
        });

        installhint_confirm.setOnClickListener(v -> {
            dialog.dismiss();
            if (installhint_select.getVisibility() == View.VISIBLE) {
                if (cmListener != null) {
                    cmListener.onConfirm();
                }
            }
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(view);
        dialog.show();
    }

    public static void showHintDialog(Context context, String title, CharSequence msg, String confirm) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context);

        View view = View.inflate(context, R.layout.common_hintdialog, null);

        TextView hintdialog_title = view.findViewById(R.id.tv_dialog_hint_title);
        hintdialog_title.setText(title);

        // 内容
        TextView hintdialog_content = view.findViewById(R.id.tv_dialog_hint_content);
        hintdialog_content.setText(msg);

        TextView hintdialog_confirm = view.findViewById(R.id.tv_dialog_hint_confirm);

        hintdialog_confirm.setText(confirm);

        hintdialog_confirm.setOnClickListener(v -> dialog.cancel());

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(view);
        dialog.show();
    }


    public static void checkDownload(Context context, String size, CheckDownloadCallBack callBack) {
        if (!NetworkUtils.isNetworkConnected(context)) {
            showNoConnectionDownloadDialog(context, null,
                    () -> callBack.onResponse(true));
        } else if (NetworkUtils.isWifiConnected(context)
                || filter4GorSize(context, size)) {
            callBack.onResponse(false);
        } else if (!SPUtils.getBoolean(getTrafficDownloadHintKey(), true)) {
            AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载，请注意流量消耗"), 500);
            callBack.onResponse(false);
        } else {
//            MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
            showDownloadDialog(context,
                    () -> callBack.onResponse(false),
                    () -> callBack.onResponse(true));
        }
    }

    private static String getTrafficDownloadHintKey() {
        return PackageUtils.getGhVersionName() + "traffic_download_hint";
    }

    private static boolean filter4GorSize(Context context, String size) {
        try {
            if (TextUtils.isEmpty(size)) {
                return false;
            }
            String mb = size.toUpperCase().replace("MB", "").trim();
            Float i = Float.valueOf(mb);
            if (NetworkUtils.isWifiOr4GConnected(context) && i <= 50) {
                AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载，请注意流量消耗"), 500);

                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void checkResumeDownload(Context context, CheckDownloadCallBack callBack) {
        if (!NetworkUtils.isNetworkConnected(context)) {
            showNoConnectionDownloadDialog(context, null, () -> callBack.onResponse(true));
        } else if (NetworkUtils.isWifiConnected(context)) {
            callBack.onResponse(false);
        } else {
            showResumeDownloadDialog(context, () -> {
                callBack.onResponse(false);
            }, () -> {
                callBack.onResponse(true);
            });
        }
    }

    public static void showNoConnectionDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener) {
        com.gh.gamecenter.common.utils.DialogUtils.showWarningDialog(context, "下载提示", "网络异常，请检查手机网络状态", "连上WiFi后自动下载", "关闭", listener, cancelListener);
    }

    public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_download_traffic, null);
        View allowOnce = contentView.findViewById(R.id.allow_once);
        View allowAlways = contentView.findViewById(R.id.allow_always);
        View wifiAuto = contentView.findViewById(R.id.wifi_auto);

        Context finalContext = context;
        allowOnce.setOnClickListener(v -> {
            AppExecutor.getUiExecutor().executeWithDelay(() -> {
                Utils.toast(finalContext, "已使用移动网络下载，请注意流量消耗");
            }, 500);
            listener.onConfirm();
            dialog.dismiss();
//            MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
        });
        wifiAuto.setOnClickListener(v -> {
            cancelListener.onCancel();
            dialog.dismiss();
//            MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
        });
        allowAlways.setOnClickListener(v -> {
            SPUtils.setBoolean(getTrafficDownloadHintKey(), false);
            AppExecutor.getUiExecutor().executeWithDelay(() -> {
                // 显示了弹窗以后，即便下面这个 toast 放在 listener.onConfirm 后调用也是显示 listener.onConfirm 里的 toast
                // 喷了，延时包治疑难杂症
                Utils.toast(finalContext, "已使用移动网络下载，请注意流量消耗");
            }, 500);
            listener.onConfirm();
            dialog.dismiss();
//            MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showResumeDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener) {
        com.gh.gamecenter.common.utils.DialogUtils.showWarningDialog(context, "下载提示", "当前正在使用移动网络，继续下载会消耗手机流量", "连上WiFi后自动下载", "继续下载", listener, cancelListener);
    }

    public static void showDownloadDialog(Context context, ConfirmListener listener) {
        com.gh.gamecenter.common.utils.DialogUtils.showWarningDialog(context, "下载提示", "您当前使用的网络为2G/3G/4G，开始下载将会消耗移动流量，确定下载？", listener);
    }

    public static void showCancelDialog(Context context, final ConfirmListener listener, CancelListener cancelListener) {
        Spanned content = Html.fromHtml(context.getString(R.string.cancel_concern_dialog));
        showCancelListenerDialog(context, "取消关注", content, "确定取消", "暂不取消", listener, cancelListener);
    }

    /**
     * ios 风格弹窗
     *
     * @param context
     * @param title      标题
     * @param message    内容
     * @param negative   取消按钮文本
     * @param positive   确认按钮文本
     * @param clListener 取消按钮监听
     * @param cmListener 确认按钮监听
     */
    public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
            , String negative, String positive, TrackableEntity trackableEntity, int gravity, boolean shouldShowCloseBtn, final CancelListener clListener, final ConfirmListener cmListener) {
        context = checkDialogContext(context);
        final Dialog dialog;
        if (trackableEntity != null) {
            dialog = new TrackableDialog(context,
                    R.style.GhAlertDialog,
                    trackableEntity.getEvent(),
                    trackableEntity.getKey(),
                    trackableEntity.getValue(),
                    trackableEntity.getCancelValue(),
                    trackableEntity.getKeyBackValue(),
                    trackableEntity.getLogShowEvent());
        } else {
            dialog = new Dialog(context, R.style.GhAlertDialog);
        }

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_new_alert, null);

        TextView titleTv = contentView.findViewById(R.id.title);
        TextView contentTv = contentView.findViewById(R.id.content);
        TextView cancelBtn = contentView.findViewById(R.id.cancel);
        TextView confirmBtn = contentView.findViewById(R.id.confirm);
        View middleLine = contentView.findViewById(R.id.middle_line);
        View closeIv = contentView.findViewById(R.id.closeIv);
        titleTv.setGravity(gravity);
        contentTv.setGravity(gravity);

        titleTv.setText(title);
        contentTv.setText(message);
        cancelBtn.setText(negative);
        confirmBtn.setText(positive);
        if (negative.isEmpty()) {
            cancelBtn.setVisibility(View.GONE);
            middleLine.setVisibility(View.GONE);
            confirmBtn.setTextColor(ContextCompat.getColor(context, R.color.text_title));
        }
        if (positive.isEmpty()) {
            confirmBtn.setVisibility(View.GONE);
            middleLine.setVisibility(View.GONE);
        }
        closeIv.setVisibility(shouldShowCloseBtn ? View.VISIBLE : View.GONE);
        closeIv.setOnClickListener(v -> dialog.dismiss());

        cancelBtn.setOnClickListener(v -> {
            if (clListener != null) clListener.onCancel();
            dialog.dismiss();
        });

        confirmBtn.setOnClickListener(v -> {
            if (cmListener != null) cmListener.onConfirm();
            dialog.dismiss();
        });

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        return dialog;
    }

    public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
            , String negative, String positive, final CancelListener clListener, final ConfirmListener cmListener) {
        return showNewAlertDialog(context, title, message, negative, positive, null, Gravity.LEFT, false, clListener, cmListener);
    }

    public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
            , String negative, String positive, int gravity, boolean shouldShowCloseBtn, final CancelListener clListener, final ConfirmListener cmListener) {
        return showNewAlertDialog(context, title, message, negative, positive, null, gravity, shouldShowCloseBtn, clListener, cmListener);
    }


    public static Dialog showDialogWithHtmlContent(Context context, String title, String content
            , String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
        contentTv.setText(Html.fromHtml(content));
        titleTv.setText(title);
        negativeTv.setText(negative);
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        return dialog;
    }

    /**
     * 取消按钮灰色
     *
     * @param context
     * @param title
     * @param message
     * @param positive
     * @param negative
     * @param cmListener
     */

    public static void showCancelAlertDialog(Context context, String title, CharSequence message
            , String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);

        contentTv.setText(message);
        titleTv.setText(title);
        negativeTv.setText(negative);
        negativeTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    /**
     * 点击外部退出和取消监听绑定
     */
    public static void showCancelListenerDialog(Context context, String title, CharSequence message
            , String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);

        contentTv.setText(message);
        titleTv.setText(title);
        negativeTv.setText(negative);
        //negativeTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (clListener != null) {
                    clListener.onCancel();
                }
                dialog.dismiss();
            }
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.setOnCancelListener(dialogInterface -> {
            if (clListener != null)
                clListener.onCancel();
        });
        dialog.show();
    }


    /**
     * 权限弹窗
     * 只能在弹窗内取消
     */
    public static void showPermissionDialog(Context context, String title, CharSequence message
            , String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);

        contentTv.setText(message);
        titleTv.setText(title);
        negativeTv.setText(negative);
        negativeTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.setCancelable(false);
        dialog.show();
    }

    /**
     * 只能在弹窗内取消
     */
    public static void showForceDialog(Context context, String title, CharSequence message
            , String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);

        contentTv.setText(message);
        titleTv.setText(title);
        negativeTv.setText(negative);
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.setCancelable(false);
        dialog.show();
    }

    /**
     * 特殊：验证手机号码
     */

    public static void checkPhoneNumDialog(Context context, CharSequence message, final ConfirmListener cmListener) {
        String s = message.toString();
        String sub1 = s.substring(0, 3);
        String sub2 = s.substring(3, 7);
        String sub3 = s.substring(7, 11);
        String phoneNum = StringUtils.buildString(sub1, " - ", sub2, " - ", sub3);

        AlertDialog alertDialog = new AlertDialog.Builder(context, R.style.GhAlertDialog)
                .setTitle("请确定手机号：")
                .setMessage(phoneNum)
                .setPositiveButton("确认", (dialog, which) -> {
                    if (cmListener != null) {
                        cmListener.onConfirm();
                    }
                })
                .setNegativeButton("取消", null)
                .create();
        alertDialog.show();

        TextView mesage = (TextView) alertDialog.findViewById(android.R.id.message);
        Button positiveBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE);
        Button negativeBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_NEGATIVE);

        positiveBtn.setTextSize(13);
        positiveBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
        negativeBtn.setTextSize(13);
        negativeBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
        if (mesage != null) {
            mesage.setGravity(Gravity.CENTER);
            mesage.setTextSize(24);
            mesage.setTextColor(ContextCompat.getColor(context, R.color.title));
            TextPaint tp = mesage.getPaint();
            tp.setFakeBoldText(true);
        }
    }

    public static void showSignDialog(Context context, String title, CharSequence message, CharSequence message2
            , String positive, final ConfirmListener cmListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_sign, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
        TextView content2Tv = contentView.findViewById(R.id.dialog_content2);

        contentTv.setText(Html.fromHtml(message.toString()));
        content2Tv.setText(Html.fromHtml(message2.toString()));
        titleTv.setText(title);
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> dialog.dismiss());

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }


    public static void showLowSystemVersionDialog(Context context) {
        final Context activityContext = checkDialogContext(context);

        final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_alert, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);

        titleTv.setText("提示");
        contentTv.setText("抱歉，您当前系统版本过低，暂不支持视频功能");
        positiveTv.setText("我知道了");

        positiveTv.setOnClickListener(view -> {
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showListDialog(Context context,
                                      List<String> selectionList,
                                      DialogInterface.OnClickListener onClickListener) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);

        String[] selectionArray = new String[selectionList.size()];
        selectionArray = selectionList.toArray(selectionArray);
        builder.setItems(selectionArray, onClickListener);
        AlertDialog dialog = builder.create();
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.show();
    }

    /**
     * @param options         供以显示的选项
     * @param disabledOptions 显示为灰色的选项（是 options 的子集）
     */
    public static void showListDialog(Context context,
                                      List<String> options,
                                      List<String> disabledOptions,
                                      OptionCallback callback) {
        context = checkDialogContext(context);

        Dialog dialog = new Dialog(context);

        LinearLayout container = new LinearLayout(context);
        container.setOrientation(LinearLayout.VERTICAL);
        container.setBackgroundColor(ContextCompat.getColor(context, R.color.background_white));
        container.setPadding(0, DisplayUtils.dip2px(context, 12f), 0, DisplayUtils.dip2px(context, 12f));

        for (String option : options) {
            TextView reportTv = new TextView(context);
            reportTv.setText(option);
            reportTv.setTextSize(17f);
            if (disabledOptions != null && disabledOptions.contains(option)) {
                reportTv.setTextColor(ContextCompat.getColor(context, R.color.btn_gray));
            } else {
                reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
                reportTv.setBackgroundResource(R.drawable.textview_white_style);
            }
            int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
            reportTv.setLayoutParams(new LinearLayout.LayoutParams(widthPixels * 9 / 10,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            reportTv.setPadding(DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 12f),
                    0, DisplayUtils.dip2px(context, 12f));
            container.addView(reportTv);

            reportTv.setOnClickListener(v -> {
                dialog.cancel();
                callback.onClicked(reportTv.getText().toString());
            });
        }

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(container);
        dialog.show();
    }


    /**
     * 特殊：目前只在提交问题错误返回时弹出
     */
    public static Dialog showCommunityDialog(Context context,
                                             String title,
                                             String contentTitle,
                                             String contentDes,
                                             String negative,
                                             String positive,
                                             final CancelListener clListener,
                                             final ConfirmListener cmListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_community, null);
        View contentContainer = contentView.findViewById(R.id.content_container);
        TextView titleTv = contentView.findViewById(R.id.title);
        TextView contentTitleTv = contentView.findViewById(R.id.content_title);
        TextView contentDesTv = contentView.findViewById(R.id.content_des);
        TextView negativeTv = contentView.findViewById(R.id.negative);
        TextView positiveTv = contentView.findViewById(R.id.positive);

        titleTv.setText(title);
        contentTitleTv.setText(contentTitle);
        contentDesTv.setText(contentDes);

        if (TextUtils.isEmpty(negative)) {
            negativeTv.setVisibility(View.GONE);
        } else {
            negativeTv.setVisibility(View.VISIBLE);
            negativeTv.setText(negative);
        }

        if (TextUtils.isEmpty(positive)) {
            positiveTv.setVisibility(View.GONE);
        } else {
            positiveTv.setText(positive);
            positiveTv.setVisibility(View.VISIBLE);
        }

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        contentContainer.setOnClickListener(v -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        return dialog;
    }

    public static void showPrivacyPolicyDialog(Context context,
                                               @NonNull PrivacyPolicyEntity entity,
                                               SimpleCallback<Boolean> callback) {

        final Context activityContext = checkDialogContext(context);

        // 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
        AtomicBoolean isCanceledByClickOutsideOfDialog = new AtomicBoolean(true);

        final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
        View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_privacy_policy, null);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawableResource(android.R.color.transparent);
            WindowManager.LayoutParams params = window.getAttributes();
            params.horizontalMargin = 0;
            params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
//            int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
//            int maxHeight = DisplayUtils.dip2px(446);
//            if (height > maxHeight) {
//                params.height = maxHeight;
//            } else {
//                params.height = height;
//            }
            window.setAttributes(params);
        }

        TextView title = contentView.findViewById(R.id.title);
        TextView bottomContent = contentView.findViewById(R.id.bottom_content);
        TextView topContent = contentView.findViewById(R.id.top_content);
        TextView allowButton = contentView.findViewById(R.id.allow_button);
        TextView disallowButton = contentView.findViewById(R.id.disallow_button);
        TextView linkContent = contentView.findViewById(R.id.link_content);
        RecyclerView permissions = contentView.findViewById(R.id.permissions_content);

        permissions.setLayoutManager(new FixLinearLayoutManager(context));
        permissions.setAdapter(new BaseRecyclerAdapter(context) {
            @NonNull
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = mLayoutInflater.inflate(R.layout.privacy_item, parent, false);
                return new PrivacyPolicyItemViewHolder(PrivacyItemBinding.bind(view));
            }

            @Override
            public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
                if (holder instanceof PrivacyPolicyItemViewHolder) {
                    PrivacyPolicyItemViewHolder viewHolder = (PrivacyPolicyItemViewHolder) holder;
                    PrivacyItemBinding binding = viewHolder.getBinding();
                    final PermissionsEntity permissionsEntity = entity.getPermissions().get(position);
                    ImageUtils.display(binding.icon, permissionsEntity.getIcon());
                    binding.name.setText(permissionsEntity.getName());
                    binding.intro.setText(permissionsEntity.getIntro());
                    GenericDraweeHierarchy hierarchy = binding.icon.getHierarchy();
                    if (hierarchy != null) {
                        if (position == 0) {
                            hierarchy.setPlaceholderImage(R.drawable.permission_storage);
                        } else if (position == 1) {
                            hierarchy.setPlaceholderImage(R.drawable.permission_phone_state);
                        }
                    }
                }
            }

            @Override
            public int getItemCount() {
                return entity.getPermissions().size();
            }
        });

        SpannableStringBuilder skipText = new SpannableStringBuilder("查看完整版的隐私政策和用户协议");
        skipText.setSpan(new ClickableSpan() {
            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
                ds.setUnderlineText(false);
            }

            @Override
            public void onClick(@NonNull View widget) {
//                MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击隐私政策");
                DirectUtils.directToExternalBrowser(context, context.getString(R.string.privacy_policy_url));
            }
        }, skipText.length() - 9, skipText.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        skipText.setSpan(new ClickableSpan() {
            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
                ds.setUnderlineText(false);
            }

            @Override
            public void onClick(@NonNull View widget) {
//                MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击用户协议");
                DirectUtils.directToExternalBrowser(context, context.getString(R.string.disclaimer_url));
            }
        }, skipText.length() - 4, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        /*skipText.setSpan(new ClickableSpan() {
            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
                ds.setUnderlineText(false);
            }

            @Override
            public void onClick(@NonNull View widget) {
//                MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击第三方SDK接入说明");
                activityContext.startActivity(WebActivity.getThirdPartySdkStatementIntent(activityContext));
            }
        }, skipText.length() - 10, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);*/

        title.setText(entity.getTitle());
        linkContent.setText(skipText);
        linkContent.setMovementMethod(LinkMovementMethod.getInstance());
        topContent.setText(entity.getTopContent());
        bottomContent.setText(ExtensionsKt.fromHtml(entity.getBottomContent()));
        bottomContent.setMovementMethod(CustomLinkMovementMethod.getInstance());

        // Remove underline
        Spannable sa = (Spannable) bottomContent.getText();
        for (URLSpan u : sa.getSpans(0, sa.length(), URLSpan.class)) {
            sa.setSpan(new UnderlineSpan() {
                public void updateDrawState(TextPaint tp) {
                    tp.setUnderlineText(false);
                }
            }, sa.getSpanStart(u), sa.getSpanEnd(u), 0);
        }

        allowButton.setOnClickListener(view -> {
            dialog.dismiss();
            callback.onCallback(true);
//            MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
        });

        disallowButton.setOnClickListener(v -> {
            dialog.dismiss();
            callback.onCallback(false);
//            showPrivacyPolicyDisallowDialog(activityContext, entity, callback);
//            MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
        });

        dialog.setOnCancelListener(cd -> {
            if (isCanceledByClickOutsideOfDialog.get()) {
//                MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
            }
        });

        dialog.setOnKeyListener((dialog1, keyCode, event) -> {
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                isCanceledByClickOutsideOfDialog.set(false);
//                MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
            }
            return false;
        });
        // 用户未同意隐私策略不应该触发 MTA 事件
//        MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");

        try {
            dialog.setCancelable(false);
            dialog.show();
        } catch (Exception ignored) {
        }
    }

    public static void showPrivacyPolicyDisallowDialog(Context context,
                                                       @NonNull PrivacyPolicyEntity entity,
                                                       EmptyCallback callback) {
        final Context activityContext = checkDialogContext(context);

        final Dialog dialog = new Dialog(activityContext, R.style.DialogWindowTransparent);

        View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_disallow_privacy_policy, null);
        View backButton = contentView.findViewById(R.id.back_button);
        View reviewButton = contentView.findViewById(R.id.review_button);

        backButton.setOnClickListener(v -> {
            // 用户未同意隐私策略不应该触发 MTA 事件
//            MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "退出应用");
            dialog.dismiss();
            AppManager.getInstance().appExit(activityContext);
        });
        reviewButton.setOnClickListener(v -> {
//            MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "再次查看");
            callback.onCallback();
            dialog.dismiss();
            //showPrivacyPolicyDialog(activityContext, entity, callback);
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCancelable(false);
        dialog.setContentView(contentView);
        try {
            dialog.show();
        } catch (Exception ignored) {
        }
    }

    /**
     * 特殊：目前只在提交问题错误返回时弹出
     */
    public static Dialog showUploadDraftDialog(Context context,
                                               final CancelListener clListener,
                                               final ConfirmListener cmListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_video_upload_draft, null);
        TextView negativeTv = contentView.findViewById(R.id.negative);
        TextView positiveTv = contentView.findViewById(R.id.positive);
        TextView content = contentView.findViewById(R.id.content);
        positiveTv.setBackground(DrawableView.getOvalDrawable(R.color.background, 999));
        negativeTv.setBackground(DrawableView.getOvalDrawable(R.color.theme, 999));
        content.setText(Html.fromHtml(context.getString(R.string.video_upload_draft_dialog_content)));

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });


        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        return dialog;
    }

    public static Dialog showTrackableDialog(Context context,
                                             String title,
                                             CharSequence message,
                                             String positive,
                                             String negative,
                                             final ConfirmListener cmListener,
                                             final CancelListener clListener,
                                             TrackableEntity trackableEntity) {
        return showTrackableDialog(context, false, title, message, positive, negative, cmListener, clListener, trackableEntity);
    }

    /**
     * @param useRoundedCornerStyle 使用圆角样式
     */
    public static Dialog showTrackableDialog(Context context,
                                             boolean useRoundedCornerStyle,
                                             String title,
                                             CharSequence message,
                                             String positive,
                                             String negative,
                                             final ConfirmListener cmListener,
                                             final CancelListener clListener,
                                             TrackableEntity trackableEntity) {
        context = checkDialogContext(context);

        final TrackableDialog dialog = new TrackableDialog(context,
                R.style.GhAlertDialog,
                trackableEntity.getEvent(),
                trackableEntity.getKey(),
                trackableEntity.getValue(),
                trackableEntity.getCancelValue(),
                trackableEntity.getKeyBackValue(),
                trackableEntity.getLogShowEvent());

        View contentView;
        if (useRoundedCornerStyle) {
            contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert_with_rounded_corner, null);
            Window window = dialog.getWindow();
            if (window != null) {
                window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            }
        } else {
            contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
        }

        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
        if (message.toString().contains("红包奖励")) {//将红包奖励四个字标红
            String str = message.toString().substring(0, message.toString().indexOf("红包奖励")) + "<font color='#FF0000'>红包奖励</font>";
            contentTv.setText(Html.fromHtml(str));
        } else {
            contentTv.setText(message);
        }
        titleTv.setText(title);
        negativeTv.setText(negative);
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        return dialog;
    }

    public static Dialog fixWebViewKeyboardNotWorking(Activity activity) {
        final Dialog dialog = new Dialog(activity, R.style.TransparentDialog);
        View view = new View(activity);
        view.setOnClickListener(v -> dialog.dismiss());
        view.postDelayed(() -> {
            if (!activity.isFinishing()) {
                dialog.show();
                dialog.dismiss();
            }
        }, 500);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(view);
        return dialog;
    }

    public static Dialog showUsageStatsDialog(Context context, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_usage_stats, null);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.setOnDismissListener(dialog1 -> {
            if (clListener != null) {
                clListener.onCancel();
            }
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        return dialog;
    }

    public static void showDownloadMutexDialog(Context context) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_downlaod_mutex, null);
        TextView positive = contentView.findViewById(R.id.dialog_positive);

        CountDownTimer timer = new CountDownTimer(6000, 1000) {
            public void onTick(long millisUntilFinished) {
                positive.setText(("我知道了（" + millisUntilFinished / 1000 + "）"));
            }

            public void onFinish() {
                dialog.dismiss();
            }
        };
        timer.start();

        positive.setOnClickListener(v -> {
            dialog.dismiss();
        });

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    // 海外下载地址弹窗
    public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
        context = checkDialogContext(context);

        if (gameEntity.getOverseasAddressDialog() == null
                || gameEntity.getApk().size() == 0
                || !gameEntity.getOverseasAddressDialog().isEnable()) {
            listener.onConfirm();
        } else {
            final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

            DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);

            View contentView = binding.getRoot();

            binding.gameIcon.displayGameIcon(gameEntity);
            binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
            binding.closeIv.setOnClickListener(v -> dialog.dismiss());

            if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
                gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
            }
            binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
            binding.downloadBtn.setText("下载（" + gameEntity.getApk().get(0).getSize() + "）");
            binding.downloadBtn.setOnClickListener(v -> {
                listener.onConfirm();
                dialog.dismiss();
            });

            Window window = dialog.getWindow();
            if (window != null) {
                window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            }

            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            dialog.setContentView(contentView);
            dialog.show();
        }
    }

    public static void showGameH5DownloadDialog(Context context, GameEntity gameEntity, RegionSetting.GameH5Download gameH5Download) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);

        View contentView = binding.getRoot();

        binding.gameIcon.displayGameIcon(gameEntity);
        binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
        binding.closeIv.setOnClickListener(v -> dialog.dismiss());

        Context finalContext = context;
        binding.urlTv.setText(gameH5Download.getDownloadLink());
        binding.downloadBtn.setText(gameH5Download.getButtonText());
        binding.downloadBtn.setOnClickListener(v -> {
            DirectUtils.directToExternalBrowser(finalContext, gameH5Download.getH5Link());
            dialog.dismiss();
        });

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showImprintDialog(Context context, GameEntity gameEntity, String titleName) {
        context = checkDialogContext(context);
        Dialog dialog = new Dialog(context, R.style.full_dialog);
        View inflate = LayoutInflater.from(context).inflate(R.layout.imprint_dialog, null);
        dialog.setContentView(inflate);
        dialog.show();

        Window window = dialog.getWindow();
        WindowManager.LayoutParams params;
        if (window != null) {
            params = window.getAttributes();
            params.width = (int) (context.getResources().getDisplayMetrics().widthPixels * 0.9);
            window.setAttributes(params);
            window.setBackgroundDrawableResource(R.drawable.textview_white_up);
        }

        inflate.findViewById(R.id.imprint_close).setOnClickListener(v -> dialog.dismiss());
        LinearLayout content = inflate.findViewById(R.id.imprint_content);
        ((TextView) inflate.findViewById(R.id.imprint_title)).setText(titleName);
        View head = LayoutInflater.from(context).inflate(R.layout.imprint_content_item, null);
        content.addView(head, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(30));
        LimitHeightLinearLayout imprintContainer = inflate.findViewById(R.id.imprint_container);
        imprintContainer.setLimitHeight((int) (context.getResources().getDisplayMetrics().heightPixels * 0.8));

        ArrayList<ApkEntity> list = gameEntity.getApk();
        SettingsEntity settings = Config.getSettings();
        for (int i = 0; i < list.size(); i++) {
            ApkEntity apk = gameEntity.getApk().get(i);
            if (settings != null && settings.getGameDownloadBlackList().contains(apk.getPackageName())) {
                continue;
            }
            View item = LayoutInflater.from(context).inflate(R.layout.imprint_content_item, null);
            ImprintContentItemBinding bind = ImprintContentItemBinding.bind(item);
            String platform = TextUtils.isEmpty(apk.getRemark()) ? apk.getPlatformName() : apk.getPlatformName() + "\n" + apk.getRemark();
            bind.imprintPlatform.setText(platform);
            bind.imprintVersion.setText(apk.getVersion());
            bind.imprintTime.setText(NewsUtils.getFormattedTime(apk.getTime() != null ? apk.getTime() : 0));
            content.addView(item, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(40));
        }


        // close line
        View view = new View(context);
        view.setBackgroundColor(context.getResources().getColor(R.color.text_5d5d5d));
        view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(1)));
        content.addView(view);
    }

    public static void showKaifuRemindDialog(Context context, String content, String gameName) {
        context = checkDialogContext(context);

        final Dialog dialog = new TrackableDialog(context, R.style.GhAlertDialog, "开服说明弹窗", "弹窗", gameName, null, null, true);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_kaifu_remind, null);

        TextView contentTv = contentView.findViewById(R.id.contentTv);
        MaxHeightNestedScrollView scrollView = contentView.findViewById(R.id.scrollView);
        contentTv.setText(Html.fromHtml(content));
        TextView ok = contentView.findViewById(R.id.dialog_ok);
        scrollView.setScrollChangedListener((l, t, oldl, oldt) -> {
            MtaHelper.onEvent("开服说明弹窗", "滑动内容", gameName);
        });
        ok.setOnClickListener(v -> {
            MtaHelper.onEvent("开服说明弹窗", "弹窗", "点击我知道了");
            MtaHelper.onEvent("开服说明弹窗", "点击我知道了", gameName);
            dialog.dismiss();
        });

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showStopServerExplanationDialog(Context context, String content, String gameName) {
        context = checkDialogContext(context);

        final Dialog dialog = new TrackableDialog(context, R.style.GhAlertDialog, "评论说明弹窗", "弹窗", gameName, null, null, true);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_stop_service_explanation, null);

        TextView contentTv = contentView.findViewById(R.id.contentTv);
        MaxHeightNestedScrollView scrollView = contentView.findViewById(R.id.scrollView);
        if (TextUtils.isEmpty(content)) {
            content = context.getString(R.string.rating_protection);
        }
        contentTv.setText(content);
        TextView ok = contentView.findViewById(R.id.dialog_ok);
        scrollView.setScrollChangedListener((l, t, oldl, oldt) -> {
            MtaHelper.onEvent("评论说明弹窗", "滑动内容", gameName);
        });
        ok.setOnClickListener(v -> {
            MtaHelper.onEvent("评论说明弹窗", "弹窗", "点击我知道了");
            MtaHelper.onEvent("评论说明弹窗", "点击我知道了", gameName);
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(60f);
            window.setAttributes(params);
        }
    }

    public static void showPluggableNeverRemindDialog(Context context, String nameAndPlatform, @NonNull ConfirmListener listener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_pluggable_never_remind, null);

        View cancelBtn = contentView.findViewById(R.id.cancel);
        View confirmBtn = contentView.findViewById(R.id.confirm);
        TextView contentTv = contentView.findViewById(R.id.content);

        contentTv.setText(("助手首页将不再提示《" + nameAndPlatform + "》的所有插件化消息，确定吗？"));

        cancelBtn.setOnClickListener(v -> {
            dialog.dismiss();
        });

        confirmBtn.setOnClickListener(v -> {
            listener.onConfirm();
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showRegulationTestDialog(Context context, @NonNull ConfirmListener confirmListener, @NonNull CancelListener cancelListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new TrackableDialog(
                context,
                R.style.GhAlertDialog,
                "礼仪考试",
                "礼仪考试弹窗",
                null, null, null,
                true);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_regulation_test, null);

        View cancelBtn = contentView.findViewById(R.id.cancel);
        View confirmBtn = contentView.findViewById(R.id.confirm);
        View linkTv = contentView.findViewById(R.id.link);

        Context finalContext = context;
        linkTv.setOnClickListener(v -> {

            MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "了解更多");
            DirectUtils.directToArticle(finalContext, "5f4477be25e07e19be4e2a22", "(礼仪测试弹窗)");
        });

        cancelBtn.setOnClickListener(v -> {
            cancelListener.onCancel();

            MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "跳过");
            dialog.dismiss();
        });

        Context finalContext1 = context;
        confirmBtn.setOnClickListener(v -> {
            Util_System_Keyboard.hideSoftKeyboard((Activity) finalContext1);

            MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "确定");
            confirmListener.onConfirm();
            dialog.dismiss();
        });

        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showUnzipFailureDialog(Context context, DownloadEntity downloadEntity) {
        final Context activityContext = checkDialogContext(context);

        final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawableResource(android.R.color.transparent);
        }

        View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_unzip_failure, null);

        View cancelBtn = contentView.findViewById(R.id.cancel);
        View confirmBtn = contentView.findViewById(R.id.confirm);


        cancelBtn.setOnClickListener(v -> {
            dialog.dismiss();
        });

        confirmBtn.setOnClickListener(v -> {
            dialog.dismiss();
            String hint = "《" + downloadEntity.getName() + "》游戏安装包解压失败，问题反馈：";
            SuggestionActivity.startSuggestionActivity(activityContext, SuggestType.normal, null, hint);
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showNoticeDialog(Context context, String title, String content, @NonNull ConfirmListener listener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_notice, null);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);

        if (title == null) {
            titleTv.setVisibility(View.GONE);
        } else {
            titleTv.setVisibility(View.VISIBLE);
            titleTv.setText(title);
        }
        contentTv.setText(content);

        contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
            listener.onConfirm();
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showVideoComplaintDialog(Context context,
                                                List<String> options,
                                                List<String> disabledOptions,
                                                OptionCallback callback) {
        context = checkDialogContext(context);

        Dialog dialog = new Dialog(context);

        View view = LayoutInflater.from(context).inflate(R.layout.dialog_video_complaint, null, false);
        LinearLayout complaintContainer = view.findViewById(R.id.complaintContainer);
        ConstraintLayout otherComplaintContainer = view.findViewById(R.id.otherComplaintContainer);
        EditText complaintCommentEt = view.findViewById(R.id.complaintCommentEt);
        TextView backTv = view.findViewById(R.id.backTv);
        TextView commitTv = view.findViewById(R.id.commitTv);
        Context finalContext = context;
        //添加透明阴影，实现类似 clipPadding=false 效果
        complaintCommentEt.setShadowLayer(complaintCommentEt.getExtendedPaddingBottom(), 0F, 0F, Color.TRANSPARENT);

        ExtensionsKt.setTextChangedListener(complaintCommentEt, (s, start, before, count) -> {
            commitTv.setTextColor(ContextCompat.getColor(finalContext, s.toString().trim().isEmpty() ? R.color.text_subtitleDesc : R.color.theme_font));
            return null;
        });

        for (String option : options) {
            TextView reportTv = new TextView(context);
            reportTv.setText(option);
            reportTv.setTextSize(16F);
            if (disabledOptions != null && disabledOptions.contains(option)) {
                reportTv.setTextColor(ContextCompat.getColor(context, R.color.btn_gray));
            } else {
                reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
                reportTv.setBackgroundResource(R.drawable.textview_white_style);
            }
            reportTv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            reportTv.setPadding(DisplayUtils.dip2px(context, 20F), DisplayUtils.dip2px(context, 17F),
                    DisplayUtils.dip2px(context, 20F), DisplayUtils.dip2px(context, 17F));
            if (option.equals("其它")) {
                ExtensionsKt.setDrawableEnd(reportTv, R.drawable.ic_complaint_arrow_right, DisplayUtils.dip2px(6F), DisplayUtils.dip2px(6F));
            }
            complaintContainer.addView(reportTv);

            reportTv.setOnClickListener(v -> {
                if (option.equals("其它")) {
                    complaintContainer.setVisibility(View.GONE);
                    otherComplaintContainer.setVisibility(View.VISIBLE);
                    complaintCommentEt.requestFocus();
                    Util_System_Keyboard.showSoftKeyboard(finalContext, complaintCommentEt);
                } else {
                    dialog.cancel();
                    JSONObject jsonObject = new JSONObject();
                    try {
                        jsonObject.put("reason", reportTv.getText().toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    callback.onClicked(jsonObject.toString());
                }
            });
        }

        backTv.setOnClickListener(v -> {
            Util_System_Keyboard.hideSoftKeyboard(finalContext, complaintCommentEt);
            complaintContainer.setVisibility(View.VISIBLE);
            otherComplaintContainer.setVisibility(View.GONE);
        });
        commitTv.setOnClickListener(v -> {
            if (complaintCommentEt.getText().toString().isEmpty()) {
                ToastUtils.INSTANCE.showToast("请先输入说明~");
                return;
            }
            dialog.cancel();
            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject.put("reason", "其它");
                jsonObject.put("description", complaintCommentEt.getText().toString());
            } catch (JSONException e) {
                e.printStackTrace();
            }
            callback.onClicked(jsonObject.toString());
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(view);
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40f);
            window.setAttributes(params);
        }
    }

    public static void showViewBadgeDialog(Context context, Badge badge, ConfirmListener listener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_view_badge, null);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
        ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);

        ImageUtils.display(badgeView, badge.getIcon());
        titleTv.setText(badge.getName());

        // 领取条件文本超过一行就不显示
        if (badge.getActions() == null || badge.getActions().isEmpty() || badge.getActions().size() > 1) {
            contentTv.setVisibility(View.INVISIBLE);
        } else {
            contentTv.setText(badge.getActions().get(0).getText());
            contentTv.post(() -> {
                if (contentTv.getLineCount() > 1) contentTv.setVisibility(View.INVISIBLE);
            });
        }

        Animation animation = AnimationUtils.loadAnimation(context, R.anim.anim_badge_light_bg);
        badgeLightBg.startAnimation(animation);

        contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
            listener.onConfirm();
            badgeLightBg.clearAnimation();
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showReceiveBadgeDialog(Context context, BadgeEntity badge, ConfirmListener listener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_receive_badge, null);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
        ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);
        TextView receiveTv = contentView.findViewById(R.id.dialog_ok);

        ImageUtils.display(badgeView, badge.getIcon());
        titleTv.setText(badge.getName());

        // 领取条件文本超过一行就不显示
        if (badge.getActions() == null || badge.getActions().isEmpty() || badge.getActions().size() > 1) {
            contentTv.setVisibility(View.INVISIBLE);
        } else {
            contentTv.setText(badge.getActions().get(0).getText());
            contentTv.post(() -> {
                if (contentTv.getLineCount() > 1) contentTv.setVisibility(View.INVISIBLE);
            });
        }

        if ("self".equals(badge.getReceive().getType())) {
            receiveTv.setText(R.string.receive_badge);
        } else {
            receiveTv.setText(R.string.apply_badge);
        }

        Animation animation = AnimationUtils.loadAnimation(context, R.anim.anim_badge_light_bg);
        badgeLightBg.startAnimation(animation);

        contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
            listener.onConfirm();
            badgeLightBg.clearAnimation();
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showPassRegulationDialog(Context context, String icon) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_pass_regulation, null);
        SimpleDraweeView userIcon = contentView.findViewById(R.id.dialog_icon);

        ImageUtils.display(userIcon, icon);

        contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static void showShortCutPermissionDialog(Context context) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_shortcut_permission, null);

        Context finalContext = context;
        contentView.findViewById(R.id.dialog_positive).setOnClickListener(v -> {
            dialog.dismiss();
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + finalContext.getPackageName()));
            finalContext.startActivity(intent);
        });

        contentView.findViewById(R.id.dialog_negative).setOnClickListener(v -> {
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
    }

    public static Dialog showCancelOrDeleteReservationDialog(Context context, String title, String message
            , String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_cancel_reservation, null);
        TextView contentTv = contentView.findViewById(R.id.dialog_content);
        TextView titleTv = contentView.findViewById(R.id.dialog_title);
        TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
        TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
        contentTv.setText(message);
        titleTv.setText(title);
        negativeTv.setText(negative);
        positiveTv.setText(positive);

        negativeTv.setOnClickListener(view -> {
            if (clListener != null) {
                clListener.onCancel();
            }
            dialog.dismiss();
        });

        positiveTv.setOnClickListener(view -> {
            if (cmListener != null) {
                cmListener.onConfirm();
            }
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(contentView);
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(60f);
            window.setAttributes(params);
        }
        return dialog;
    }

    public static void showSimulatorParseErrorDialog(Context context, String gameId, String gameName, ConfirmListener confirmListener) {
        context = checkDialogContext(context);
        final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);

        DialogPackageParseErrorBinding binding = DialogPackageParseErrorBinding.inflate(LayoutInflater.from(context), null, false);
        Context finalContext = context;
        SpannableStringBuilder builder = new SpanBuilder("您也可以点击提交反馈跟我们联系").click(context, 6, 10, R.color.theme_font, true, new Function0<Unit>() {
            @Override
            public Unit invoke() {
                SimpleGameEntity entity = new SimpleGameEntity(gameId, gameName, "");
                SuggestionActivity.startSuggestionActivity(finalContext, SuggestType.gameQuestion, "notfound", "模拟器安装包解析错误", entity, "-");
                dialog.dismiss();
                return null;
            }
        }).build();
        binding.feedbackTv.setText(builder);
        binding.feedbackTv.setMovementMethod(new LinkMovementMethod());

        binding.cancel.setOnClickListener(v -> {
            dialog.dismiss();
        });
        binding.confirm.setOnClickListener(v -> {
            confirmListener.onConfirm();
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(60f);
            window.setAttributes(params);
        }
    }

    public static void showReportReasonDialog(Context context, ArrayList<String> items, ReportReasonCallBack callBack) {
        showReportReasonDialog(context, items, "", callBack);
    }

    @SuppressLint("SetTextI18n")
    public static void showReportReasonDialog(Context context, ArrayList<String> items, String title, ReportReasonCallBack callBack) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
        DialogReportReasonBinding binding = DialogReportReasonBinding.inflate(LayoutInflater.from(context));

        if (!title.isEmpty()) {
            binding.reasonTitle.setText(title);
        }

        ReportReasonAdapter reportReasonAdapter = new ReportReasonAdapter(context, items, reason -> {
            if (reason.equals("其他原因")) {
                binding.reasonTitle.setText(R.string.report_reason_other_title);
                binding.normalReasonContainer.setVisibility(View.GONE);
                binding.otherReasonContainer.setVisibility(View.VISIBLE);
            } else {
                dialog.dismiss();
                callBack.onResponse(reason, "");
            }
            return null;
        });
        binding.reasonRv.setLayoutManager(new LinearLayoutManager(context));
        binding.reasonRv.addItemDecoration(new VerticalItemDecoration(context, 1F, false, R.color.background));
        binding.reasonRv.setAdapter(reportReasonAdapter);

        binding.negativeBtn.setOnClickListener(v -> {
            binding.reasonTitle.setText(R.string.report_reason_title);
            binding.normalReasonContainer.setVisibility(View.VISIBLE);
            binding.otherReasonContainer.setVisibility(View.GONE);
        });

        binding.positiveBtn.setOnClickListener(v -> {
            if (TextUtils.isEmpty(binding.otherReasonEt.getText().toString().trim())) {
                ToastUtils.showToast("请填写举报原因");
            } else {
                dialog.dismiss();
                callBack.onResponse("其他原因", binding.otherReasonEt.getText().toString());
            }
        });

        Context finalContext = context;
        ExtensionsKt.setTextChangedListener(binding.otherReasonEt, (s, start, before, count) -> {
            int tvCount = s.length();
            if (tvCount >= 500) {
                binding.tvCount.setTextColor(ContextCompat.getColor(finalContext, R.color.theme_red));
            }
            binding.tvCount.setText(tvCount + "/500");
            return null;
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
    }

    public static Dialog showBindPhoneDialog(Context context, ConfirmListener listener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
        DialogBindPhoneBinding binding = DialogBindPhoneBinding.inflate(LayoutInflater.from(context));

        binding.positiveTv.setOnClickListener(v -> {
            dialog.dismiss();
            listener.onConfirm();
        });

        binding.closeIv.setOnClickListener(v -> {
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
        return dialog;
    }

    public static void showReceiveLibaoSuccessDialog(Context context, String title, String des, String libaoCode, ConfirmListener listener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
        DialogReceiveLibaoSuccessBinding binding = DialogReceiveLibaoSuccessBinding.inflate(LayoutInflater.from(context));
        binding.title.setText(title);
        binding.libaoCodeTv.setText(libaoCode);
        binding.desTv.setText(des);

        binding.confirm.setOnClickListener(v -> {
            dialog.dismiss();
            listener.onConfirm();
        });

        binding.cancel.setOnClickListener(v -> {
            dialog.dismiss();
        });

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(60f);
            window.setAttributes(params);
        }
    }

    public static void showReserveSuccess2WechatBindDialog(Context context, ConfirmListener confirmListener, CancelListener cancelListener) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
        DialogWechatReserveSuccessBinding binding = DialogWechatReserveSuccessBinding.inflate(LayoutInflater.from(context));
        binding.closeBtn.setOnClickListener(v -> {
            cancelListener.onCancel();
            dialog.dismiss();
        });
        binding.openBtn.setOnClickListener(v -> {
            confirmListener.onConfirm();
            dialog.dismiss();
        });
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = DisplayUtils.dip2px(300f);
            window.setAttributes(params);
        }
    }

    public static void showReserveSuccessDialog(Context context) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
        DialogAlertDefaultBinding binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(context));
        binding.titleTv.setText("游戏预约成功");
        binding.contentTv.setText("游戏上线时，您将在消息中心和微信公众号收到通知，不会错过任何预约的游戏");
        binding.confirmTv.setText("我知道了");
        binding.centerDivider.setVisibility(View.GONE);
        binding.cancelTv.setVisibility(View.GONE);
        ExtensionsKt.setDrawableStart(binding.titleTv, R.drawable.ic_reserve_success, null, null);
        binding.confirmTv.setOnClickListener(v -> dialog.dismiss());
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
        Window window = dialog.getWindow();
        if (window != null) {
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = DisplayUtils.dip2px(300f);
            window.setAttributes(params);
        }
    }

    public static void showRelievePhoneDialog(Context context) {
        context = checkDialogContext(context);

        final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
        DialogRelievePhoneBinding binding = DialogRelievePhoneBinding.inflate(LayoutInflater.from(context));

        Context finalContext = context;
        binding.realNameBtn.setOnClickListener(v -> {
            dialog.dismiss();
            Intent intent = ShellActivity.getIntent(finalContext, ShellActivity.Type.REAL_NAME_INFO);
            finalContext.startActivity(intent);
        });

        binding.bindPhoneBtn.setOnClickListener(v -> {
            dialog.dismiss();
            Intent intent = SettingBridge.INSTANCE.getBindPhoneNormalIntent(finalContext, false);
            finalContext.startActivity(intent);
        });

        binding.cancelBtn.setOnClickListener(v -> dialog.dismiss());

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(binding.getRoot());
        dialog.show();
    }

    /**
     * @param context may be is application context
     * @return activity context
     */
    public static Context checkDialogContext(Context context) {
        if (context == null) {
            throw new NullPointerException("dialog context is null");
        }

        if (context instanceof Activity) {
            return context;
        }

        // currentActivity 是否存在 isDestroyed 的情况?
        return AppManager.getInstance().currentActivity();
    }

    public interface OptionCallback {
        void onClicked(String text);
    }

    public interface CheckDownloadCallBack {
        void onResponse(boolean isSubscribe);
    }

    public interface ReportReasonCallBack {
        void onResponse(String reason, String desc);
    }
}
