package com.example.iot_controlhost.ui.dialog;

import android.content.Context;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.example.iot_controlhost.R;
import com.example.iot_controlhost.adapter.SetAdapter;
import com.example.iot_controlhost.base.BaseDialog;
import com.example.iot_controlhost.databinding.DialogSetBinding;
import com.example.iot_controlhost.databinding.ItemSetBinding;
import com.example.iot_controlhost.model.Log;
import com.example.iot_controlhost.model.MyTask;
import com.example.iot_controlhost.model.Set;
import com.example.iot_controlhost.model.thread.QueueIOUITask;
import com.example.iot_controlhost.utils.DialogUtil;
import com.example.iot_controlhost.utils.MMKVUtil;
import com.example.iot_controlhost.utils.MyQueue;
import com.example.iot_controlhost.utils.MyUtil;
import com.example.iot_controlhost.utils.control.temperature.TemperatureController;
import com.example.iot_controlhost.utils.control.ventilator.VentilatorController;
import com.example.iot_controlhost.utils.database.LogDBManager;
import com.example.iot_controlhost.utils.global.AutoModelSet;
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.UserLog;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.timer.ThemeTaskUtil;
import com.example.iot_controlhost.utils.timer.UVTaskUtil;
import com.xuexiang.rxutil2.rxbus.RxBusUtils;
import com.xuexiang.rxutil2.rxjava.RxJavaUtils;
import com.xuexiang.rxutil2.rxjava.task.RxAsyncTask;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import es.dmoral.toasty.Toasty;

/**
 *
 */
public class SetBaseDialog extends BaseDialog<DialogSetBinding> {
    List<Set> setList;
    SetAdapter setAdapter;

    public SetBaseDialog(@NonNull Context context) {
        super(context);
        setList = new ArrayList<>();
        setAdapter = new SetAdapter(setList, ItemSetBinding.class);
        binding.btnAppClose.setOnClickListener(v1 -> new ConfirmDialog(mContext, mContext.getString(R.string.warning), "确定要关闭程序吗？",
                () -> MyUtil.exitApp()).show());
        binding.btnAppRestart.setOnClickListener(v1 -> new ConfirmDialog(mContext, mContext.getString(R.string.warning), "确定要重启程序吗？",
                () -> MyUtil.relaunchApp()).show());
        binding.btnDeviceShutdown.setOnClickListener(v1 -> new ConfirmDialog(mContext, mContext.getString(R.string.warning), "确定要关闭主机吗？",
                () -> MyUtil.shutDown()).show());
        binding.btnDeviceRestart.setOnClickListener(v1 -> new ConfirmDialog(mContext, mContext.getString(R.string.warning), "确定要重启主机吗？",
                () -> MyUtil.reboot()).show());
        binding.rvSet.setLayoutManager(new LinearLayoutManager(mContext));
        binding.rvSet.setAdapter(setAdapter);
        binding.ivReboot1.setImageDrawable(mContext.getDrawable(RoomSetting.isDarkTheme() ? R.mipmap.refresh : R.mipmap.reboot));
        binding.ivReboot2.setImageDrawable(mContext.getDrawable(RoomSetting.isDarkTheme() ? R.mipmap.refresh : R.mipmap.reboot));
        binding.ivClose1.setImageDrawable(mContext.getDrawable(RoomSetting.isDarkTheme() ? R.mipmap.power : R.mipmap.shutdown));
        binding.ivClose2.setImageDrawable(mContext.getDrawable(RoomSetting.isDarkTheme() ? R.mipmap.power : R.mipmap.shutdown));
        setMain();
    }

    private void setMain() {
        setList.clear();
        setList.add(new Set("自动模式设置", view -> setAutoParam()));
        setList.add(new Set(mContext.getString(R.string.set_password_main_lock_time), RoomSetting.getMainActivityOperateLockTimeOut() + "秒", view ->
                new TextViewDialog(mContext, mContext.getString(R.string.set_password_main_lock_time), null, str -> {
                    try {
                        long time = Long.parseLong(str);
                        if (time < 5) {
                            new ConfirmDialog(mContext, mContext.getString(R.string.tip), "时间不可小于5s，请重新输入", null).show();
                            return;
                        }
                        long oldTime = RoomSetting.getMainActivityOperateLockTimeOut();
                        MMKVUtil.put(RoomSetting.MAIN_ACTIVITY_OPERATE_LOCK_TIMEOUT, time);
                        logSettingChanged("自动锁屏等待时间", oldTime + "秒", time + "秒");
                        setMain();
                    } catch (Exception e) {
                        new ConfirmDialog(mContext, mContext.getString(R.string.tip), "输入格式有误，设置失败", null).show();
                    }
                }, true).show()));
        setList.add(new Set(mContext.getString(R.string.notice_type), RoomSetting.getNoticeType(), view ->
                new SpinnerDialog(mContext, mContext.getString(R.string.notice_type), "请选择通知类型", RoomSetting.NOTICE_TYPE_SPINNER, sel -> {
                    String oldValue = RoomSetting.getNoticeType();
                    MMKVUtil.put(RoomSetting.NOTICE_TYPE, sel);
                    logSettingChanged("通知类型", oldValue, sel);
                    setMain();
                }).show()));
        setList.add(new Set(mContext.getString(R.string.light_night),
                RoomSetting.getAutoLightNight() ? "根据日出日落时间自动设置" : RoomSetting.isDarkTheme() ? "总是暗色调" : "总是亮色调",
                v2 -> new SpinnerDialog(mContext, mContext.getString(R.string.light_night), "请选择色调调节方式", new String[]{"总是亮色调", "总是暗色调", "根据日出日落时间自动设置"}, sel -> {
                    String oldValue = RoomSetting.getAutoLightNight() ? "根据日出日落时间自动设置"
                            : RoomSetting.isDarkTheme() ? "总是暗色调" : "总是亮色调";
                    boolean isDark;
                    if ("根据日出日落时间自动设置".equals(sel)) {
                        MMKVUtil.put(RoomSetting.AUTO_LIGHT_NIGHT, true);
                        isDark = ThemeTaskUtil.resetTask();
                    } else {
                        MMKVUtil.put(RoomSetting.AUTO_LIGHT_NIGHT, false);
                        isDark = "总是暗色调".equals(sel);
                    }
                    dismiss();
                    this.dismiss();
                    logSettingChanged("界面色调", oldValue, sel);
                    MyUtil.switchDarkMode(isDark);
                }).show()));
        setList.add(new Set(getString(R.string.set_password_main_lock), "******", view -> new PasswordDialog(mContext, "请先输入原锁屏密码",
                null, ti -> {
            if (!ti.getText().toString().equals(RoomSetting.getMainActivityLock())) {
                new ConfirmDialog(mContext, "提示", "设置失败，原锁屏密码错误", null).show();
                return;
            }
            new PasswordDialog(mContext, "请输入六位新锁屏密码",
                    null, ti2 -> {
                if (ti2.getText().toString().length() != 6) {
                    new ConfirmDialog(mContext, "提示", "设置失败，锁屏密码长度为6位，请重新设置", null).show();
                    return;
                }
                MMKVUtil.put(RoomSetting.MAIN_ACTIVITY_LOCK, ti2.getText().toString());
                UserLog.operate("本机屏幕", "锁屏密码修改成功（密码内容未记录）");
                Toasty.success(mContext, "锁屏新密码设置成功").show();
            }).show();
        }).show()));
        setList.add(new Set("消毒作业期间自动关闭空调", RoomSetting.isAirConditionForceCloseEnable(), (compoundButton, b) -> {
            boolean oldValue = RoomSetting.isAirConditionForceCloseEnable();
            MMKVUtil.put(RoomSetting.IS_AIR_CONDITION_FORCE_CLOSE_ENABLE, b);
            logSettingChanged("消毒作业期间自动关闭空调", oldValue, b);
            setMain();
        }));
        setList.add(new Set(mContext.getString(R.string.log), view -> showLogDialog()));
        setAdapter.setDataList(setList);
    }

    /**
     * 设置自动模式参数
     */
    private void setAutoParam() {
        setList.clear();
        setList.add(new Set("返回上一级", view -> setMain()));
        setList.add(new Set("升温设备", AutoModelSet.getAutoTemperatureHeat(), view ->
                new SpinnerDialog(mContext, mContext.getString(R.string.temperature_control_heat), "请选择升温设备", SpinnerList.TEMPERATURE_HEAT, selection -> {
                    String oldValue = AutoModelSet.getAutoTemperatureHeat();
                    MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_HEAT, selection);
                    logSettingChanged("自动升温设备", oldValue, selection);
                    updateTemperatureControl();
                }).show()));
        setList.add(new Set("降温设备", AutoModelSet.getAutoTemperatureCool(), view ->
                new SpinnerDialog(mContext, mContext.getString(R.string.temperature_control_heat), "请选择降温设备", SpinnerList.TEMPERATURE_COOL, selection -> {
                    String oldValue = AutoModelSet.getAutoTemperatureCool();
                    MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_COOL, selection);
                    logSettingChanged("自动降温设备", oldValue, selection);
                    updateTemperatureControl();
                }).show()));
        setList.add(new Set("温度控制模式", AutoModelSet.getAutoTemperatureMode(), view ->
                new SpinnerDialog(mContext, mContext.getString(R.string.temperature_control_mode), "请选择温控模式", SpinnerList.TEMPERATURE_MODE, selection -> {
                    String oldMode = AutoModelSet.getAutoTemperatureMode();
                    double target = AutoModelSet.getTargetTemperature();
                    double min = AutoModelSet.getMinTemperature();
                    double max = AutoModelSet.getMaxTemperature();
                    // 获取当前选择模式的偏差
                    double bias ;
                    String heatMode;
                    if (selection.equals(SpinnerList.TEMPERATURE_MODE[1])) {
                        bias = Variable.AUTO_DO_NOTHING_TEMPERATURE_NORMAL;
                        heatMode = SpinnerList.TEMPERATURE_HEAT[1];
                    } else if (selection.equals(SpinnerList.TEMPERATURE_MODE[2])) {
                        bias = Variable.AUTO_DO_NOTHING_TEMPERATURE_SAVING;
                        heatMode = SpinnerList.TEMPERATURE_HEAT[2];
                    } else {
                        MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_MODE, selection);
                        logSettingChanged("温度控制模式", oldMode, selection);
                        updateTemperatureControl();
                        return;
                    }
                    if (target - min < bias || max - target < bias) {
                        new ConfirmDialog(mContext, mContext.getString(R.string.warning), "切换模式后自动最高最低与目标值偏差为" + bias + "℃，是否继续", () -> {
                            MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_MODE, selection);
                            MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_HEAT, heatMode);
                            MMKVUtil.put(AutoModelSet.MIN_TEMPERATURE,  target - bias);
                            MMKVUtil.put(AutoModelSet.MAX_TEMPERATURE, target + bias);
                            UserLog.operate("本机屏幕", "设置变化：温度控制模式=" + oldMode + " → " + selection
                                    + "，温度下限=" + min + " → " + (target - bias) + "℃，温度上限="
                                    + max + " → " + (target + bias) + "℃");
                            MyLog.app("温度控制模式修改：" + oldMode + "→" + selection
                                    + "，自动调整目标上下限为" + (target - bias) + "~" + (target + bias) + "℃");
                            updateTemperatureControl();
                        }).show();
                    } else {
                        MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_MODE, selection);
                        MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE_HEAT, heatMode);
                        logSettingChanged("温度控制模式", oldMode, selection);
                        updateTemperatureControl();
                    }
                }).show()
        ));
        setList.add(new Set("消毒灯计划", AutoModelSet.isAutoDisinfect() ? UVTaskUtil.getUvTask().size() + mContext.getString(R.string.plans) : "手动控制", view -> {
            //设置自动模式消毒
            List<MyTask> myTaskList = UVTaskUtil.getUvTask();
            Collections.sort(myTaskList);
            new UvTaskDialog(mContext, myTaskList).show();
        }));
        setList.add(new Set("匀风扇控制-启动时机", AutoModelSet.getAutoEvenMode(), view ->
                new SpinnerDialog(mContext, "匀风扇控制", "请选择匀风扇启动时机", SpinnerList.AUTO_EVEN_MODES, selection -> {
                    String oldValue = AutoModelSet.getAutoEvenMode();
                    MMKVUtil.put(AutoModelSet.AUTO_EVEN_MODE, selection);
                    logSettingChanged("匀风扇启动时机", oldValue, selection);
                    RxBusUtils.get().post(RxTag.UPDATE_AUTO, 3);
                    setAutoParam();
                }).show()));
        setList.add(new Set("匀风扇控制-在加湿期间不运行", AutoModelSet.isAutoEvenModeDuringHumidify()?"是" : "否", view ->
                new SpinnerDialog(mContext, "匀风扇在加湿期间不运行", "请选择", SpinnerList.YES_OR_NO, selection -> {
                    boolean oldValue = AutoModelSet.isAutoEvenModeDuringHumidify();
                    MMKVUtil.put(AutoModelSet.AUTO_EVEN_MODE_DURING_HUMIDIFY, selection.equals("是"));
                    logSettingChanged("匀风扇加湿期间停运", oldValue, selection.equals("是"));
                    RxBusUtils.get().post(RxTag.UPDATE_AUTO, 3);
                    setAutoParam();
                }).show()));
        setList.add(new Set("换气扇控制", AutoModelSet.getVentilatorMode(), view ->
                new SpinnerDialog(mContext, "换气扇控制", "请选择换气扇控制方法", SpinnerList.VENTILATION_MODES, selection -> {
                    String oldValue = AutoModelSet.getVentilatorMode();
                    MMKVUtil.put(AutoModelSet.VENTILATOR_MODE, selection);
                    logSettingChanged("换气扇控制方式", oldValue, selection);
                    if (!oldValue.equals(selection)) {
                        VentilatorController.getInstance().reloadSchedule("本机屏幕-换气扇控制方式");
                    }
                    setAutoParam();
                }).show()));
        setList.add(new Set("新风控制", AutoModelSet.getAirExchangeMode(), view ->
                new SpinnerDialog(mContext, "新风控制", "请选择新风控制方法", SpinnerList.AIR_EXCHANGE_MODES, selection -> {
                    String oldValue = AutoModelSet.getAirExchangeMode();
                    MMKVUtil.put(AutoModelSet.AIR_EXCHANGE_MODE, selection);
                    logSettingChanged("新风控制方式", oldValue, selection);
                    setAutoParam();
                }).show()));
        setList.add(new Set("地暖最大温度限制", AutoModelSet.getAutoFlorMaxTemp() + "℃", view ->
                new TextViewDialog(mContext, "自动模式地暖最大温度限制(35~45℃)", String.valueOf(AutoModelSet.getAutoFlorMaxTemp()), str -> {
                    try {
                        double temp = Double.parseDouble(str);
                        if (temp > 45 || temp < 35) {
                            new ConfirmDialog(mContext, mContext.getString(R.string.tip), "地暖温度区间需为35~45℃，请重新设置", null).show();
                            return;
                        }
                        double oldTemp = AutoModelSet.getAutoFlorMaxTemp();
                        MMKVUtil.put(AutoModelSet.AUTO_FLOOR_MAX_TEMP, temp);
                        logSettingChanged("地暖最大温度限制", oldTemp + "℃", temp + "℃");
                        setAutoParam();
                    } catch (Exception e) {
                        new ConfirmDialog(mContext, mContext.getString(R.string.tip), "输入格式有误，设置失败", null).show();
                    }
                }, true).show()));
        setAdapter.setDataList(setList);
    }

    /**
     * 更新温度控制算法及加热降温方式
     */
    public void updateTemperatureControl() {
        DialogUtil.showLoadingDialog(mContext, "正在更新温度控制模式，请稍等...");
        MyQueue.start(MyQueue.TYPE_CONTROLLER, new QueueIOUITask<Object>() {
            @Override
            public Object doInQueueThread() throws Exception {
                TemperatureController.getInstance().refreshStrategy();
                return null;
            }

            @Override
            public void doInUIThread(Object o) {
                DialogUtil.hideLoadingDialog();
                setAutoParam();
            }
        });
    }

    /**
     * 日志显示弹窗
     */
    public void showLogDialog() {
        DialogUtil.showLoadingDialog(mContext, "正在读取日志中...");
        RxJavaUtils.executeAsyncTask(new RxAsyncTask<Object, List<Log>>(null) {
            @Override
            public List<Log> doInIOThread(Object o) {
                return LogDBManager.queryLatest(UserLog.FILTER_ALL);
            }

            @Override
            public void doInUIThread(List<Log> logs) {
                DialogUtil.hideLoadingDialog();
                new LogDialog(mContext, logs).show();
            }
        });
    }

    private void logSettingChanged(String name, Object oldValue, Object newValue) {
        UserLog.operate("本机屏幕", "设置变化：" + name + "=" + oldValue + " → " + newValue);
        MyLog.app("设置修改：" + name + "=" + oldValue + "→" + newValue);
    }
}
