package com.netease.captcha;

import android.app.Activity;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.netease.nis.captcha.Captcha;
import com.netease.nis.captcha.CaptchaConfiguration;
import com.netease.nis.captcha.CaptchaListener;
import com.netease.nis.captcha.CaptchaConfiguration.Theme;

/**
 * Created by hzhuqi on 2018/8/21.
 */
public class CaptchaHelper {
    public static final String TAG = "RNCaptcha";
    private static final String MESSAGE = "message";
    private ReactContext context;
    private CaptchaListener captchaListener;
    private String captchaId;
    private boolean isDebug;
    private int timeout;
    private String languageStr;
    private float dimAmount;
    private int failedMaxRetryCount;
    private String controlBarStartUrl;
    private String controlBarMovingUrl;
    private String controlBarErrorUrl;
    private boolean isTouchOutsideDisappear;
    private boolean isHideCloseBtn;
    private boolean useDefaultFallback;
    private boolean isShowLoading;
    private boolean isCloseButtonBottom;
    private String theme;
    private String loadingText;
    private String apiServer;
    private String staticServer;
    private boolean isMourningDay;
    private String size;
    private int refreshInterval;
    private boolean isIpv6;

    private boolean isShowInnerClose;

    private boolean canUpload;

    private String extraData;
    private ReadableMap styleConfig;

    public void init(Activity activity, ReactContext context, ReadableMap map) {
        initListener();
        this.context = context;

        getParameter(map);
        getParameterSplit(map);

        CaptchaConfiguration.Builder builder = new CaptchaConfiguration.Builder();
        // 验证码业务id
        if (!TextUtils.isEmpty(captchaId)) {
            builder.captchaId(captchaId);
        } else {
            Log.e(TAG, "业务id不能为空");
            return;
        }
        builder.listener(captchaListener);
        builder.debug(isDebug);
        if (timeout != 0) {
            builder.timeout(timeout);
        }
        if (!TextUtils.isEmpty(languageStr)) {
            builder.languageType(StyleSettingTools.string2LangType(languageStr));
        }
        if (dimAmount != 0) {
            builder.backgroundDimAmount(dimAmount);
        }
        if (failedMaxRetryCount != 0) {
            builder.failedMaxRetryCount(failedMaxRetryCount);
        }

        setParamSplit(builder);
        if (styleConfig != null) {
            StyleSettingTools.setStyle(styleConfig, builder);
        }
        Captcha.getInstance().init(builder.build(activity));
    }

    private void getParameter(ReadableMap map) {
        captchaId = map.hasKey("captcha_id") ? map.getString("captcha_id") : "";
        timeout = map.hasKey("timeout") ? map.getInt("timeout") : 1000 * 10;
        languageStr = map.hasKey("language_type") ? map.getString("language_type") : "";
        isDebug = map.hasKey("is_debug") && map.getBoolean("is_debug");
        controlBarStartUrl = map.hasKey("control_bar_start_url") ? map.getString("control_bar_start_url") : "";
        controlBarMovingUrl = map.hasKey("control_bar_moving_url") ? map.getString("control_bar_moving_url") : "";
        controlBarErrorUrl = map.hasKey("control_bar_error_url") ? map.getString("control_bar_error_url") : "";
        dimAmount = map.hasKey("dimAmount") ? (float) map.getDouble("dimAmount") : 0.5f;
        isTouchOutsideDisappear = !map.hasKey("is_touch_outside_disappear") || map.getBoolean("is_touch_outside_disappear");
        isHideCloseBtn = map.hasKey("is_hide_close_button") && map.getBoolean("is_hide_close_button");
    }

    private void getParameterSplit(ReadableMap map) {
        useDefaultFallback = !map.hasKey("use_default_fallback") || map.getBoolean("use_default_fallback");
        failedMaxRetryCount = map.hasKey("failed_max_retry_count") ? map.getInt("failed_max_retry_count") : 3;
        theme = map.hasKey("theme") ? map.getString("theme") : "";
        loadingText = map.hasKey("loading_text") ? map.getString("loading_text") : "";
        apiServer = map.hasKey("api_server") ? map.getString("api_server") : "";
        staticServer = map.hasKey("static_server") ? map.getString("static_server") : "";
        isShowLoading = !map.hasKey("is_show_loading") || map.getBoolean("is_show_loading");
        isCloseButtonBottom = map.hasKey("is_close_button_bottom") && map.getBoolean("is_close_button_bottom");
        isMourningDay = map.hasKey("is_mourning_day") && map.getBoolean("is_mourning_day");
        size = map.hasKey("size") ? map.getString("size") : "";
        refreshInterval = map.hasKey("refreshInterval") ? map.getInt("refreshInterval") : 300;
        isIpv6 = map.hasKey("isIpv6") && map.getBoolean("isIpv6");
        isShowInnerClose = map.hasKey("is_show_inner_close") && map.getBoolean("is_show_inner_close");
        canUpload = !map.hasKey("can_upload") || map.getBoolean("can_upload");
        extraData = map.hasKey("extra_data") ? map.getString("extra_data") : "";
        styleConfig = map.hasKey("styleConfig") ? map.getMap("styleConfig") : null;
    }

    private void setParamSplit(CaptchaConfiguration.Builder builder) {
        if (!TextUtils.isEmpty(controlBarStartUrl) && !TextUtils.isEmpty(controlBarMovingUrl) && !TextUtils.isEmpty(controlBarErrorUrl)) {
            builder.controlBarImageUrl(controlBarStartUrl, controlBarMovingUrl, controlBarErrorUrl);
        }
        builder.touchOutsideDisappear(isTouchOutsideDisappear);
        builder.useDefaultFallback(useDefaultFallback);
        builder.hideCloseButton(isHideCloseBtn);
        builder.isShowLoading(isShowLoading);
        builder.isCloseButtonBottom(isCloseButtonBottom);
        if (!TextUtils.isEmpty(theme)) {
            builder.theme("light".equals(theme) ? Theme.LIGHT : Theme.DARK);
        }
        if (!TextUtils.isEmpty(loadingText)) {
            builder.loadingText(loadingText);
        }
        if (!TextUtils.isEmpty(apiServer)) {
            builder.apiServer(apiServer);
        }
        if (!TextUtils.isEmpty(staticServer)) {
            builder.staticServer(staticServer);
        }

        builder.isMourningDay(isMourningDay);
        if (!TextUtils.isEmpty(size)) {
            builder.size(size);
        }
        if (!TextUtils.isEmpty(extraData)) {
            builder.extraData(extraData);
        }
        builder.setRefreshInterval(refreshInterval);
        builder.ipv6(isIpv6);
        builder.isShowInnerClose(isShowInnerClose);
        builder.disableReport(!canUpload);
    }

    public void showCaptcha() {
        Captcha.getInstance().validate();
    }

    public void destroy() {
        Captcha.getInstance().destroy();
    }

    private void initListener() {
        captchaListener = new CaptchaListener() {
            @Override
            public void onValidate(String result, String validate, String msg, String captchaType, String errorValidate) {
                WritableMap event = Arguments.createMap();
                event.putString("validate", validate);
                event.putString("result", result);
                event.putString(MESSAGE, msg);
                sendEvent("onSuccess", event);
                Log.i(TAG, "验证结果:" + result);
            }

            @Override
            public void onError(int code, String msg) {
                WritableMap event = Arguments.createMap();
                event.putInt("code", code);
                event.putString(MESSAGE, msg);
                sendEvent("onError", event);
            }

            @Override
            public void onClose(Captcha.CloseType closeType) {
                WritableMap event = Arguments.createMap();
                if (closeType == Captcha.CloseType.USER_CLOSE) {
                    event.putString(MESSAGE, "manual");
                } else if (closeType == Captcha.CloseType.VERIFY_SUCCESS_CLOSE) {
                    event.putString(MESSAGE, "auto");
                } else if (closeType == Captcha.CloseType.TIP_CLOSE) {
                    event.putString(MESSAGE, "manual");
                }
                sendEvent("onClose", event);
            }

            @Override
            public void onCaptchaShow() {
                sendEvent("onCaptchaShow", Arguments.createMap());
            }
        };
    }

    private void sendEvent(String eventName, WritableMap event) {
        context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(
                eventName, event);
    }
}
