package com.example.iot_controlhost.ui.activity;


import android.app.Activity;
import android.app.Application;
import android.content.Intent;

import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;

import com.example.iot_controlhost.base.BasePresenter;
import com.example.iot_controlhost.model.controller.Floor;
import com.example.iot_controlhost.model.net.CommonResponse;
import com.example.iot_controlhost.model.net.WebSet;
import com.example.iot_controlhost.model.sensor.FloorTSensor;
import com.example.iot_controlhost.model.sensor.GasSensor;
import com.example.iot_controlhost.model.sensor.THSensor;
import com.example.iot_controlhost.service.MQTTService;
import com.example.iot_controlhost.utils.MMKVUtil;
import com.example.iot_controlhost.utils.PollingTask;
import com.example.iot_controlhost.utils.control.DeviceAnomalyDetection;
import com.example.iot_controlhost.utils.database.EnergyDBManager;
import com.example.iot_controlhost.utils.database.SilkwormDBManager;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorAmmoniaSensorUtil;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorCO2SensorUtil;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorFloorTSensorUtil;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorTHSensorUtil;
import com.example.iot_controlhost.utils.global.AutoModelSet;
import com.example.iot_controlhost.utils.global.HardwareSetting;
import com.example.iot_controlhost.utils.global.RoomController;
import com.example.iot_controlhost.utils.global.RoomSensor;
import com.example.iot_controlhost.utils.global.RoomSetting;
import com.example.iot_controlhost.utils.global.RxTag;
import com.example.iot_controlhost.utils.global.SpinnerList;
import com.example.iot_controlhost.utils.global.Variable;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.network.Url;
import com.example.iot_controlhost.utils.network.XHttpManager;
import com.example.iot_controlhost.utils.network.XHttpShorthand;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.xuexiang.rxutil2.rxjava.RxJavaUtils;
import com.xuexiang.rxutil2.rxjava.task.RxIOTask;

import org.xutils.http.RequestParams;
import org.xutils.x;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author：DuanKaiji
 * @Date：2023-05-11/09:45
 * @Declaration：
 */
public class SplashActivityPresenter extends BasePresenter {
    private MutableLiveData<ProcessInfo> processLiveData = new MutableLiveData<>();
    private MutableLiveData<Boolean> needHideRegisterDialog = new MutableLiveData<>();
    private Activity currentActivity;

    public SplashActivityPresenter(@NonNull Application application) {
        super(application);
    }

    public void init() {
        processLiveData.postValue(new ProcessInfo(1, "正在初始化Frp服务..."));
        RxJavaUtils.doInIOThread(new RxIOTask<Object>(null) {
            @Override
            public Void doInIOThread(Object o) {
                // 检查向后兼容性
                checkOldVersion();
                processLiveData.postValue(new ProcessInfo(5, "正在检查本地配置..."));
                // 记录是否长时间未开机，即未在共育
                Date lastRecordDate = EnergyDBManager.queryLastRecordDate();
                if (lastRecordDate == null ||
                        lastRecordDate.getTime() < System.currentTimeMillis() - Variable.LONG_TIME_NOT_START) {
                    MyLog.app("长时间未启动，设置启动时间：" + new Date());
                    MMKVUtil.put(RxTag.IS_LONG_TIME_NOT_START, System.currentTimeMillis());
                }

                // 初始化MQTT网络
                processLiveData.postValue(new ProcessInfo(10, "正在连接服务器..."));
                currentActivity.startService(new Intent(currentActivity, MQTTService.class));
                // 检查是否注册
                PollingTask.getInstance("checkRegister").startPollingTaskOnIOThread(RxTag.CHECK_REGISTER, 3, () -> {
                    if (HardwareSetting.isRegistered()) {
                        PollingTask.getInstance("checkRegister").stopAllPollingTasks();
                        needHideRegisterDialog.postValue(true);
                        processLiveData.postValue(new ProcessInfo(20, "正在下载最新配置..."));
                        downloadLocalSet();
                    }
                });
                return null;
            }
        });
    }

    /**
     * 检查过往版本向后兼容性
     */
    private void checkOldVersion() {
        // 改变温控策略
        switch (AutoModelSet.getAutoTemperatureMode()) {
            case "分挡位控制" -> {
                MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_MODE, SpinnerList.TEMPERATURE_MODE[1]);
                double bias = Variable.AUTO_DO_NOTHING_TEMPERATURE_NORMAL;
                double target = AutoModelSet.getTargetTemperature();
                double min = AutoModelSet.getMinTemperature();
                double max = AutoModelSet.getMaxTemperature();
                // 检查是否符合普通模式设定-最大最小值是否为目标温度上下bias度
                if (target - min < bias) {
                    MMKVUtil.put(AutoModelSet.MIN_TEMPERATURE, target - bias);
                }
                if (max - target < bias) {
                    MMKVUtil.put(AutoModelSet.MAX_TEMPERATURE, target + bias);
                }
            }
            case "全功率控制" -> {
                MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_MODE, SpinnerList.TEMPERATURE_MODE[0]);
            }
        }
        // 转固定温湿度传感器为动态温湿度传感器
        THSensor indoorTHSensor1 = new THSensor(RoomSensor.SENSOR_NAME[7]);
        if (!IndoorTHSensorUtil.hasSensor(indoorTHSensor1.getName())) {
            IndoorTHSensorUtil.insert(indoorTHSensor1);
        }
        THSensor indoorTHSensor2 = new THSensor(RoomSensor.SENSOR_NAME[8]);
        if (!IndoorTHSensorUtil.hasSensor(indoorTHSensor2.getName())) {
            IndoorTHSensorUtil.insert(indoorTHSensor2);
        }
        GasSensor indoorCO2Sensor = new GasSensor(RoomSensor.SENSOR_NAME[3]);
        if (!IndoorCO2SensorUtil.hasSensor(indoorCO2Sensor.getName())) {
            IndoorCO2SensorUtil.insert(indoorCO2Sensor);
        }
        GasSensor ammoniaSensor = new GasSensor(RoomSensor.SENSOR_NAME[4]);
        if (!IndoorCO2SensorUtil.hasSensor(ammoniaSensor.getName())) {
            IndoorAmmoniaSensorUtil.insert(ammoniaSensor);
        }
        FloorTSensor floorTSensor = new FloorTSensor(RoomSensor.SENSOR_NAME[5]);
        if (!IndoorFloorTSensorUtil.hasSensor(floorTSensor.getName())) {
            IndoorFloorTSensorUtil.insert(floorTSensor);
        }
        // 120版本：高精度模式下，最大最小温度不可小于等于目标温度0.2度偏差
        if (AutoModelSet.getAutoTemperatureMode().equals(SpinnerList.TEMPERATURE_MODE[0])) {
            double bias = Variable.AUTO_DO_NOTHING_TEMPERATURE_FULL;
            double target = AutoModelSet.getTargetTemperature();
            double min = AutoModelSet.getMinTemperature();
            double max = AutoModelSet.getMaxTemperature();
            if (target - min <= bias) {
                MMKVUtil.put(AutoModelSet.MIN_TEMPERATURE, target - bias);
            }
            if (max - target <= bias) {
                MMKVUtil.put(AutoModelSet.MAX_TEMPERATURE, target + bias);
            }
        }
        // 130版本：不在使用蚕季数据库，迁移旧数据到新数据库
        SilkwormDBManager.initSK();
    }

    /**
     * 下载并更新配置
     */
    public void downloadLocalSet() {
        RequestParams params = XHttpManager.getInstance().getRequestParams(Url.getConfig);
        params.addParameter("hostCode", HardwareSetting.getHostId());
        x.http().get(params, new XHttpShorthand<CommonResponse>() {
            @Override
            public void success(CommonResponse model) {
                String configStr = model.getData().toString();
                WebSet webSet = new Gson().fromJson(configStr, new TypeToken<WebSet>() {
                }.getType());
                if (webSet != null) {
                    if (webSet.getSetUpdateTime() > RoomSetting.getSetTime()) {
                        //如果服务器配置更新时间大于本地配置更新时间，则更新本地配置
                        RoomSetting.setSetTime(webSet.getSetUpdateTime());
                        Map<String, Object> config = webSet.getSetJson();
                        //将键值对存入MMKV
                        for (String key : config.keySet()) {
                            Object value = config.get(key);
                            //修复部分配置项是整型，但是解析出来是double型导致无法正确导入的bug
                            if (key.endsWith("PWM") //pwm值为整型
                                    || key.contains(Floor.MAX_GEAR) //最大档位为整型
                                    || key.contains(RoomSetting.MAIN_ACTIVITY_OPERATE_LOCK_TIMEOUT) //锁屏时间为整型
                            ) {
                                MMKVUtil.put(key, ((Double) value).intValue());
                            } else {
                                MMKVUtil.put(key, value);
                            }
                        }
                        successTips("配置已更新");
                        MyLog.networkError("配置已更新");
                    }
                } else {
                    // 云端配置为空，将本地配置上传至云端
                    RequestParams params = XHttpManager.getInstance().getRequestParams(Url.uploadConfig);
                    params.addParameter("ConfigJson", SetActivityPresenter.getCurrentSetJsonString());
                    params.addParameter("hostCode", HardwareSetting.getHostId());
                    x.http().post(params, new XHttpShorthand<CommonResponse>() {
                        @Override
                        public void success(CommonResponse model) {
                            MyLog.network("配置已上传");
                        }

                        @Override
                        public void error(Throwable e) {
                        }
                    });
                }
            }

            @Override
            public void error(Throwable e) {
                errorTips("配置下载失败");
                MyLog.networkError("配置下载失败");
            }

            @Override
            public void onFinish() {
                super.onFinish();
                // 初始化控制器
                processLiveData.postValue(new ProcessInfo(40, "正在初始化控制器..."));
                RoomController.init();
                EnergyDBManager.clearLogsOlderThanThreeMonths();
                // 初始化传感器
                processLiveData.postValue(new ProcessInfo(60, "正在初始化传感器..."));
                RoomSensor.init();
                // 初始化故障预警
                processLiveData.postValue(new ProcessInfo(80, "正在初始化故障预警..."));
                DeviceAnomalyDetection.init();
                // 正在检查权限
                processLiveData.postValue(new ProcessInfo(90, "正在检查权限..."));
                checkPermission();
            }
        });
    }

    /**
     * 检查与请求权限
     */
    void checkPermission() {
        //申请读取存储的权限
        String permessions[];
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            permessions = new String[]{Permission.MANAGE_EXTERNAL_STORAGE};
        } else {
            permessions = new String[]{Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE};
        }
        XXPermissions.with(currentActivity)
                .permission(permessions)
                .permission(Permission.READ_PHONE_STATE)
                .permission(Permission.REQUEST_INSTALL_PACKAGES)
                .permission(Permission.CAMERA)
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                        if (allGranted) {
                            processLiveData.postValue(new ProcessInfo(100, "系统启动成功"));
                            MyLog.app("系统启动成功");
                        } else {
                            MyLog.appError("获取部分权限成功，但部分权限未正常授予");
                            XXPermissions.startPermissionActivity(getApplication(), permissions);
                        }
                    }

                    @Override
                    public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                        if (doNotAskAgain) {
                            MyLog.app("被永久拒绝授权，需手动授予权限");
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
                            XXPermissions.startPermissionActivity(getApplication(), permissions);
                        } else {
                            MyLog.appError("权限请求失败");
                        }
                    }
                });
    }

    public MutableLiveData<Boolean> getNeedHideRegisterDialog() {
        return needHideRegisterDialog;
    }

    public MutableLiveData<ProcessInfo> getProcessLiveData() {
        return processLiveData;
    }

    public void setActivity(Activity activity) {
        this.currentActivity = activity;
    }

    /**
     * 进度提示类
     */
    public class ProcessInfo {
        private int process;
        private String tips;

        public ProcessInfo(int process, String tips) {
            this.process = process;
            this.tips = tips;
        }

        public int getProcess() {
            return process;
        }

        public void setProcess(int process) {
            this.process = process;
        }

        public String getTips() {
            return tips;
        }

        public void setTips(String tips) {
            this.tips = tips;
        }
    }
}
