package com.xg.navigation;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.react.bridge.Promise;
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.WritableArray;
import com.xg.navigation.bridge.BundleConverter;
import com.xg.navigation.bridge.PromiseUtil;
import com.xg.navigation.delegates.bottom.BaseBottomDelegate;
import com.xg.navigation.splash.SplashScreen;
import com.xg.navigation.util.NavigationUtil;
import com.xg.navigation.util.RxBus;
import com.xg.navigation.fragment.NavigationBottomDelegate;

import java.util.List;

import io.reactivex.functions.Consumer;
import me.yokeyword.fragmentation.ISupportFragment;


@SuppressWarnings("unused")
public class ReactNavigationModule extends ReactContextBaseJavaModule {

//    private static final Set<String> callBackIDSet = new ConcurrentSkipListSet<>();

    //    private static final ScheduledExecutorService mExecutorService = Executors.newScheduledThreadPool(3);
    @SuppressWarnings("FieldCanBeLocal")
    private final String NAME = "XGNavigation";
    private static final String ACTIVITY_PARAMS_BUNDLE = "ACTIVITY_PARAMS_BUNDLE";

    private Promise mRootPromise;

    ReactNavigationModule(ReactApplicationContext reactContext) {
        super(reactContext);
        //注册事件
        RxBus.getInstance().register(Boolean.class).subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(Boolean isComplete) throws Exception {
                PromiseUtil.resolveToJs(mRootPromise,isComplete);
                mRootPromise = null;
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                PromiseUtil.resolveToJs(mRootPromise,false);
                mRootPromise = null;
            }
        });
    }

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

    /**
     * 设置根Fragment
     * @param params 参数
     * @param animated  动画
     * @param promise  回调
     */
    @ReactMethod
    public void resetRoot(final ReadableMap params, final boolean animated, Promise promise) {

        if (params == null) {
            PromiseUtil.rejectToJs(promise,new RuntimeException("params is null"));
            return;
        }

        mRootPromise = promise;

        Intent intent = new Intent(NavigationApplication.instance, NavigationActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(ACTIVITY_PARAMS_BUNDLE, BundleConverter.toBundle(params));

        if (!CurrentActivityManager.getInstance().isActivityDestroyed()){
            CurrentActivityManager.getInstance().getActivity().reSetRootFragment(intent);
        }else {
            PromiseUtil.resolveToJs(mRootPromise,false);
            mRootPromise = null;
        }
    }

    /**
     * 打开一个新的Fragment
     * @param params  参数
     * @param animated  动画
     */
    @ReactMethod
    public void push(final ReadableMap params, boolean animated) {

        String pageType;
        String pagePath;
        String transitionsConfig;
        try {
            pageType = params.getString("pageType");
            pagePath = params.getString("pagePath");
            transitionsConfig = params.getString("transitionsConfig");
            NavigationUtil.push(pageType, pagePath, BundleConverter.toBundle(params), transitionsConfig, animated, false);
        } catch (Exception e) {
            Log.e("ReactNavigationModule", e.getLocalizedMessage());
        }
    }

    /**
     * 替换路由栈顶部Fragment
     * @param params  参数
     * @param animated  动画
     */
    @ReactMethod
    public void replaceStackTopRoute(final ReadableMap params, boolean animated){
        String pageType;
        String pagePath;
        String transitionsConfig;
        try {
            pageType = params.getString("pageType");
            pagePath = params.getString("pagePath");
            transitionsConfig = params.getString("transitionsConfig");
            NavigationUtil.push(pageType, pagePath, BundleConverter.toBundle(params), transitionsConfig, animated, true);
        } catch (Exception e) {
            Log.e("ReactNavigationModule", e.getLocalizedMessage());
        }
    }

    /**
     * 退出当前Fragment
     * @param animated  动画
     */
    @ReactMethod
    public void pop(boolean animated) {
        NavigationUtil.pop(animated);
    }

    /**
     * 退到根Fragment
     * @param animated  动画
     */
    @ReactMethod
    public void popToRoot(boolean animated) {
        NavigationUtil.popToRoot(animated);
    }

    /**
     * 跳转到指定已存在的Fragment
     * @param params 参数信息
     * @param animated  动画
     */
    @ReactMethod
    public void popToRoute(final ReadableMap params, final boolean animated) {
        if (CurrentActivityManager.getInstance().isActivityDestroyed()){
            return;
        }
        NavigationActivity activity = CurrentActivityManager.getInstance().getActivity();
        try {
            String uuid = params.getString("uniqueId");

            if (TextUtils.isEmpty(uuid)) {
                return;
            }

            List<Fragment> fragments = activity.getFragments();
            int size = fragments.size();

            if (size <= 1) {
                return;
            }

            Fragment toFragment = NavigationUtil.findFragmentById(fragments, uuid);
            if (toFragment == null) {
                return;
            }

            activity.getSupportDelegate().start((ISupportFragment) toFragment, ISupportFragment.SINGLETASK);

        } catch (Exception ignored) {
        }
    }

    /**
     * 设置对应Fragment 选中的下标
     * @param tabStack  参数
     * @param newIndex  选中的下标
     */
    @ReactMethod
    public void setTabBarSelectedIndex(final ReadableMap tabStack, final int newIndex) {

        String uuid;
        try {
            uuid = tabStack.getString("uniqueId");
        } catch (Exception e) {
            uuid = "";
        }

        NavigationUtil.setTabIndex(uuid,newIndex);
    }

    /**
     * 判断是否是子Fragment
     * @param route  参数信息
     * @param promise  回调  true表示是Tab页面，false表示是Tab页面内部的子页面
     */
    @ReactMethod
    public void isChildTab(final ReadableMap route, final Promise promise) {
        if (route == null) {
            PromiseUtil.resolveToJs(promise, false);
            return;
        }

        final String uuid;
        try {
            uuid = route.getString("uniqueId");
        } catch (Exception e) {
            PromiseUtil.resolveToJs(promise, false);
            return;
        }

        if (TextUtils.isEmpty(uuid)) {
            PromiseUtil.resolveToJs(promise, false);
            return;
        }
        if (CurrentActivityManager.getInstance().isActivityDestroyed()){
            PromiseUtil.rejectToJs(promise,new RuntimeException("activity has destroyed"));
            return;
        }
        NavigationActivity activity = CurrentActivityManager.getInstance().getActivity();
        List<Fragment> fragments = activity.getFragments();
        int size = fragments.size();
        for (int i = size - 1; i >= 0; --i) {
            final Fragment current = fragments.get(i);
            if (current == null) {
                continue;
            }
            if (current instanceof NavigationBottomDelegate) {

                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Fragment fragment = NavigationUtil.matchTabs((BaseBottomDelegate) current, uuid);
                        if (fragment != null) {
                            PromiseUtil.resolveToJs(promise, true);
                        } else {
                            PromiseUtil.resolveToJs(promise, false);
                        }
                    }
                });
                return;
            }
        }
        PromiseUtil.resolveToJs(promise, false);
    }

    /**
     * 获取整个路由栈（所有的Fragment）
     * @param promise  回调
     */
    @ReactMethod
    public void getRouteStack(Promise promise) {
        if (CurrentActivityManager.getInstance().isActivityDestroyed()){
            PromiseUtil.rejectToJs(promise,new RuntimeException("activity has destroyed"));
            return;
        }
        try {
            WritableArray writableArray = NavigationUtil.getFragments();
            if(null != writableArray) {
                PromiseUtil.resolveToJs(promise,writableArray);
            }else {
                PromiseUtil.rejectToJs(promise,new RuntimeException("activity has destroyed"));
            }
        } catch (Exception ignored) {
            PromiseUtil.rejectToJs(promise,ignored);
        }

    }

    @ReactMethod
    public void showLaunchImageOnWindow(Promise promise) {
        if (CurrentActivityManager.getInstance().isActivityDestroyed()){
            return;
        }
        SplashScreen.show(CurrentActivityManager.getInstance().getActivity(), R.mipmap.splash_screen);
    }

    @ReactMethod
    public void removeLaunchImageFromWindow(Promise promise) {
        if (CurrentActivityManager.getInstance().isActivityDestroyed()){
            return;
        }
        SplashScreen.hide(CurrentActivityManager.getInstance().getActivity());
    }

    @ReactMethod
    public void setTabBarItemBadgeValue(ReadableMap tabRoute, int tabIndex, String badgeValue) {
        try {
            String uuid = tabRoute.getString("uniqueId");

            if (TextUtils.isEmpty(uuid)) {
                return;
            }
            if (CurrentActivityManager.getInstance().isActivityDestroyed()){
                return;
            }
            List<Fragment> fragments = CurrentActivityManager.getInstance().getActivity().getFragments();
            Fragment toFragment = NavigationUtil.findFragmentById(fragments, uuid);
            if (toFragment == null) {
                return;
            }

            if (toFragment instanceof BaseBottomDelegate) {
                ((BaseBottomDelegate) toFragment).setTabBarItemBadgeValue(tabIndex, badgeValue);
            }
        } catch (Exception ignored) {

        }

    }

    /**
     * 弹出弹窗
     * @param alertConfig 弹窗的信息
     */
    @ReactMethod
    public void alert(final ReadableMap alertConfig) {
        NavigationUtil.alert(alertConfig);
    }

    /**
     * dismiss alert
     *
     * @param alertId  通过id来移除
     */
    @ReactMethod
    public void removeAlert(String alertId) {
        NavigationUtil.removeAlert(alertId);
    }

    /**
     * 判断弹窗状态，是否正在展示
     * @param alertId  编号
     * @param promise  回调
     */
    @ReactMethod
    public void alertIsShow(String alertId, Promise promise) {
        promise.resolve(NavigationUtil.alertIsShow(alertId));

    }

}
