package com.tofly.ghrq_route.base.ui;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import androidx.annotation.LayoutRes;

import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.mgq.base.utils.net.NetworkStatus;
import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.base.BaseApp;
import com.tofly.ghrq_route.module.OfflineWork.OfflineWorkTool;
import com.tofly.ghrq_route.module.OfflineWork.domain.OfflineWorkEvent;
import com.tofly.ghrq_route.module.systemConfig.domain.SystemConfigEvent;
import com.tofly.ghrq_route.module.user.UserInfoTool;
import com.tofly.ghrq_route.common.ui.activity.UiLogin;
import com.tofly.ghrq_route.common.ui.activity.UiMain;
import com.tofly.ghrq_route.common.ui.activity.UiRegisterAccount;
import com.tofly.ghrq_route.common.ui.activity.UiSetting;
import com.tofly.ghrq_route.common.ui.activity.UiSign;
import com.tofly.ghrq_route.common.ui.dialog.ConnectHintDialog;
import com.tofly.ghrq_route.common.util.EventBusUtil;
import com.tofly.ghrq_route.common.util.app.AppUtil;
import com.tofly.ghrq_route.common.util.sharedPreference.SharePreUtil;

import org.greenrobot.eventbus.Subscribe;

import java.util.List;

/**
 * Created by zombiexq on 2016/6/13.
 */
public abstract class BaseUi extends AppCompatActivity {

    protected BaseApp app;

    protected boolean showLoadBar = false;
    protected boolean showDebugMsg = true;
    private boolean bPaddingTop = true;
    private Toast toast;
    private CollapsingToolbarLayout collapsingToolbarLayout;
    private Toolbar toolbar;
    private ActionBar actionBar;
    private LinearLayout layoutTopErrorArea;
    private TextView textTopErrorHint;
    private TextView textTopErrorAct;
    private String strTitle = "";
    private View.OnClickListener mNavClickListener;
    protected InputMethodManager inputMethodManager;
    //private Snackbar downloadsb;

    public static final String MAIN_TITLE_KEY = "title";

    protected CollapsingToolbarLayoutState state;

    protected enum CollapsingToolbarLayoutState {
        EXPANDED,
        COLLAPSED,
        INTERNEDIATE
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // debug memory
        debugMemory("onCreate");
        // async task handler
        inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        // init application
        this.app = (BaseApp) this.getApplicationContext();
        app.addActivity(this);

        BaseApp.getInstance().getLoginUser();

        getLastForceRestart();

        // close strict mode for special device
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());

        EventBusUtil.register(this);
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);
        Bundle bundle = getIntent().getExtras();
        if (bundle != null){
            String title = bundle.getString(MAIN_TITLE_KEY, "");
            setToolbarTitle(title);
        }
        initToolbar();
        initTopErrorBar();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // debug memory
        debugMemory("onResume");
        showTopErrorBar(OfflineWorkTool.isOffline());
        if (!(this instanceof UiLogin) && !(this instanceof UiSetting) && !(this instanceof UiRegisterAccount) )
            BaseApp.getInstance().startBackgroundOfflineWorkService(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // debug memory
        debugMemory("onPause");
    }

    @Override
    protected void onStart() {
        super.onStart();
        // debug memory
        debugMemory("onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        // debug memory
        debugMemory("onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        EventBusUtil.unregister(this);

        ConnectHintDialog hintDialog = BaseApp.getInstance().getConnectHintDialog();
        if (hintDialog != null){
            hintDialog.dismissDialog();
        }

        //结束Activity&从栈中移除该Activity
        app.finishActivity(this);
    }

    @Subscribe()
    public void onOfflineEvent(OfflineWorkEvent offlineWorkEvent) {
        switch (offlineWorkEvent.getEvent()) {
            case OfflineWorkEvent.DEVICE_IS_OFFLINE:
                showTopErrorBar(true);
                setTopErrorActShow(false);
                String strWarn = getResources().getString(R.string.connect_server_error);
                setTopErrorHintText(strWarn);
                break;
            case OfflineWorkEvent.DEVICE_IS_ONLINE:
                showTopErrorBar(false);
                break;
            case OfflineWorkEvent.SERVER_IS_REACHABLE: {
                boolean isReachAble = (boolean) offlineWorkEvent.getObject();
                int connect_type = isReachAble ? BaseApp.ConnectType.CONNECT_SERVER_CONNECTED
                        : BaseApp.ConnectType.CONNECT_SERVER_DISCONNECTED;
                BaseApp.getInstance().showConnectHintDialog(this, connect_type);
                break;
            }
            case OfflineWorkEvent.NETWORK_IS_REACHABLE: {
                boolean isReachAble = (boolean) offlineWorkEvent.getObject();
                int connect_type = isReachAble ? BaseApp.ConnectType.CONNECT_NETWORK_CONNECTED
                        : BaseApp.ConnectType.CONNECT_NETWORK_DISCONNECTED;
                BaseApp.getInstance().showConnectHintDialog(this, connect_type);
                break;
            }
        }
    }

    @Subscribe()
    public void onSysconfigEvent(SystemConfigEvent systemConfigEvent){
        if (systemConfigEvent.getEvent().equals(SystemConfigEvent.SYSTEM_BACKUP_SERVER_CHANGED)){
            boolean isOpen = (boolean) systemConfigEvent.getObject();
            if (BaseApp.getInstance().isAppForeground()){
                int msg_res = isOpen ? R.string.backup_server_open : R.string.backup_server_close;
                showAlertWithConfirmButton(R.string.backup_server_mode, msg_res, false, null);
            }
        }
    }

    protected void reload() {
        finish();
        startActivity(getIntent());
    }

    protected void gotoSystemHome() {
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        homeIntent.addCategory(Intent.CATEGORY_HOME);
        startActivity(homeIntent);
    }

    private void getLastForceRestart(){
        if (!(this instanceof UiMain)){
            boolean bLastForceRestart = SharePreUtil.getAppForceRestart(this);
            if (bLastForceRestart){
                int signState = SharePreUtil.getLastSignState(this);
                /*已签到还未签退,开启实时位置信息上传服务*/
                if (signState == UiSign.SIGN_CHECKED_ON_TYPE) {
                    BaseApp.getInstance().startAllBackgroundService(this);
                } else {
                    BaseApp.getInstance().stopBackgroundService(this);
                }
                SharePreUtil.setAppForceRestart(this, false);
            }
        }else {
            SharePreUtil.setAppForceRestart(this, false);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // util method

    private void initToolbar(){
        toolbar = findViewById(R.id.main_toolbar);
        collapsingToolbarLayout = findViewById(R.id.layout_collapse_toolbar);
        if (toolbar != null){
            if (strTitle.isEmpty())
                strTitle = getTitle().toString();
            //if (/*!strTitle.isEmpty()*/true)
            toolbar.setTitle(strTitle);

            setSupportActionBar(toolbar);
            actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.setDisplayHomeAsUpEnabled(true);
            }
            toolbar.setNavigationOnClickListener(v -> {
                if (mNavClickListener != null){
                    mNavClickListener.onClick(v);
                }else {
                    BaseUi.this.finish();
                }
            });
        }
    }

    @TargetApi(19)
    public void setTranslucentStatus() {
        if (true)
            return;

        Window window = getWindow();
        int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
        WindowManager.LayoutParams attributes = window.getAttributes();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.addFlags(flagTranslucentStatus);
            window.addFlags(flagTranslucentNavigation);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        } else {
            attributes.flags |= flagTranslucentStatus | flagTranslucentNavigation;
            window.setAttributes(attributes);
        }
    }

    public void setDarkStatusBar() {
        Window window = getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
    }

    public void setLightStatusBar() {
        Window window = getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
    }

    public void setToolbarPadding() {
        Window window = getWindow();
/*        if (toolbar != null) {
            setToolBarPaddingHeight(window, toolbar);
        }*/
/*        if (collapsingToolbarLayout != null) {
            setCollapseToolbarMairgin(window, collapsingToolbarLayout);
        }*/
    }

    public static void setCollapseToolbarMairgin(Window window, CollapsingToolbarLayout toolbarLayout) {
        //TODO: 代码设置标题栏paddingtop为状态栏的高
        int statusBarHeight = getStatusBarHeight(window.getContext());
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
            AppBarLayout.LayoutParams layoutParams = (AppBarLayout.LayoutParams) toolbarLayout.getLayoutParams();
            layoutParams.topMargin = statusBarHeight;
            toolbarLayout.setLayoutParams(layoutParams);
        }
    }

    public static void setToolBarPaddingHeight(Window window, View view) {
        //TODO: 代码设置标题栏paddingtop为状态栏的高
        int statusBarHeight = getStatusBarHeight(window.getContext());
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = layoutParams.height + statusBarHeight;
        view.setLayoutParams(layoutParams);
        view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());
    }

    public static int getStatusBarHeight(Context context) {
        //TODO: 算取状态栏的高
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    public static int getNavigationBarHeight(Context var0) {
        boolean var1 = ViewConfiguration.get(var0).hasPermanentMenuKey();
        int var2;
        return (var2 = var0.getResources().getIdentifier("navigation_bar_height", "dimen", "android")) > 0 && !var1?var0.getResources().getDimensionPixelSize(var2):0;
    }

    public static int getDialogHeight(Context context) {
        int screenHeight = getScreenHeight(context) - getStatusBarHeight(context) - getNavigationBarHeight(context);
        int dialogHeight = screenHeight;
        return dialogHeight;
    }

    public static int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Point point = new Point();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            wm.getDefaultDisplay().getRealSize(point);
            return point.y;
        } else {
            DisplayMetrics outMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(outMetrics);
            return outMetrics.heightPixels;
        }
    }

    private void initTopErrorBar(){
        layoutTopErrorArea = findViewById(R.id.layout_top_error);
        textTopErrorHint = findViewById(R.id.text_connect_error_hint);
        textTopErrorAct = findViewById(R.id.text_connect_error_act);
    }

    public void showTopErrorBar(boolean show){
        if (layoutTopErrorArea != null)
            layoutTopErrorArea.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    public void setTopErrorHintText(String hint){
        if (textTopErrorHint != null)
            textTopErrorHint.setText(hint);
    }

    public TextView getTextTopErrorAct(){
        return textTopErrorAct;
    }

    public void setTopErrorActShow(boolean show){
        if (textTopErrorAct != null)
            textTopErrorAct.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    public void setTopErrorActClicked(View.OnClickListener listener){
        if (textTopErrorAct != null){
            textTopErrorAct.setOnClickListener(listener);
        }
    }

    public void checkUserMapConfig(){
        final UserInfoTool userInfoTool = UserInfoTool.getInstance();
        boolean hasConfig = userInfoTool.hasLocalUserMapConfig(this.getClass().getSimpleName());
        if (!hasConfig){
            showTopErrorBar(true);
            String strWarn = getResources().getString(R.string.main_load_usermap_err);
            setTopErrorHintText(strWarn);
            if (textTopErrorAct != null){
                textTopErrorAct.setVisibility(View.VISIBLE);
                textTopErrorAct.setOnClickListener(v -> {
                    textTopErrorAct.setEnabled(false);
                    /*userInfoTool.getUserMapConfigData(BaseUi.this, new UserCallBack(){
                        @Override
                        public void onGetMapConfigData(boolean isSuccess, int errorCode, String errMsg, MapUrlConfigDataBean urlConfigDataBean, List<UserMapDataBean> userMapDataBeanList) {
                            textTopErrorAct.setEnabled(true);
                            if (isSuccess){
                                showTopErrorBar(false);
                                setTopErrorActShow(false);
                            }else {
                                errMsg = BaseApp.formatErrorMessage(errorCode, errMsg);
                                String strWarn = getResources().getString(R.string.main_load_usermap_err)  + errMsg;
                                toast(strWarn);
                            }
                        }
                    });*/
                    BaseApp.getInstance().forceRestartApp();
                });
            }
        }
    }

    public boolean isNetworkConnected(){
        return NetworkStatus.isNetworkConnected(this);
    }

    @SuppressLint("ShowToast")
    public void toast(String msg) {
        if (toast == null) {
            toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
        }else {
            toast.setText(msg);
        }
        toast.show();
    }

    @SuppressLint("ShowToast")
    public void toast(int msgId) {
        if (toast == null) {
            toast = Toast.makeText(this, msgId, Toast.LENGTH_SHORT);
        }else {
            toast.setText(msgId);
        }
        toast.show();
    }

    public void overlay(Class<?> classObj) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        intent.setClass(this, classObj);
        startActivity(intent);
    }

    public void overlay(Class<?> classObj, Bundle params) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        intent.setClass(this, classObj);
        intent.putExtras(params);
        startActivity(intent);
    }

    public void overlay_to(Class<?> classObj) {
        overlay_to(classObj, null);
    }

    public void overlay_to(Class<?> classObj, Bundle bundle) {
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.setClass(this, classObj);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
        overridePendingTransition(0, R.anim.anim_leftout);
    }

    public void forward(Class<?> classObj) {//跳转封装方法
        Intent intent = new Intent();
        intent.setClass(this, classObj);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        this.startActivity(intent);
        this.finish();
    }

    public void forward(final Class<?> classObj, Object object) {

    }

    public void forward(Class<?> classObj, Bundle params) {
        Intent intent = new Intent();
        intent.setClass(this, classObj);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtras(params);
        this.startActivity(intent);
        this.finish();
    }

    public Context getContext() {
        return this;
    }

    public Toolbar getToolbar() { return toolbar; }

    public String getStringById(int resId){
        return getResources().getString(resId);
    }

    public void setToolbarTitle(String title){
        strTitle = title;
    }

    public void setOnNavigationClickListener(View.OnClickListener listener){
        mNavClickListener = listener;
    }

    public void showLoadBar() {
        this.findViewById(R.id.main_load_bar).setVisibility(View.VISIBLE);
        this.findViewById(R.id.main_load_bar).bringToFront();
        showLoadBar = true;
    }

    public void hideLoadBar() {
        if (showLoadBar) {
            this.findViewById(R.id.main_load_bar).setVisibility(View.GONE);
            showLoadBar = false;
        }
    }

    public void showAlertDialog(int title, int msg, DialogInterface.OnClickListener onClickListener) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(title);
        builder.setMessage(msg);
        builder.setPositiveButton(android.R.string.ok, onClickListener);
        builder.setNegativeButton(android.R.string.cancel, null);
        builder.show();
    }

    public void showAlertDialog(String title, String msg, DialogInterface.OnClickListener onClickListener) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(title);
        builder.setMessage(msg);
        builder.setPositiveButton(android.R.string.ok, onClickListener);
        builder.setNegativeButton(android.R.string.cancel, null);
        builder.show();
    }

    public AlertDialog showAlertWithConfirmButton(int titleId, int messageId, boolean cancelable,
                                             final DialogInterface.OnClickListener listener ){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(titleId);
        builder.setMessage(messageId);
        builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
            if (listener != null)
                listener.onClick(dialog, which);
        });
        builder.setCancelable(cancelable);
        return builder.show();
    }

    public void showAlertWithConfirmButton(String title, String message, boolean cancelable,
                                           final DialogInterface.OnClickListener listener ){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(title);
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
            if (listener != null)
                listener.onClick(dialog, which);
        });
        builder.setCancelable(cancelable);
        builder.show();
    }

    public void showAlertWithConfirmCancelButton(int titleId, int messageId, boolean cancelable,
                                           final DialogInterface.OnClickListener listener ){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(titleId);
        builder.setMessage(messageId);
        builder.setPositiveButton(android.R.string.ok, listener);
        builder.setNegativeButton(android.R.string.cancel, null);
        builder.setCancelable(cancelable);
        builder.show();
    }

    public void showAlertWithConfirmCancelButton(String title, String message, boolean cancelable,
                                                 final DialogInterface.OnClickListener listener ){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(title);
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok, listener);
        builder.setNegativeButton(android.R.string.cancel, null);
        builder.setCancelable(cancelable);
        builder.show();
    }

    public boolean isForeground() {
        String className = getClass().getName();
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
        if (list != null && list.size() > 0) {
            ComponentName cpn = list.get(0).topActivity;
            return className.equals(cpn.getClassName());
        }
        return false;
    }

    public String getForegroundClassName(){
        String className = "";
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
        if (list != null && list.size() > 0) {
            ComponentName cpn = list.get(0).topActivity;
            className = cpn.getClassName();
        }
        return className;
    }

    public void hideSoftKeyboard() {
        if (getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {
            if (getCurrentFocus() != null)
                inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /*public void onNetworkError(int taskId) {
        toast(C.err.network);
    }*/

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // debug method

    public void debugMemory(String tag) {
        if (this.showDebugMsg) {

            Log.w(this.getClass().getSimpleName(), tag + ":" + AppUtil.getUsedMemory());
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // common classes


}
