package com.siwei.recyclebox.application;


import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.aliyun.alink.apiclient.constants.MethodType;
import com.aliyun.alink.dm.api.DeviceInfo;
import com.aliyun.alink.dm.model.ResponseModel;
import com.aliyun.alink.linkkit.api.ILinkKitConnectListener;
import com.aliyun.alink.linkkit.api.IoTMqttClientConfig;
import com.aliyun.alink.linkkit.api.LinkKit;
import com.aliyun.alink.linkkit.api.LinkKitInitParams;
import com.aliyun.alink.linksdk.channel.core.persistent.mqtt.MqttConfigure;
import com.aliyun.alink.linksdk.channel.core.persistent.mqtt.request.MqttPublishRequest;
import com.aliyun.alink.linksdk.cmp.connect.hubapi.HubApiRequest;
import com.aliyun.alink.linksdk.cmp.core.base.AMessage;
import com.aliyun.alink.linksdk.cmp.core.base.ARequest;
import com.aliyun.alink.linksdk.cmp.core.base.AResponse;
import com.aliyun.alink.linksdk.cmp.core.base.ConnectState;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectNotifyListener;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSendListener;
import com.aliyun.alink.linksdk.tmp.api.OutputParams;
import com.aliyun.alink.linksdk.tmp.device.payload.ValueWrapper;
import com.aliyun.alink.linksdk.tmp.listener.IPublishResourceListener;
import com.aliyun.alink.linksdk.tools.AError;
import com.aliyun.alink.linksdk.tools.ALog;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.siwei.recyclebox.BuildConfig;
import com.siwei.recyclebox.deviceUtils.SerialPortUtil;
import com.siwei.recyclebox.ui.main.MainActivity;
import com.siwei.recyclebox.R;
import com.siwei.recyclebox.ui.main.MainViewModel;
//import com.squareup.leakcanary.LeakCanary;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.LogRecord;

import me.goldze.mvvmhabit.base.BaseApplication;
import me.goldze.mvvmhabit.crash.CaocConfig;
import me.goldze.mvvmhabit.crash.CustomActivityOnCrash;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.SPUtils;
import me.goldze.mvvmhabit.utils.StringUtils;
import com.siwei.recyclebox.ui.main.MainViewModel;
import com.squareup.leakcanary.LeakCanary;
import com.tencent.bugly.crashreport.CrashReport;


/**
 * Created by goldze on 2017/7/16.
 */

public class AppApplication extends BaseApplication implements CustomActivityOnCrash.EventListener{

    private String TAG = "Application";
    @Override
    public void onCreate() {
        super.onCreate();
        SerialPortUtil.getInstance().init(this);        //初+始化串口
        SPUtils.getInstance().put("RunningState",0);
        SPUtils.getInstance().put("TaskSwitch",1);
        CrashReport.initCrashReport(getApplicationContext(), "40c3954b93", true);//测试阶段为true  发布时改成false
        CrashReport.setUserId(this,MainViewModel.getDeviceId(this));
        //是否开启打印日志
        KLog.init(BuildConfig.DEBUG);
        //初始化全局异常崩溃
        initCrash();
        //内存泄漏检测
        if (!LeakCanary.isInAnalyzerProcess(this)) {
            LeakCanary.install(this);
        }
        initIoTDynamic();
    }

    private Handler mHandler=new Handler(msg ->{
        return true;
    });


    private void initAliIoT(DeviceInfo deviceInfo){
        /**
         * 设置设备三元组信息
         */
//        DeviceInfo deviceInfo = new DeviceInfo();
//        deviceInfo.productKey = "a13H8L6bDyf";// 产品类型
//        deviceInfo.deviceName = "9pD3trz6OaDV8GF7yRsb";// 设备名称
//        deviceInfo.deviceSecret = "a3NRdNGf7W5uYmW4mNG7tupSq9skwm0j";// 设备密钥
//        deviceInfo.deviceSecret = SPUtils.getInstance().getString("deviceSecret");
        /**
         * 设置设备当前的初始状态值，属性需要和云端创建的物模型属性一致
         * 如果这里什么属性都不填，物模型就没有当前设备相关属性的初始值。
         * 用户调用物模型上报接口之后，物模型会有相关数据缓存。
         */
        Map<String, ValueWrapper> propertyValues = new HashMap<>();
        //心跳包 interval 单位秒
        MqttConfigure.setKeepAliveInterval(300);

        // 示例
        // propertyValues.put("LightSwitch", new ValueWrapper.BooleanValueWrapper(0));
        IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(deviceInfo.productKey, deviceInfo.deviceName, deviceInfo.deviceSecret);
        // 对应 receiveOfflineMsg = !cleanSession, 默认不接受离线消息
        clientConfig.receiveOfflineMsg = true;
        // 慎用 设置 mqtt 请求域名，默认 productKey+".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883" ,如果无具体的业务需求，请不要设置。
        //clientConfig.channelHost = "xxx";
        LinkKitInitParams params = new LinkKitInitParams();
        params.deviceInfo = deviceInfo;
        params.propertyValues = propertyValues;
        params.mqttClientConfig = clientConfig;
        /**
         * 设备初始化建联
         * onError 初始化建联失败，需要用户重试初始化。如因网络问题导致初始化失败。
         * onInitDone 初始化成功
         */
        Log.i(TAG,params.toString()+"设备三元组信息");
        LinkKit.getInstance().init(this, params, new ILinkKitConnectListener() {
            @Override
            public void onError(AError error) {
                // 初始化失败 error包含初始化错误信息
//                initIoTDynamic();
                KLog.e("初始化失败."+error.getMsg());

                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        initIoTDynamic();
                    }
                },60000);
            }
            @Override
            public void onInitDone(Object data) {
                // 初始化成功 data 作为预留参数
                KLog.d("初始化成功,data:"+data);
                MqttConfigure.setKeepAliveInterval(60);

            }
        });
//        ALog.setLevel(ALog.LEVEL_DEBUG);//TODO 开启内部日志输出
        /*-----------连接状态监听---------------------------*/
    }

    /**
     * 一型一密动态注册。
     */
    private void initIoTDynamic(){
        /**
         * 注意：动态注册成功，设备上线之后，不能再次执行动态注册，云端会返回已注册错误信息。
         *   因此用户在编程时首先需要判断设备是否已获取过deviceSecret，没有获取过的情况下再
         *   调用动态注册接口去获取deviceSecret
         */
        DeviceInfo myDeviceInfo = new DeviceInfo();
//        myDeviceInfo.productKey = "a1EtqHmfpNk";//正式服
        myDeviceInfo.productKey = "a13H8L6bDyf";//测试服
//
//        myDeviceInfo.productSecret = "x6wHbrbXUMFYtvLl";//正式服
        myDeviceInfo.productSecret = "Nc4Y4KsjofejCy27";//测试服

        System.out.println(MainViewModel.getDeviceId(this)+"----------------------------+");
        myDeviceInfo.deviceName = MainViewModel.getDeviceId(this);
        Log.i("IMEI=",MainViewModel.getDeviceId(this));
        SPUtils.getInstance().put("IMEI",MainViewModel.getDeviceId(this));
//        myDeviceInfo.deviceName="123456";

//        SPUtils.getInstance().put("deviceSecret2","WMClVkIJipSunIY4fOSd2Be3xo42TfVs");//存
//        SPUtils.getInstance().put("deviceSecret2","WMClVkIJipSunIY4fOSd2Be3xo42TfVs");//测试服
//        String secret = SPUtils.getInstance().getString("deviceSecret2");//读
        String secret ="WMClVkIJipSunIY4fOSd2Be3xo42TfVs";
        Log.i(TAG,"secret=="+secret);

        if(secret != null &&  !secret.equals("")){
            myDeviceInfo.deviceSecret = secret;
            initAliIoT(myDeviceInfo);
            return;
        }
        LinkKitInitParams params = new LinkKitInitParams();
        params.deviceInfo = myDeviceInfo;
        System.out.println("-------"+myDeviceInfo.deviceName+"  "+myDeviceInfo.productKey);
// 设置动态注册请求 path 和 域名，域名使用默认即可
        HubApiRequest hubApiRequest = new HubApiRequest();
        hubApiRequest.path = "/auth/register/device";
//        hubApiRequest.domain
        LinkKit.getInstance().deviceRegister(this, params, hubApiRequest, new IConnectSendListener() {
            @Override
            public void onResponse(ARequest aRequest, AResponse aResponse) {
                // aRequest 用户的请求数据
                System.out.println("arequest:"+aRequest.toString()+"  aResponse:"+aResponse);
                if (aResponse != null && aResponse.data != null) {
                    ResponseModel<Map<String, String>> response = JSONObject.parseObject(aResponse.data.toString(),
                            new TypeReference<ResponseModel<Map<String, String>>>() {
                            }.getType());
                    Log.i(TAG,"response=="+response+"/"+response.code);
                    if ("200".equals(response.code) && response.data != null && response.data.containsKey("deviceSecret") &&
                            !TextUtils.isEmpty(response.data.get("deviceSecret"))) {
                        System.out.println("deviceSecret:"+response.data.get("deviceSecret"));
                        myDeviceInfo.deviceSecret = response.data.get("deviceSecret");
                        SPUtils.getInstance().put("deviceSecret2",myDeviceInfo.deviceSecret);//存
                        initAliIoT(myDeviceInfo);
                    }
                }
            }
            @Override
            public void onFailure(ARequest aRequest, AError aError) {
                System.out.println("code:"+aError.getCode()+"  subCode:"+aError.getSubCode());
                System.out.println("msg:"+aError.getMsg());
                Log.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError.getSubMsg() + "]");
            }
        });
//  ####### 一型一密动态注册接口结束  ######
    }
    @Override
    public void onTerminate() {
        super.onTerminate();

    }
    /*
    * 全局异常捕捉
    * */
    private void initCrash() {
        CaocConfig.Builder.create()
                .backgroundMode(CaocConfig.BACKGROUND_MODE_SILENT) //背景模式,开启沉浸式
                .enabled(true) //是否启动全局异常捕获
                .showErrorDetails(true) //是否显示错误详细信息
                .showRestartButton(true) //是否显示重启按钮
                .trackActivities(true) //是否跟踪Activity
                .minTimeBetweenCrashesMs(2000) //崩溃的间隔时间(毫秒)
                .errorDrawable(R.mipmap.ic_launcher) //错误图标
                .restartActivity(MainActivity.class) //重新启动后的activity
//                .errorActivity(YourCustomErrorActivity.class) //崩溃后的错误activity
                .eventListener(this) //崩溃后的错误监听
                .apply();

    }
    @Override
    public void onLaunchErrorActivity() {
//        Log.i(TAG,"1111+++");
            Intent mStartActivity = new Intent(this,MainActivity.class);
            int mPendingIntentId = 123456;
            PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
            AlarmManager mgr = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
            mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
            System.exit(0);

    }

    @Override
    public void onRestartAppFromErrorActivity() {
        Log.i(TAG,"222+++0");
    }

    @Override
    public void onCloseAppFromErrorActivity() {
        Log.i(TAG,"333++++");
    }
}
