package com.rnboat.framework;

import android.content.Intent;
import android.os.Bundle;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.google.gson.JsonElement;
import com.rnboat.framework.base.BaseActivity;
import com.rnboat.framework.base.BaseH5Activity;
import com.rnboat.framework.base.BaseRNActivity;
import com.rnboat.framework.model.BaseParamsConfig;
import com.tencent.bugly.crashreport.CrashReport;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by Castiel on 2018/3/30.
 */

public class DispatcherModule extends ReactContextBaseJavaModule {

    private static String MODULE_NAME = "Navigation";

    public DispatcherModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return MODULE_NAME;
    }

    @ReactMethod
    public void push(ReadableMap params) {
        ReadableNativeMap middleMap = (ReadableNativeMap) params;
        HashMap nativeMap = middleMap.toHashMap();
        BaseParamsConfig baseParamsConfig = BaseParamsConfig.decodeParams(nativeMap);
        if (baseParamsConfig != null) {
            if (baseParamsConfig.getOpenType().equals(BaseParamsConfig.OpenType.H5)) {
                Intent intent = new Intent(getCurrentActivity(), BaseH5Activity.class);
                intent.putExtra(BaseH5Activity.URL, baseParamsConfig.getHtmlUrl());
                getCurrentActivity().startActivity(intent);
            } else {
                Intent intent = new Intent(getCurrentActivity(), BaseRNActivity.class);
                intent.putExtra(BaseRNActivity.BUNDLE_MAIN_COMPONENT_NAME, baseParamsConfig.getComponentName());
                intent.putExtra(BaseRNActivity.BUNDLE_PATH, baseParamsConfig.getBundlePath());

                if (baseParamsConfig.getLaunchOptions() != null) {
                    Bundle bundle = new Bundle();
                    Set<Map.Entry<String, JsonElement>> entrySet = baseParamsConfig.getLaunchOptions().entrySet();
                    for (Map.Entry<String, JsonElement> s : entrySet) {
                        bundle.putString(s.getKey(), String.valueOf(s.getValue()));
                    }

                    intent.putExtra(BaseRNActivity.BUNDLE_LAUNCH_OPTIONS, bundle);
                }
                getCurrentActivity().startActivity(intent);
            }
        }
    }

    @ReactMethod
    public void reLaunch(final ReadableMap params) {
        if (getCurrentActivity() instanceof BaseRNActivity) {
            getCurrentActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ReadableNativeMap middleMap = (ReadableNativeMap) params;
                    HashMap nativeMap = middleMap.toHashMap();
                    BaseParamsConfig baseParamsConfig = BaseParamsConfig.decodeParams(nativeMap);
                    Bundle bundle = null;
                    if (baseParamsConfig.getLaunchOptions() != null) {
                        bundle = new Bundle();
                        Set<Map.Entry<String, JsonElement>> entrySet = baseParamsConfig.getLaunchOptions().entrySet();
                        for (Map.Entry<String, JsonElement> s : entrySet) {
                            bundle.putString(s.getKey(), String.valueOf(s.getValue()));
                        }
                    }
                    ((BaseRNActivity) getCurrentActivity()).reCreateNewInstance(baseParamsConfig.getBundlePath(), bundle);
                }
            });
        }
    }

    @ReactMethod
    public void pop(ReadableMap params) {
        ReadableNativeMap middleMap = (ReadableNativeMap) params;
        HashMap nativeMap = middleMap.toHashMap();
        BaseParamsConfig baseParamsConfig = BaseParamsConfig.decodeParams(nativeMap);
        if (baseParamsConfig != null) {
            getCurrentActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    getCurrentActivity().finish();
                }
            });
        }
    }

    @ReactMethod
    public void popToRoot(ReadableMap params) throws ClassNotFoundException {
        ReadableNativeMap middleMap = (ReadableNativeMap) params;
        HashMap nativeMap = middleMap.toHashMap();
        BaseParamsConfig baseParamsConfig = BaseParamsConfig.decodeParams(nativeMap);
        if (baseParamsConfig != null) {
            final Class<?> beReflectedClass = Class.forName(String.format("%s.MainActivity", ConfigManager.APP_PACKAGE_NAME));
            getCurrentActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Intent intent = new Intent(getCurrentActivity(), beReflectedClass);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    getCurrentActivity().startActivity(intent);
                    getCurrentActivity().overridePendingTransition(R.anim.slide_in_from_left, R.anim.slide_out_from_right);
                }
            });
        }
    }

    @ReactMethod
    public void testCrash(ReadableMap params) {
        if (params.getString("crashType").equals("java"))
            CrashReport.testJavaCrash();
        else if (params.getString("crashType").equals("native"))
            CrashReport.testNativeCrash();
        else
            CrashReport.testANRCrash();
    }

    @ReactMethod
    public void hideLoadingDialog(final int triggerNumber) {
        if (getCurrentActivity() != null && getCurrentActivity() instanceof BaseActivity) {
            getCurrentActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ((BaseActivity) getCurrentActivity()).hideLoadingDialog(triggerNumber);
                }
            });
        }
    }

    @ReactMethod
    public void showLoadingDialog() {
        if (getCurrentActivity() != null && getCurrentActivity() instanceof BaseActivity) {
            ((BaseActivity) getCurrentActivity()).showLoadingDialog();
        }
    }
}
