package com.frame.base;

import android.app.Application;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;

import com.base.utils.Config;
import com.base.utils.base.BaseApp;
import com.base.utils.eventbusmodel.EventMimcRouse;
import com.base.utils.eventbusmodel.EventNoActivity;
import com.base.utils.eventbusmodel.EventRestartApp;
import com.base.utils.tools.android.ActivityUtil;
import com.base.utils.tools.android.LanguageUtil;
import com.base.utils.tools.android.LogUtil;
import com.base.utils.tools.android.SPUtil;
import com.base.utils.tools.exception.ExceptionCatchActivity;
import com.base.utils.tools.exception.ExceptionCatchUtil;
import com.base.utils.tools.java.FileUtil;
import com.frame.base.bean.BeanHeartbeat;
import com.frame.base.server.MyFrameService;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;

/**
 * 入口
 */

public abstract class FrameApp extends BaseApp {
    protected static FrameApp appInstance;

    /* 文件缓存的目录 */
    public String mAppDir;
    public String mPicturesDir;
    public String mVoicesDir;
    public String mVideosDir;
    public String mFilesDir;

    public static FrameApp getInstance() {
        return appInstance;
    }

    private void openTryException() {
        //设置异常捕获
        Thread.setDefaultUncaughtExceptionHandler(ExceptionCatchUtil.getInstance(appInstance, new ExceptionCatchUtil.OnExceptionHandleListener() {
            @Override
            public void onExceptionHandle(final Throwable throwable) {
                try {
                    FileUtil.saveExceptionToSDCard(appInstance, throwable);
                } catch (Exception e) {
                    e.printStackTrace();
                    LogUtil.err(FrameApp.class, "onExceptionHandle:" + e.getLocalizedMessage());
                }
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Looper.prepare();
                        //先停止所有服务
                        appInstance.stopService(new Intent(appInstance, MyFrameService.class));
                        //相关UI处理,跳转到异常展示页面
                        ActivityUtil.finishAllActivity();
                        Intent intent = new Intent(appInstance, ExceptionCatchActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra(ExceptionCatchActivity.INTENT_DATA_KEY, throwable);
                        appInstance.startActivity(intent);
                        //这种方法退出应用，是会保留某些后进程,例如:Service,Notifications等。
                        ActivityUtil.exit();
                        //ActivityUtil.exit(appInstance);
                        Looper.loop();
                    }
                }).start();

            }
        }));
    }

    @Override
    public void onCreate() {
        super.onCreate();
        appInstance = this;
        //注册EventBus
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        onConfig();                                                                //要求子类自己配置相关信息
        LanguageUtil.setAppLanguage(appInstance);                                  //语言
        ActivityUtil.registerActivityListener(appInstance);                        //Activity管理
        FileUtil.setAppFileDir();                                                  //设置App存储主目录
        // 初始化App目录
        initAppDir();
        if (Config.isOpenTryCatchException) {
            openTryException();                                                     //异常捕获,务必在开启Bugly之前调用
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(new Intent(appInstance, MyFrameService.class));
        } else {
            startService(new Intent(appInstance, MyFrameService.class));    //启动框架后台服务
        }
    }

    private void initAppDir() {
        File file = getExternalFilesDir(null);
        if (file != null && !file.exists()) {
            file.mkdirs();
        }
        if (file != null) {
            mAppDir = file.getAbsolutePath();
        }

        file = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        if (file != null && !file.exists()) {
            file.mkdirs();
        }
        if (file != null) {
            mPicturesDir = file.getAbsolutePath();
        }

        file = getExternalFilesDir(Environment.DIRECTORY_MUSIC);
        if (file != null && !file.exists()) {
            file.mkdirs();
        }
        if (file != null) {
            mVoicesDir = file.getAbsolutePath();
        }

        file = getExternalFilesDir(Environment.DIRECTORY_MOVIES);
        if (file != null && !file.exists()) {
            file.mkdirs();
        }
        if (file != null) {
            mVideosDir = file.getAbsolutePath();
        }

        file = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
        if (file != null && !file.exists()) {
            file.mkdirs();
        }
        if (file != null) {
            mFilesDir = file.getAbsolutePath();
        }
    }



    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        //消减 、 清除内存
        LogUtil.w(FrameApp.class, "onTerminate() level:" + level);
        if (level == Application.TRIM_MEMORY_RUNNING_MODERATE) {
            //程序健壮的运行
        } else if (level == Application.TRIM_MEMORY_UI_HIDDEN) {
            //程序UI被隐藏
            //FrameUtil.destroy();//如果在升级版本。就销毁
            ActivityUtil.setAppIsBackground(appInstance, true);
        } else if (level == Application.TRIM_MEMORY_RUNNING_CRITICAL) {
            //程序运行临界、危险
        }

    }

    @Override
    public void onTerminate() {
        // 程序终止的时候执行
        super.onTerminate();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        stopService(new Intent(appInstance, MyFrameService.class));
    }


    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        //监听系统语言发生了改变
        super.onConfigurationChanged(newConfig);
        String userLanguage = SPUtil.getAppLanguageString(this);
        //系统语言改变了应用保持之前设置的语言
        if (userLanguage != null) {
            LanguageUtil.switchAppLanguage(this, userLanguage);
        }
    }


    //收到异常捕获，用户关闭窗口并重启的事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventRestartApp(EventRestartApp restartAppEvent) {
        if (onFrameAppListener != null) {
            onFrameAppListener.onRestart(restartAppEvent);
        }
    }

    //收到程序被结束的事件（原理：把Activity收集起来，如果size等于0，则认为程序结束）
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventClearAllActivity(EventNoActivity eventNoActivity) {
        if (onFrameAppListener != null) {
            onFrameAppListener.onClear(eventNoActivity);
        }
    }

    //当Activity栈只留下一个Activity
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMimcRouse(EventMimcRouse eventMimcRouse) {
        if (onFrameAppListener != null) {
            onFrameAppListener.onMimcRouse(eventMimcRouse);
        }
    }

    public abstract void onConfig();

    public interface OnFrameAppListener {
        void onRestart(EventRestartApp restartApp);      //程序重启

        void onClear(EventNoActivity eventNoActivity);   //所有的Activity被清空

        void onHeartbeat(BeanHeartbeat heartbeat);       //心跳事件

        void onMimcRouse(EventMimcRouse eventMimcRouse);  //唤醒MIMC，当只剩下一个Activity的时候
    }

    public OnFrameAppListener getOnFrameAppListener() {
        return onFrameAppListener;
    }

    public OnFrameAppListener onFrameAppListener;

    public void setOnFrameAppListener(OnFrameAppListener onFrameAppListener) {
        this.onFrameAppListener = onFrameAppListener;
    }


    @Override
    public void onLowMemory() {
        // 低内存的时候执行
        super.onLowMemory();
        Log.e(FrameApp.class.getSimpleName(), "onLowMemory()");
    }

    @Override
    protected void finalize() throws Throwable {
        //最后结束
        super.finalize();
        Log.e(FrameApp.class.getSimpleName(), "finalize()");
    }
}