package com.gh.common.util;

import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_NEXT_TO;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_REQUIRE_REDIRECT;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_TO;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.gh.gamecenter.common.base.activity.ToolBarActivity;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.SplashScreenActivity;
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager;
import com.gh.gamecenter.common.avoidcallback.Callback;
import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.core.utils.ClassUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;

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

import java.util.Iterator;
import java.util.Set;

public class EntranceUtils {

    public static void jumpActivityCompat(Context context, Bundle bundle) {
        bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);

        if (HaloApp.getInstance().isRunningForeground || HaloApp.getInstance().isAlreadyUpAndRunning) {
            // 应用正在运行，前台或后台
            String to = bundle.getString(KEY_TO);
            Class<?> clazz = ClassUtils.forName(to);
            if (clazz == null) clazz = MainActivity.class;
            if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment
                ToolBarActivity.startFragmentNewTask(context, (Class<? extends ToolbarFragment>) clazz, bundle);
            } else {
                Intent intent1 = new Intent(context, clazz);
                intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                // 如果 activity 名称有 singleton 的就添加 reorder_to_front 标签 (有点粗暴有点蠢，但暂时就先这样吧 :C )
                if (clazz.getSimpleName().toLowerCase().contains("singleton")) {
                    intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                }
                intent1.putExtras(bundle);
                context.startActivity(intent1);
            }
        } else {
            // 应用未在运行
            context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
        }
    }

    public static void jumpActivity(Context context, Bundle bundle) {
        bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);

        if (HaloApp.getInstance().isRunningForeground) {
            // 应用正在运行，前台或后台
            String to = bundle.getString(KEY_TO);
            Class<?> clazz = ClassUtils.forName(to);
            if (clazz == null) clazz = MainActivity.class;
            if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment
                ToolBarActivity.startFragmentNewTask(context, (Class<? extends ToolbarFragment>) clazz, bundle);
            } else {
                Intent intent1 = new Intent(context, clazz);
                intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                // 如果 activity 名称有 singleton 的就添加 reorder_to_front 标签 (有点粗暴有点蠢，但暂时就先这样吧 :C )
                if (clazz.getSimpleName().toLowerCase().contains("singleton")) {
                    intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                }
                intent1.putExtras(bundle);
                context.startActivity(intent1);
            }
        } else {
            // 应用未在运行
            context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
        }
    }

    public static void jumpActivity(Context context, Bundle nextToBundle, Bundle bundle, Callback callback) {
        bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);

        if (HaloApp.getInstance().isRunningForeground) {
            // 应用正在运行，前台或后台
            String to = bundle.getString(KEY_TO);
            Class<?> clazz = ClassUtils.forName(to);
            if (clazz == null) clazz = MainActivity.class;
            if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment
                ToolBarActivity.startFragmentNewTask(context, (Class<? extends ToolbarFragment>) clazz, bundle);
            } else {
                Intent intent1 = new Intent(context, clazz);
                //TODO:添加FLAG_ACTIVITY_NEW_TASK会导致一跳转页面callback就被调用
                //intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent1.putExtras(bundle);

                AvoidOnResultManager.Companion.getInstance((AppCompatActivity) context)
                        .startForResult(intent1, callback);
            }
        } else {
            // 应用未在运行
            if (nextToBundle != null) {
                bundle.putBundle(KEY_NEXT_TO, nextToBundle);
            }
            context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
        }
    }

    public static void saveShortcut(String activityName, @Nullable Bundle bundle) {
        if (BuildConfig.DEBUG) {
            if (activityName.contains("MainActivity")) {
                SPUtils.setString(EntranceConsts.KEY_BUNDLE, "");
                return;
            }

            if (bundle == null) bundle = new Bundle();
            try {
                JSONObject json = new JSONObject();
                json.put(KEY_TO, activityName);
                json = getJsonFromBundle(bundle, json, null);
                Utils.toast(HaloApp.getInstance().getApplication(), "保存捷径成功");
                SPUtils.setString(EntranceConsts.KEY_BUNDLE, json.toString());
            } catch (Exception e) {
                e.printStackTrace();
                SPUtils.setString(EntranceConsts.KEY_BUNDLE, "");
            }
        }
    }

    /**
     * 将 Bundle 转为 Json
     */
    private static JSONObject getJsonFromBundle(Bundle bundle, JSONObject json, @Nullable JSONObject bundleWrapper) throws JSONException {
        Set<String> keys = bundle.keySet();

        for (String key : keys) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Object object = bundle.get(key);
                if (object instanceof Bundle) {
                    json = getJsonFromBundle((Bundle) object, json, new JSONObject());
                } else if (object instanceof Parcelable) {
                    String parcelableName = key + ":parcelable";
                    String parcelableType = object.getClass().getName();
                    String objectJsonString = GsonUtils.toJson(object);
                    JSONObject jObject = null;
                    jObject = new JSONObject(objectJsonString);

                    if (bundleWrapper != null) {
                        bundleWrapper.put(parcelableName, parcelableType);
                        bundleWrapper.put(key, jObject);
                    } else {
                        json.put(parcelableName, parcelableType);
                        json.put(key, jObject);
                    }
                } else {
                    if (bundleWrapper != null) {
                        bundleWrapper.put(key, JSONObject.wrap(bundle.get(key)));
                    } else {
                        json.put(key, JSONObject.wrap(bundle.get(key)));
                    }
                }
            }
        }

        if (bundleWrapper != null) {
            json.put(":bundle", bundleWrapper);
        }
        return json;
    }

    /**
     * 快捷地跳转到上次保存的页面
     */
    public static void jumpShortcut(Activity activity) {
        if (BuildConfig.DEBUG) {
            if (!hasShortcut()) return;

            Bundle bundle = new Bundle();
            try {
                JSONObject jsonObject = new JSONObject(SPUtils.getString(EntranceConsts.KEY_BUNDLE));
                getBundleFromJson(bundle, jsonObject, null);
            } catch (Exception e) {
                e.printStackTrace();
            }

            EntranceUtils.jumpActivity(activity, bundle);
        }
    }

    /**
     * 从 JSON 里还原 Bundle
     */
    private static void getBundleFromJson(Bundle bundle, JSONObject jsonObject, @Nullable Bundle bundleWithin) throws JSONException, ClassNotFoundException {
        Iterator<String> iter = jsonObject.keys();
        String parcelableName = "";
        while (iter.hasNext()) {
            String key = (String) iter.next();
            String value = jsonObject.getString(key);
            if (key.contains(":parcelable")) {
                parcelableName = value;
            } else if (key.contains(":bundle")) {
                getBundleFromJson(bundle, new JSONObject(value), new Bundle());
            } else {
                if (bundleWithin != null) {
                    if (!TextUtils.isEmpty(parcelableName)) {
                        Class<?> gClass = Class.forName(parcelableName);
                        bundleWithin.putParcelable(key, ((Parcelable) GsonUtils.fromJson(value, gClass)));
                    } else {
                        bundleWithin.putString(key, value);
                    }

                    // TODO 支持多层 bundle 嵌套
                    // TODO 直接用 GSON 提供的 Bundle Adapter https://github.com/google-gson/typeadapters/blob/master/android/src/main/java/BundleTypeAdapterFactory.java
                    if (!bundle.containsKey("normalFragmentBundle")) {
                        bundle.putBundle("normalFragmentBundle", bundleWithin);
                    }
                } else {
                    if (!TextUtils.isEmpty(parcelableName)) {
                        Class<?> gClass = Class.forName(parcelableName);
                        bundle.putParcelable(key, ((Parcelable) GsonUtils.fromJson(value, gClass)));
                    } else {
                        bundle.putString(key, value);
                    }
                }
            }
        }
    }

    public static boolean hasShortcut() {
        return !TextUtils.isEmpty(SPUtils.getString(EntranceConsts.KEY_BUNDLE));
    }
}
