package com.gh.gamecenter.geetest;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;

import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.AppDebugConfig;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.utils.RuntimeUtils;
import com.lightgame.utils.Utils;

import org.json.JSONObject;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;

/**
 * Created by khy on 2017/1/12.
 * 验证码工具类
 */
public class GeetestUtils {

    private boolean isOperating;
    private ProgressDialog mProgressDialog;
    private GeetestListener mGeetestListener;
    private int mRetryCount = 0;
    private final int RETRY_MAX_COUNT = 3;

    public static GeetestUtils getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 由于后续webview textview 需要activity context，所以此处传activity context
     *
     * @param context
     * @param listener
     */
    public void showDialog(Context context, GeetestListener listener) {

        mProgressDialog = ProgressDialog.show(context, null, "Loading", true, true);

        mGeetestListener = listener;
        checkServer(context);

//        mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
//            @Override
//            public void onCancel(DialogInterface dialog) {
////                    toastMsg("user cancel progress dialog");
//                // 用户主动退出验证
//            }
//        });
    }

    private void checkServer(final Context context) {
        isOperating = true;

        RetrofitManager.getInstance().getApi()
                .getCaptchaData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new JSONObjectResponse() {
                    @Override
                    public void onResponse(JSONObject info) {
                        super.onResponse(info);
                        isOperating = false;
                        try {
                            if (info.toString().length() > 0) {

                                Utils.log("验证模块返回：" + info.toString());

                                if (info.getInt("success") == 1) {
                                    openGtTest(context, info);
                                } else {
                                    //  从API_1获得极验服务宕机或不可用通知, 使用备用验证或静态验证
                                    if (mProgressDialog.isShowing()) {
                                        mProgressDialog.dismiss();
                                    }
                                    toastMsg(context, "从服务器不接受的验证");
                                }
                            }

                        } catch (Exception e) {
                            if (mProgressDialog.isShowing()) {
                                mProgressDialog.dismiss();
                            }
                            toastMsg(context, "从API接收到无效的JSON参数");
                            e.printStackTrace();
                        }

                    }

                    @Override
                    public void onFailure(HttpException e) {
                        super.onFailure(e);
                        if (mProgressDialog.isShowing()) {
                            mProgressDialog.dismiss();
                        }
                        toastMsg(context, "服务器返回错误/网络错误");
                        isOperating = false;
                    }
                });
    }

    private void openGtTest(final Context context, JSONObject params) {

        if (AppDebugConfig.IS_DEBUG) {
            AppDebugConfig.logMethodWithParams(this, context, params);
        }

        mRetryCount = 0;
        final GtDialog dialog = new GtDialog(context, params);

        if (context instanceof Activity) {
            dialog.setOwnerActivity((Activity) context);
        }

        // 启用debug可以在webview上看到验证过程的一些数据
        dialog.setDebug(AppDebugConfig.IS_DEBUG);

//        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
//            @Override
//            public void onCancel(DialogInterface dialog) {
//                // 用户取消验证
////                toastMsg("user close the geetest.");
//            }
//        });

        dialog.setGtListener(new GtListener() {

            @Override
            public void gtCallReady(Boolean status) {
                AppExecutor.getUiExecutor().execute(() -> {
                    if (AppDebugConfig.IS_DEBUG) {
                        AppDebugConfig.logMethodWithParams(this, status, mProgressDialog.isShowing());
                    }

                    mRetryCount = 0;
                    if (!mProgressDialog.isShowing()) {
                        //被手动取消了，也就是其实用户想取消loading了，那么即使回调也不弹出
                        return;
                    }

                    mProgressDialog.dismiss();

                    if (status) {
                        // 验证加载完成
                        Activity ownerActivity = dialog.getOwnerActivity();

                        if (ownerActivity != null
                                && (ownerActivity.isFinishing()
                                || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) && ownerActivity.isDestroyed())) {
                            // activity 不可见
                            toastMsg(context, "验证加载超时，请重新尝试");
                        } else {
                            dialog.show();
                        }
                    } else {
                        // 验证加载超时,未准备完成
                        toastMsg(context, "验证加载超时，请重新尝试");
                    }
                });
            }

            @Override
            public void gtCallClose() {
                AppExecutor.getUiExecutor().execute(() -> {
                    if (AppDebugConfig.IS_DEBUG) {
                        AppDebugConfig.logMethodWithParams(this);
                    }
                    if (dialog != null && dialog.isShowing()) {
                        dialog.dismiss();
                    }
                });
            }

            @Override
            public void gtError() {
                AppExecutor.getUiExecutor().execute(() -> {
                    if (AppDebugConfig.IS_DEBUG) {
                        AppDebugConfig.logMethodWithParams(this);
                    }

                    if (mRetryCount < RETRY_MAX_COUNT) {
                        mRetryCount++;
                        checkServer(context);
                    } else {
                        if (mProgressDialog.isShowing()) {
                            mProgressDialog.dismiss();
                        }
                    }
                });
            }

            @Override
            public void gtResult(boolean success, String result) {
                AppExecutor.getUiExecutor().execute(() -> {
                    if (AppDebugConfig.IS_DEBUG) {
                        AppDebugConfig.logMethodWithParams(this, success, result);
                    }

                    if (success) {
                        if (dialog != null && dialog.isShowing()) {
                            dialog.dismiss();
                        }
                        if (mGeetestListener != null) {
                            mGeetestListener.onVerified(result);
                        }
                        Utils.log("client captcha succeed:" + result);
                    } else {
                        // 验证失败
                        Utils.log("client captcha failed:" + result);
                    }
                });
            }

        });

        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                // 需要重新get challenge
                if (AppDebugConfig.IS_DEBUG) {
                    AppDebugConfig.logMethodWithParams(this);
                }
            }
        });

        dialog.init();

    }

    private void toastMsg(Context context, String msg) {
        RuntimeUtils.getInstance().toast(context, msg);
    }

    private static class SingletonHolder {
        private static final GeetestUtils INSTANCE = new GeetestUtils();
    }
}
