package com.xg.navigation.activities;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentationMagician;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ContentFrameLayout;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.modules.core.PermissionAwareActivity;
import com.facebook.react.modules.core.PermissionListener;
import com.xg.navigation.NavigationApplication;
import com.xg.navigation.R;
import com.xg.navigation.bridge.MyReactActivityDelegate;
import com.xg.navigation.constants.NavigationConstants;
import com.xg.navigation.debug.DebugStackDelegate;
import com.xg.navigation.delegates.BaseDelegate;
import com.xg.navigation.splash.SplashScreen;
import com.xg.navigation.util.NavigationUtil;
import com.xg.navigation.util.SPUtil;

import java.util.ArrayList;
import java.util.List;

import me.yokeyword.fragmentation.ExtraTransaction;
import me.yokeyword.fragmentation.Fragmentation;
import me.yokeyword.fragmentation.ISupportActivity;
import me.yokeyword.fragmentation.SupportActivityDelegate;
import me.yokeyword.fragmentation.anim.DefaultHorizontalAnimator;
import me.yokeyword.fragmentation.anim.FragmentAnimator;

import static java.lang.System.exit;

public abstract class ProxyActivity extends AppCompatActivity implements ISupportActivity,PermissionAwareActivity {
    private static final String TAG = "ProxyActivity";
    private DebugStackDelegate mDebugStackDelegate;
    private final SupportActivityDelegate DELEGATE = new SupportActivityDelegate(this);
    private MyReactActivityDelegate mDelegate;
    private boolean mHasSetRoot;
    public abstract BaseDelegate setRootDelegate(Intent intent);

    public abstract String setRootTag(Intent intent);

    public abstract void init();

    public abstract String getMainComponentName();

    public abstract int splashRes();
    /**
     * 获取对应的pagePath
     * @param target
     * @return
     */
    public abstract String getPagePath(String target);

    /**
     * 获取对应的pageType
     * @param target
     * @return
     */
    public abstract String getPageType(String target);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SplashScreen.show(this,splashRes());
        DELEGATE.onCreate(savedInstanceState);
        mDebugStackDelegate = new DebugStackDelegate(this);
        mHasSetRoot = false;
        initReact(savedInstanceState);
        init();
        ContentFrameLayout container = new ContentFrameLayout(this);
        container.setId(R.id.delegate_container);
        setContentView(container);
        Log.i(TAG, "onCreate: ");
    }

    private void initReact(Bundle savedInstanceState){
        String mainComponentName = getMainComponentName();
        mDelegate = new MyReactActivityDelegate(this, mainComponentName);
        SPUtil.put(NavigationApplication.instance, NavigationConstants.MAIN_COMPONENT_NAME, mainComponentName);
        mDelegate.onCreate(savedInstanceState);
    }

    public void reSetRootFragment(final Intent intent){
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(!getSupportFragmentManager().isStateSaved()) {
                    getSupportFragmentManager().popBackStackImmediate(null, 1);
                }
                BaseDelegate baseDelegate = setRootDelegate(intent);
                DELEGATE.extraTransaction()
                        .setTag(setRootTag(intent))
                        .loadRootFragment(R.id.delegate_container, baseDelegate);
                if(!mHasSetRoot) {
                    outLinkJump();
                }
                mHasSetRoot = true;
            }
        });
        SplashScreen.hide(this);
    }

    @Override
    protected void onDestroy() {
        DELEGATE.onDestroy();
        mDelegate.onDestroy();
        super.onDestroy();
        System.gc();
        System.runFinalization();
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        Log.i(TAG, "onPostCreate: ");
//        DELEGATE.onPostCreate(savedInstanceState);
        mDebugStackDelegate.onPostCreate();

    }

    @Override
    public SupportActivityDelegate getSupportDelegate() {
        return DELEGATE;
    }

    @Override
    public ExtraTransaction extraTransaction() {
        return DELEGATE.extraTransaction();
    }

    @Override
    public FragmentAnimator getFragmentAnimator() {
        return DELEGATE.getFragmentAnimator();
    }

    @Override
    public void setFragmentAnimator(FragmentAnimator fragmentAnimator) {
        DELEGATE.setFragmentAnimator(new DefaultHorizontalAnimator());
    }

    @Override
    public FragmentAnimator onCreateFragmentAnimator() {
        return DELEGATE.onCreateFragmentAnimator();
    }

    @Override
    public void post(Runnable runnable) {
        DELEGATE.post(runnable);
    }

    @Override
    public void onBackPressedSupport() {
        if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
            DELEGATE.pop();
        } else {
//            ActivityCompat.finishAfterTransition(this);
            exit(0);
        }
    }

    @Override
    public void onBackPressed() {
        DELEGATE.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mDelegate.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mDelegate.onResume();
        Log.i(TAG, "onResume: ");
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        mDelegate.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public void onNewIntent(Intent intent) {
        if (!mDelegate.onNewIntent(intent)) {
            super.onNewIntent(intent);
        }
    }

    @Override
    public void requestPermissions(
            String[] permissions,
            int requestCode,
            PermissionListener listener) {
        mDelegate.requestPermissions(permissions, requestCode, listener);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        mDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    protected final ReactNativeHost getReactNativeHost() {
        return mDelegate.getReactNativeHost();
    }

    protected final ReactInstanceManager getReactInstanceManager() {
        return mDelegate.getReactInstanceManager();
    }

    /**
     * 获取子路由
     */
    public List<Fragment> getFragments() {
        List<Fragment> fragments = new ArrayList<>();
        try {
            fragments =  FragmentationMagician.getActiveFragments(getSupportFragmentManager());
        } catch (Exception ignored) {
        }

        return fragments;
    }
    /**
     * 外部链接跳转处理
     */
    private void outLinkJump(){
        Intent intent = getIntent();
        Uri uri = intent.getData();
        if(null == uri){
            return;
        }
        String pagePath = uri.getQueryParameter("p");
        if(TextUtils.isEmpty(pagePath)){
            // 如果传参没有带targetPath, 那么没必要再进行跳转
            return;
        }
        // 目标path
        String targetPath = getPagePath(pagePath);
        // 目标的页面类型
        String targetPageType = getPageType(pagePath);
        if(TextUtils.isEmpty(targetPath) || TextUtils.isEmpty(targetPageType)){
            return;
        }
        // 如果NavigationActivity已经起来了, 销毁当前的Activity
        // 直接进行跳转的工作
        Bundle params = new Bundle();
        for(String key: uri.getQueryParameterNames()){
            if(!NavigationConstants.PATH_KEY.equals(key)){
                params.putString(key, uri.getQueryParameter(key));
            }
        }
        NavigationUtil.push(targetPageType, targetPath, NavigationConstants.FROM_RIGHT, true, params);
    }
}
