package cn.m4399.operateBZ.phx;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

import org.json.JSONArray;

import java.util.Locale;

import cn.m4399.operateBZ.CloudArchive;
import cn.m4399.operateBZ.OperateCenter;
import cn.m4399.operateBZ.OperateConfig;
import cn.m4399.operateBZ.Order;
import cn.m4399.operateBZ.User;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;

@Keep
public class OperateCenterPHX extends StandardFeature {
    private static final String TAG = "OperatePHX";
    private final OperateCenter mOpeCenter = OperateCenter.getInstance();

    /*
     * @param iWebview 使用的页面(固定参数,必须要写)
     * @param options  显示的角标数量参数 (固定参数,必须要写)
     */
    public void initSDK(IWebview iWebview, JSONArray options) {
        Callback callback = Callback.optCallback(iWebview, options);
        Activity activity = iWebview.getActivity();
        if (activity != null) {
            initSDK(activity, options, callback);
        } else {
            Log.e(TAG, "OPERATE: Context not valid, is it instance of Activity");
        }
    }

    private void initSDK(Activity activity, JSONArray options, Callback callback) {
        Log.e(TAG, "OPERATE: start init 4399 operate SDK, callback " + callback.id);
        Log.e(TAG, "    options: " + options);

        String gameKey = options.optString(1);
        int orientation = options.optInt(2, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        boolean compatNotch = options.optBoolean(3, true);
        if (TextUtils.isEmpty(gameKey)) {
            Log.e(TAG, "OPERATE: init 4399 operate SDK error, game key invalid");
            return;
        }

        // 初始化选项，传入游戏配置，更多说明见接入文档
        OperateConfig operateConfig = new OperateConfig.Builder(activity)
                // 设置游戏运营 key，此参数需要在原创开放平台注册应用后得到
                .setGameKey(gameKey)
                // 设置SDK页面方向，应与游戏方向一致，部分第三方页面需要在AndroidManifest中设置
                .setOrientation(orientation)
                // 设置游戏是否兼在高于Android 9.0版本系统容全面屏，默认不兼容
                .compatNotch(compatNotch)
                .build();
        mOpeCenter.setConfig(operateConfig);

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // A1: 初始化SDK
                // 此过程中检查当前帐号是否在登录中，只有在init之后， isLogin()返回的状态才可靠
                // 注意：初始化完成后，其他接口才可用
                mOpeCenter.init(activity, new OperateCenter.OnInitGlobalListener() {
                    // 执行化结果处理
                    @Override
                    public void onInitFinished(boolean isLogin, User user) {
                        androidLog(String.format("[onInitFinished] %s, %s", isLogin, user));
                        callback.invoke(RetValue
                                .event("init_finished")
                                .user(user)
                                .more("isLogin", isLogin)
                                .toString(), true
                        );
                    }

                    /*
                     * 注销帐号的回调，游戏一般应在此回到登录场景
                     * fromUserCenter 区分是否是从悬浮窗-个人中心("4399游戏助手页面")注销的，若是则为true，不是为false
                     */
                    @Override
                    public void onUserAccountLogout(boolean fromUserCenter) {
                        androidLog(String.format("[onUserAccountLogout] fromUserCenter? %s", fromUserCenter));
                        callback.invoke(RetValue
                                .event("account_logout")
                                .more("fromUserCenter", fromUserCenter)
                                .toString(), true
                        );
                    }

                    // 个人中心里切换帐号的回调，游戏一般应在此回到选服场景（分区服），或者其他初始场景
                    @Override
                    public void onSwitchUserAccountFinished(boolean fromUserCenter, User user) {
                        androidLog(String.format("[onUserAccountLogout] fromUserCenter? %s, new user: %s", fromUserCenter, user));
                        callback.invoke(RetValue
                                .event("account_switch")
                                .user(user)
                                .more("fromUserCenter", fromUserCenter)
                                .toString(), true
                        );
                    }
                });
            }
        });
    }

    public void isLogin(IWebview iWebview, JSONArray args) {
        runOnUiThread(iWebview, new Runnable() {
            @Override
            public void run() {
                Callback callback = Callback.optCallback(iWebview, args);
                callback.invoke(RetValue
                                .event("check_login")
                                .more("isLogin", mOpeCenter.isLogin())
                                .toString(),
                        false);
            }
        });
    }

    public void getUser(IWebview iWebview, JSONArray args) {
        runOnUiThread(iWebview, new Runnable() {
            @Override
            public void run() {
                Callback callback = Callback.optCallback(iWebview, args);
                callback.invoke(RetValue
                                .event("get_user")
                                .user(mOpeCenter.getCurrentAccount())
                                .toString(),
                        false);
            }
        });
    }


    public void login(IWebview iWebview, JSONArray args) {
        Callback callback = Callback.optCallback(iWebview, args);
        runOnUiThread(iWebview, new Runnable() {
            @Override
            public void run() {
                mOpeCenter.login(iWebview.getActivity(), new OperateCenter.OnLoginFinishedListener() {
                    @Override
                    public void onLoginFinished(boolean success, int resultCode, User user) {
                        callback.invoke(RetValue
                                .event("account_login")
                                .user(user)
                                .more("success", success)
                                .more("resultCode", resultCode)
                                .toString()
                        );
                        androidLog(String.format(Locale.getDefault(),
                                "[onLoginFinished] success? %s, resultCode: %d, user: %s", success, resultCode, user));
                    }
                });
            }
        });
    }

    public void logout(IWebview iWebview, JSONArray args) {
        runOnUiThread(iWebview, new Runnable() {
            @Override
            public void run() {
                mOpeCenter.logout();
            }
        });
    }

    // money, mark, commodity, supportExcess
    public void recharge(IWebview iWebview, JSONArray args) {
        runOnUiThread(iWebview, new Runnable() {
            @Override
            public void run() {
                Callback callback = Callback.optCallback(iWebview, args);
                mOpeCenter.recharge(iWebview.getActivity(),
                        new Order(args.optInt(1), args.optString(2))
                                .commodity(args.optString(3, null))
                                .supportExcess(args.optBoolean(4, false)),
                        (success, resultCode, msg) -> {
                            androidLog(msg);
                            callback.invoke(RetValue
                                    .event("recharge_finished")
                                    .more("success", success)
                                    .more("resultCode", resultCode)
                                    .more("message", msg)
                                    .toString()
                            );
                        });
            }
        });
    }

    public void readArchive(IWebview iWebview, JSONArray args) {
        Callback callback = Callback.optCallback(iWebview, args);
        runOnUiThread(iWebview, new Runnable() {
            @Override
            public void run() {
                mOpeCenter.getArchiveStringSimple(new CloudArchive.SimpleStrGetListener() {
                    @Override
                    public void onSuccess(@NonNull String data) {
                        callback.invoke(RetValue
                                        .event("read_archive")
                                        //.more("data", Base64.encodeToString(data.getBytes(), Base64.NO_WRAP | Base64.URL_SAFE))
                                        .data(data)
                                        .toString(),
                                true);
                    }

                    @Override
                    public void onFailure(int resultCode, @NonNull String eMsg) {
                        callback.invoke(RetValue
                                        .event("read_archive")
                                        .more("resultCode", resultCode)
                                        .more("message", eMsg)
                                        .toString(),
                                true);
                    }
                });
            }
        });
    }

    private void runOnUiThread(IWebview iWebview, Runnable runnable) {
        Activity activity = iWebview.getActivity();
        if (activity != null) {
            activity.runOnUiThread(runnable);
        } else {
            Log.e(TAG, "OPERATE: Context not valid, is it instance of Activity");
        }
    }

    public void androidLog(IWebview iWebview, JSONArray args) {
        androidLog(String.valueOf(args));
    }

    private static final int LEN_MAX_CHARS = 2048;

    static void androidLog(String msg) {
        int index = 0;
        final int len = msg.length();
        if (len < LEN_MAX_CHARS)
            Log.e(TAG, msg);
        else {
            while (index < len) {
                if (len <= index + LEN_MAX_CHARS) {
                    Log.e(TAG, msg.substring(index));
                    index += len;
                } else {
                    Log.e(TAG, msg.substring(index, index + LEN_MAX_CHARS));
                    index += LEN_MAX_CHARS;
                }
            }
        }
    }
}
