package com.rnboat.framework.base;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;

import com.facebook.quicklog.identifiers.ReactNativeBridge;
import com.facebook.react.BuildConfig;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import com.rnboat.framework.ConfigManager;
import com.rnboat.framework.model.FrameworkConfig;
import com.rnboat.framework.util.AppUtils;
import com.rnboat.framework.util.DataUtil;

import java.util.ArrayList;

//import com.qianmi.qmlogger.QMLog;

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

public class BaseRNActivity extends ReactActivity {
    private static final String TAG = "BaseRNActivity";
    public static final String BUNDLE_MAIN_COMPONENT_NAME = "BUNDLE_MAIN_COMPONENT_NAME";
    public static final String BUNDLE_PATH = "BUNDLE_PATH";
    public static final String BUNDLE_LAUNCH_OPTIONS = "BUNDLE_LAUNCH_OPTIONS";
    public boolean onDebugSuccess = false;
    private Bundle savedInstanceState;
    private FrameworkConfig.FrameworkState mCurrentActivityState;
    private int clickDebugCount = 0;
    private ArrayList lstNoPropagatedKeyCodes;
    public static final int OVERLAY_PERMISSION_REQ_CODE = 1000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.savedInstanceState = savedInstanceState;
        checkPerms();
    }

    public void checkPerms() {
        // Checking if device version > 22 and we need to use new permission model
        // Checking if we can draw window overlay
        if (ConfigManager.DEBUG &&
                Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1 &&
                !Settings.canDrawOverlays(this)) {
            // Requesting permission for window overlay(needed for all react-native apps)
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
        }
        else {
            createReactActivityDelegate(getIntent().getStringExtra(BUNDLE_PATH), getIntent().getBundleExtra(BUNDLE_LAUNCH_OPTIONS), savedInstanceState);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            checkPerms();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
//        QMLog.e(TAG, getMainComponentName());
    }

    public void setCurrentActivityState(FrameworkConfig.FrameworkState mCurrentActivityState) {
        this.mCurrentActivityState = mCurrentActivityState;
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (this.mCurrentActivityState != null) {
            FrameworkConfig.State = this.mCurrentActivityState;
        }
    }

    public void reCreateNewInstance(String bundlePath, Bundle launchOptions) {
        mDelegate.onDestroy();
        createReactActivityDelegate(bundlePath, launchOptions, savedInstanceState);
        mDelegate.getReactNativeHost().getReactInstanceManager().onHostResume(
                this,
                this);
    }

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        String bundleName = getIntent().getStringExtra(BUNDLE_MAIN_COMPONENT_NAME);
        if (bundleName == null) {
            return ConfigManager.DEFAULT_MAIN_COMPONENT_NAME;
//            QMLog.e(TAG, "please set the BUNDLE_MAIN_COMPONENT_NAME");
        }
        return bundleName;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus == true) {
            Log.e(TAG, "onWindowFocusChanged");
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP: {
                if (ev.getRawX() > getWindowManager().getDefaultDisplay().getWidth() - 100 &&
                        ev.getRawY() > getWindowManager().getDefaultDisplay().getHeight() - 100) {
                    if (clickDebugCount == 0) {
                        timer.start();
                    }
                    clickDebugCount++;
                    Log.e(TAG, "clickDebugCount->" + String.valueOf(clickDebugCount));
                }
                break;
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    private CountDownTimer timer = new CountDownTimer(5000, 200) {
        private boolean trigger = false;
        @Override
        public void onTick(long millisUntilFinished) {
            if (clickDebugCount >= ConfigManager.DEBUG_CLICK_COUNT && !trigger) {
                trigger = true;
                Log.e(TAG, ConfigManager.MSG_DEBUG);
                if (mDelegate != null && mDelegate.getReactInstanceManager() != null && mDelegate.getReactInstanceManager().getCurrentReactContext() != null)
                    mDelegate.getReactInstanceManager().getCurrentReactContext().getJSModule(RCTNativeAppEventEmitter.class).emit(ConfigManager.MSG_DEBUG, null);
            }
        }

        @Override
        public void onFinish() {
            if (clickDebugCount >= ConfigManager.DEBUG_CLICK_COUNT && !onDebugSuccess) {
                Intent finishIntent = new Intent();
                finishIntent.setAction(RNBoatApplication.APP_FINISH_ACTION);
                sendBroadcast(finishIntent);
            }
            clickDebugCount = 0;
            onDebugSuccess = false;
            trigger = false;
            Log.e(TAG, "CountDownTimer onFinish");
        }
    };

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        onKeyDownEvent(keyCode, event);
        if (!shouldPropagated(keyCode))
            return true;
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        onKeyUpEvent(keyCode, event);
        if (!shouldPropagated(keyCode))
            return true;
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
        onKeyMultipleEvent(keyCode, repeatCount, event);
        if (!shouldPropagated(keyCode))
            return true;
        return super.onKeyMultiple(keyCode, repeatCount, event);
    }

    public void onKeyDownEvent(int keyCode, KeyEvent keyEvent) {
        if (mDelegate != null && mDelegate.getReactInstanceManager() != null && mDelegate.getReactInstanceManager().getCurrentReactContext() != null)
            mDelegate.getReactInstanceManager().getCurrentReactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(ConfigManager.ON_KEY_DOWN, DataUtil.getJsEventParams(keyCode, keyEvent, null));
    }

    public void onKeyUpEvent(int keyCode, KeyEvent keyEvent) {
        if (mDelegate != null && mDelegate.getReactInstanceManager() != null && mDelegate.getReactInstanceManager().getCurrentReactContext() != null)
            mDelegate.getReactInstanceManager().getCurrentReactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(ConfigManager.ON_KEY_UP, DataUtil.getJsEventParams(keyCode, keyEvent, null));
    }

    public void onKeyMultipleEvent(int keyCode, int repeatCount, KeyEvent keyEvent) {
        if (mDelegate != null && mDelegate.getReactInstanceManager() != null && mDelegate.getReactInstanceManager().getCurrentReactContext() != null)
            mDelegate.getReactInstanceManager().getCurrentReactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(ConfigManager.ON_KEY_MULTIPLE, DataUtil.getJsEventParams(keyCode, keyEvent, repeatCount));
    }

    public void setOnDebugSuccess(boolean onDebugSuccess) {
        this.onDebugSuccess = onDebugSuccess;
    }

    public void setNoPropagatedKeyCodes(ArrayList lstNoPropagatedKeyCodes) {
        this.lstNoPropagatedKeyCodes = new ArrayList(lstNoPropagatedKeyCodes);
    }

    public boolean shouldPropagated(int keyCode) {
        if (lstNoPropagatedKeyCodes != null) {
            return !lstNoPropagatedKeyCodes.contains((double)keyCode);
        }
        return true;
    }

    @Override
    protected void onDestroy() {
        timer.cancel();
        timer = null;
        super.onDestroy();
    }
}
