package com.bonait.bnframework.business;

import android.app.Activity;
import android.app.Application;
import android.util.Log;

import com.bonait.bnframework.BuildConfig;
import com.bonait.bnframework.common.constant.ConfigName;
import com.bonait.bnframework.common.constant.Constants;
import com.bonait.bnframework.common.constant.DataBus;
import com.bonait.bnframework.common.db.QueryDB;
import com.bonait.bnframework.common.db.file.DBHelper;
import com.bonait.bnframework.common.db.mode.BPA_ALERTLOG;
import com.bonait.bnframework.common.db.mode.BPA_CLOUDDATA;
import com.bonait.bnframework.common.db.mode.BPA_GOODS;
import com.bonait.bnframework.common.db.mode.BPA_GOODSRECIPE;
import com.bonait.bnframework.common.db.mode.BPA_LOG;
import com.bonait.bnframework.common.db.mode.BPA_PLCADDRESS;
import com.bonait.bnframework.common.db.mode.BPA_SILOS;
import com.bonait.bnframework.common.db.mode.BPA_SILOSANDMATERIAL;
import com.bonait.bnframework.common.db.mode.BPA_USER;
import com.bonait.bnframework.common.db.res.AlertLogEnum;
import com.bonait.bnframework.common.db.res.UserLogEnum;
import com.bonait.bnframework.common.helper.CrashHandler;
import com.bonait.bnframework.common.helper.I.IMessageLogNotify;
import com.bonait.bnframework.common.helper.LogcatHelper;
import com.bonait.bnframework.common.helper.MessageLog;
import com.bonait.bnframework.common.helper.SdCart;
import com.bonait.bnframework.common.modbus.ModbusTcpHelper;
import com.bonait.bnframework.common.modbus.ModbusTcpMainHelper;
import com.bonait.bnframework.common.modbus.ModbusTcpMainServer;
import com.bonait.bnframework.common.notification.MainNotification;
import com.bonait.bnframework.common.utils.AppUtils;
import com.bonait.bnframework.common.utils.NetworkUtils;
import com.bonait.bnframework.common.utils.PreferenceUtils;
import com.bonait.bnframework.common.utils.WifiInterceptor;
import com.bonait.bnframework.manager.ActivityLifecycleManager;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheEntity;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.FormatStrategy;
import com.orhanobut.logger.Logger;
import com.orhanobut.logger.PrettyFormatStrategy;
import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager;

import org.litepal.LitePal;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import okhttp3.OkHttpClient;

public class MainInit {
    /**
     * 初始化
     * @param app
     */
    public static void Init(Application app)
    {
        //0.全局异常捕获,保存为SD卡本级目录 crash
        CrashHandler.getInstance().init(app);

        //1.设置程序active,初始化Main函数进程,初始化消息日志
        InitMsgLog();

        //2.初始化SD卡,数据库DB
        SdCart.getInstance().initSD();

        //4.初始化Main,并且增加本地图片库
        ConfigData.getInstance().AddImage(app);
        // activity生命周期管理
        ActivityLifecycleManager.get().init(app);

        // QMUI 框架初始化
        QMUISwipeBackActivityManager.init(app);

        // LitePal 数据库初始化
        LitePal.initialize(app);

        // 全局配置OkGo
        initOkGo(app);

        // 配置sharedPreferences
        PreferenceUtils.initPreference(app, AppUtils.getAppName(app), Activity.MODE_PRIVATE);

        // 初始化通知栏消息渠道
        MainNotification.initNotificationChannel(app);

        // 内存泄漏检测
        initLeakCanary(false);

        // Log日志打印框架
        initLogCat();

        // SmartShow Toast框架，暂时不用，先使用ToastUtils工具类的
        //SmartShow.init(this);

        //初始化DB数据
        InitDBdata();
        DataBus.getInstance().GetLc();//获取料仓数据
        ConfigData.getInstance().LoadingCloud();//加载云端数据

        //设置连接到有线网络
       // NetworkUtils.connetEnternet(app);

        //text();

        //cx_cp();

        //日志
        LogcatHelper.getInstance(app).start();
        ExecuteTheRecipe.showlog("程序启动中...");
    }


    //========================================================================//
    public static void text()
    {
        String id="38f0a737-2476-40d8-a7d8-28ff7796e9d2";
        BPA_GOODS gd=QueryDB.GetGoodsId(id);
        ArrayList<BPA_GOODSRECIPE> PF=QueryDB.GetGoodsSrecipeID(id);
        ArrayList<BPA_GOODS> goods= QueryDB.GetGoodsALL();
        for (BPA_GOODS good:goods)
        {
            if(!good.id.equals(id))
            {
                for (BPA_GOODSRECIPE m:PF)
                {
                    m.id=java.util.UUID.randomUUID().toString();
                    m.goodsID=good.id;
                    QueryDB.AddGoodsSrecipe(m);
                }
            }
        }





    }

    /**
     * 根据第一个配方重新写配方
     */
    public static void cx_cp()
    {
        ArrayList<BPA_GOODS> goods= QueryDB.GetGoodsALL();
        //38f0a737-2476-40d8-a7d8-28ff7796e9d2  鱼香肉丝
        //b414cef3-a315-4841-954a-abee17af02d6  重游发财


        String ydrs="dc2136ad-ee32-48c1-8077-afbdb80af9a3";
        ArrayList<BPA_GOODSRECIPE> ydrs_pf=QueryDB.GetGoodsSrecipeID(ydrs);


        String hc="b414cef3-a315-4841-954a-abee17af02d6";
        ArrayList<BPA_GOODSRECIPE> hc_pf=QueryDB.GetGoodsSrecipeID(hc);

        ArrayList<BPA_GOODSRECIPE> rec= QueryDB.GetGoodsSrecipeALL();
        for (BPA_GOODSRECIPE pf:rec)
        {
            QueryDB.DeleteGoodsSrecipe(pf);
        }
        for (BPA_GOODS good:goods)
        {
            if(good.sort<=30)
            {
                for (BPA_GOODSRECIPE m:ydrs_pf)
                {
                    m.id=java.util.UUID.randomUUID().toString();
                    m.goodsID=good.id;
                    QueryDB.AddGoodsSrecipe(m);
                }
            }else
            {
                for (BPA_GOODSRECIPE m:hc_pf)
                {
                    m.id=java.util.UUID.randomUUID().toString();
                    m.goodsID=good.id;
                    QueryDB.AddGoodsSrecipe(m);
                }
            }
        }
    }
    /**
     * 初始化数据库数据(默认数据)
     */
    public static void InitDBdata() {
        //1.没有用户数据 默认写一个admin
        if (QueryDB.GetUserALL().size() <= 0) {
            BPA_USER user = new BPA_USER();
            user.id = "20230415-fyf";
            user.name = "管理员";
            user.account = "admin";
            user.pass = "123456";
            user.deviceID = ConfigName.getInstance().DeviceId;
            user.userID = "超级管理员";
            user.exp = "管理员";
            QueryDB.AddUser(user);

            BPA_USER user1 = new BPA_USER();
            user1.name = "一般用户";
            user1.account = "ybyh";
            user1.pass = "123456";
            user1.deviceID = ConfigName.getInstance().DeviceId;
            user1.userID = "一般用户";
            user1.exp = "一般用户";
            QueryDB.AddUser(user1);


            BPA_USER user2 = new BPA_USER();
            user2.name = "研发用户";
            user2.account = "yfyh";
            user2.pass = "123456";
            user2.deviceID = ConfigName.getInstance().DeviceId;
            user2.userID = "研发用户";
            user2.exp = "研发用户";
            QueryDB.AddUser(user2);



            //10个料仓
            if (QueryDB.GetSilosALL().size() == 0) {
                for (int i = 0; i < 5; i++) {
                    BPA_SILOS silo = new BPA_SILOS();
                    silo.id = java.util.UUID.randomUUID().toString();
                    silo.num = i + 1;
                    silo.thrsoleValue=ConfigName.getInstance().SiloAlarmThreshold;
                    silo.warningValue=ConfigName.getInstance().SiloFeedThreshold;
                    BPA_SILOSANDMATERIAL sm = new BPA_SILOSANDMATERIAL();
                    sm.silosID = silo.id;
                    sm.materialID = "";
                    QueryDB.AddSilos(silo);
                    QueryDB.AddSilosAndMaterial(sm);
                }
            }
        }

        if(QueryDB.GetPlcaddressALL().size()<=0)
        {
            ConfigData.getInstance().RevertPLCProcess();
        }
    }
    /**
     * 删除表-重新生成新表
     */
    public static void DBdelete()
    {
//        DBHelper.getInstance(this).DeleteCreateTables(BPA_CLOUDDATA.class,null);
//        DBHelper.getInstance(this).DeleteCreateTables(BPA_PLCADDRESS.class,null);
    }

    /**
     * 初始化消息日志接收打印
     */
    public  static  void InitMsgLog(){
        MessageLog.MsgNotify = new IMessageLogNotify() {
            @Override
            public void ErrorMsg(String msg) {
                if(msg.contains("msg:com.serotonin.modbus4j.exception"))
                {
                    if(msg.contains("主设备"))
                    {
                        ModbusTcpMainHelper.get().release();//释放modbus
                        ConfigName.getInstance().PlcMainIsConnect=false;
                        BPA_ALERTLOG log = new BPA_ALERTLOG();
                        log.userID = ConfigName.getInstance().user.userID;
                        log.type=4;
                        log.text = msg+"主程序断开PLC，准备重连机制...";
                        QueryDB.AddAlertlog(log);
                        Log.e("主控PLC", "主控PLC: 连接断开");

                    }else if(msg.contains("PLC设备"))
                    {
                        ModbusTcpHelper.get().release();//释放modbus
                        ConfigName.getInstance().PlcIsConnect=false;
                        BPA_ALERTLOG log = new BPA_ALERTLOG();
                        log.userID = ConfigName.getInstance().user.userID;
                        log.type=4;
                        log.text = msg+"PLC程序断开PLC，准备重连机制...";
                        QueryDB.AddAlertlog(log);
                        Log.e("设备PLC", "设备PLC: 连接断开");

                    }

                }
            }
            @Override
            public void InfoMsg(String msg) {
                Log.i("Info", msg);

            }
            @Override
            public void WarnMsg(String msg) {
                Log.w("Warn", msg);
            }
            @Override
            public void UserMsg(UserLogEnum type, String msg) {
                BPA_LOG log = new BPA_LOG();
                log.userID = ConfigName.getInstance().user.userID;
                switch (type.toString())
                {
                    case "登录日志":log.type=1;
                        break;
                    case "角色操作日志":log.type=2;
                        break;
                    case "数据接收":log.type=3;
                        break;
                    case "上传日志":log.type=4;
                        break;
                    case "订单处理日志":log.type=5;
                        break;
                }
                log.text = msg;
                QueryDB.Addlog(log);
            }

            @Override
            public void AlertMsg(AlertLogEnum type, String msg) {
                BPA_ALERTLOG log = new BPA_ALERTLOG();
                log.userID = ConfigName.getInstance().user.userID;
                switch (type.toString())
                {
                    case "异常订单未制作日志":log.type=1;
                        break;
                    case "料仓缺料日志":log.type=2;
                        break;
                    case "传感器异常日志":log.type=3;
                        break;
                    case "其他":log.type=4;
                        break;
                }
                log.text = msg;

                QueryDB.AddAlertlog(log);
            }
        };
    }
    /**
     * 内存泄漏检测，根据flag来判断要不要初始化
     */
    private static void initLeakCanary(boolean flag) {
        if (flag) {
            // leak 内存检测注册
//            if (LeakCanary.isInAnalyzerProcess(this)) {
//                return;
//            }
//            LeakCanary.install(this);
        }
    }

    /**
     * 初始化log日志框架
     */
    private static void initLogCat() {
        FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
                .showThreadInfo(false)  // （可选）是否显示线程信息。 默认值为true
                .methodCount(2)         // （可选）要显示的方法行数。 默认2
                .build();
        Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy) {
            @Override
            public boolean isLoggable(int priority, String tag) {
                return BuildConfig.DEBUG;
            }
        });
    }

    /**
     * 配置OkGo
     */
    private static void initOkGo(Application app) {

        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
        /*HttpHeaders headers = new HttpHeaders();
        headers.put("commonHeaderKey1", "commonHeaderValue1");    //header不支持中文，不允许有特殊字符
        headers.put("commonHeaderKey2", "commonHeaderValue2");
        HttpParams params = new HttpParams();
        params.put("commonParamsKey1", "commonParamsValue1");     //param支持中文,直接传,不要自己编码
        params.put("commonParamsKey2", "这里支持中文参数");*/
        //----------------------------------------------------------------------------------------//

        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        //log相关
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
        //log打印级别，决定了log显示的详细程度
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
        //log颜色级别，决定了log在控制台显示的颜色
        loggingInterceptor.setColorLevel(Level.INFO);
        //添加OkGo默认debug日志
        builder.addInterceptor(loggingInterceptor);
        //builder.addInterceptor(new WifiInterceptor(app));
        //-------------------------配置超时时间，默认60000ms，60s------------------------------//
        //OkGo.DEFAULT_MILLISECONDS
        //全局的连接超时时间
        builder.connectTimeout(Constants.CONNECT_TIME_OUT, TimeUnit.MILLISECONDS);
        //全局的读取超时时间
        builder.readTimeout(Constants.CONNECT_TIME_OUT, TimeUnit.MILLISECONDS);
        //全局的写入超时时间
        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
        OkGo.getInstance().init(app)                           //必须调用初始化
                .setOkHttpClient(builder.build())               //建议设置OkHttpClient，不设置将使用默认的
                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
                .setRetryCount(0);                               //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
        //.addCommonParams(params);                       //全局公共参数

    }
}
