package com.example.iot_controlhost.ui.dialog;

import android.content.Context;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.example.iot_controlhost.R;
import com.example.iot_controlhost.base.BaseDialog;
import com.example.iot_controlhost.databinding.DialogSetAutoBinding;
import com.example.iot_controlhost.model.AITHMode;
import com.example.iot_controlhost.utils.MMKVUtil;
import com.example.iot_controlhost.utils.MyUtil;
import com.example.iot_controlhost.utils.database.MyAIModeUtil;
import com.example.iot_controlhost.utils.control.ventilator.VentilatorController;
import com.example.iot_controlhost.utils.global.AIModelSet;
import com.example.iot_controlhost.utils.global.AutoModelSet;
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.xuexiang.rxutil2.rxbus.RxBusUtils;

import java.util.List;

/**
 * @Description 自动模式设置弹窗
 * @Author DuanKaiji
 * @CreateTime 2024年03月06日 14:05
 */
public class SetAutoParamDialog extends BaseDialog<DialogSetAutoBinding> {

    /**
     * 构造函数
     *
     * @param context      上下文
     * @param setType      设置类型 0温度 1湿度 2换气
     *                     3智能模式-温湿度 4智能模式-换气扇
     * @param defaultValue 默认值
     */
    public SetAutoParamDialog(@NonNull Context context, int setType, String[] defaultValue) {
        super(context);
        binding.tiSet1.setText(defaultValue[0]);
        binding.tiSet2.setText(defaultValue[1]);
        if (setType == 0 || setType == 1 || setType == 2) {
            binding.tiSet3.setText(defaultValue[2]);
            binding.set0.setVisibility(View.VISIBLE);
        }
        String strSet1 = null;
        String strSet2 = null;
        String strSet3 = null;
        switch (setType) {
            case 0:
                //设置温度
                binding.tvSetTitle.setText(R.string.auto_set_temperature);
                strSet1 = context.getString(R.string.target_temperature);
                strSet2 = context.getString(R.string.temperature_max);
                strSet3 = context.getString(R.string.temperature_min);
                binding.tvSet1Symbol.setText(R.string.T_symbol);
                binding.tvSet2Symbol.setText(R.string.T_symbol);
                binding.tvSet3Symbol.setText(R.string.T_symbol);
                MyUtil.changeIcon(context, binding.ivAuto, AutoModelSet.isAutoTemperature(), binding.llAutoSetParam, binding.llAutoSetParamNone);
                binding.set0.setOnClickListener(v -> MyUtil.changeIcon(context, binding.ivAuto, binding.llAutoSetParam, binding.llAutoSetParamNone));
                break;
            case 1:
                //设置湿度
                binding.tvSetTitle.setText(R.string.auto_set_humidity);
                strSet1 = context.getString(R.string.target_humidity);
                strSet2 = context.getString(R.string.humidity_max);
                strSet3 = context.getString(R.string.humidity_min);
                binding.tvSet1Symbol.setText(R.string.H_symbol);
                binding.tvSet2Symbol.setText(R.string.H_symbol);
                binding.set3.setVisibility(View.VISIBLE);
                binding.tvSet3Symbol.setText(R.string.H_symbol);
                MyUtil.changeIcon(context, binding.ivAuto, AutoModelSet.isAutoHumidity(), binding.llAutoSetParam, binding.llAutoSetParamNone);
                binding.set0.setOnClickListener(v -> MyUtil.changeIcon(context, binding.ivAuto, binding.llAutoSetParam, binding.llAutoSetParamNone));
                break;
            case 2:
            default:
                //设置换气
                binding.tvSetTitle.setText(R.string.auto_set_ventilation);
                strSet1 = context.getString(R.string.target_start_time);
                strSet2 = context.getString(R.string.target_stop_time);
                strSet3 = context.getString(R.string.target_co2);
                binding.tvSet1Symbol.setText(R.string.minute);
                binding.tvSet2Symbol.setText(R.string.minute);
                binding.set3.setVisibility(View.VISIBLE);
                binding.tvSet3Symbol.setText(R.string.ppm);
                MyUtil.changeIcon(context, binding.ivAuto, AutoModelSet.isAutoVentilator(), binding.llAutoSetParam, binding.llAutoSetParamNone);
                binding.set0.setOnClickListener(v -> MyUtil.changeIcon(context, binding.ivAuto, binding.llAutoSetParam, binding.llAutoSetParamNone));
                break;
            case 3:
                //设置智能模式-温湿度
                binding.tvSetTitle.setText(R.string.ai_set_th);
                binding.tvSet1.setText(R.string.target_temperature);
                binding.tvSet1Symbol.setText(R.string.T_symbol);
                binding.tvSet2.setText(R.string.target_humidity);
                binding.tvSet2Symbol.setText(R.string.H_symbol);
                binding.set3.setVisibility(View.GONE);
                binding.llAutoSetParamNone.setVisibility(View.GONE);
                break;
            case 4:
                //设置智能模式-换气扇
                binding.tvSetTitle.setText(R.string.ai_set_ventilation);
                binding.tvSet1.setText(R.string.target_start_time);
                binding.tvSet1Symbol.setText(R.string.minute);
                binding.tvSet2.setText(R.string.target_stop_time);
                binding.tvSet2Symbol.setText(R.string.minute);
                binding.set3.setVisibility(View.GONE);
                binding.llAutoSetParamNone.setVisibility(View.GONE);
                break;
        }
        binding.tvSet1.setText(strSet1);
        binding.tvSet2.setText(strSet2);
        binding.tvSet3.setText(strSet3);
        binding.tiSet1.setOnClickListener(v -> new NumberInputDialog(mContext, binding.tiSet1).show());
        binding.tvSet1Symbol.setOnClickListener(v -> new NumberInputDialog(mContext, binding.tiSet1).show());
        binding.tiSet2.setOnClickListener(v -> new NumberInputDialog(mContext, binding.tiSet2).show());
        binding.tvSet2Symbol.setOnClickListener(v -> new NumberInputDialog(mContext, binding.tiSet2).show());
        binding.tiSet3.setOnClickListener(v -> new NumberInputDialog(mContext, binding.tiSet3).show());
        binding.tvSet3Symbol.setOnClickListener(v -> new NumberInputDialog(mContext, binding.tiSet3).show());
        binding.btnAdd2.setOnClickListener(getAutoSetAddAndMinusOnClickListener(binding.tiSet2, setType, true));
        binding.btnAdd3.setOnClickListener(getAutoSetAddAndMinusOnClickListener(binding.tiSet3, setType, true));
        binding.btnMinus2.setOnClickListener(getAutoSetAddAndMinusOnClickListener(binding.tiSet2, setType, false));
        binding.btnMinus3.setOnClickListener(getAutoSetAddAndMinusOnClickListener(binding.tiSet3, setType, false));
        if (setType == 0 || setType == 1) {
            // 新需求：在设置目标温湿度时，最大值和最小值的范围随着目标值的变化而变化
            binding.btnAdd1.setOnClickListener(getTargetListener(binding.tiSet1, binding.tiSet2, binding.tiSet3, setType, true));
            binding.btnMinus1.setOnClickListener(getTargetListener(binding.tiSet1, binding.tiSet2, binding.tiSet3, setType, false));
        } else {
            binding.btnAdd1.setOnClickListener(getAutoSetAddAndMinusOnClickListener(binding.tiSet1, setType, true));
            binding.btnMinus1.setOnClickListener(getAutoSetAddAndMinusOnClickListener(binding.tiSet1, setType, false));
        }
        binding.btnYes.setOnClickListener(view -> {
            double min = setType <= 2 ? Double.parseDouble(binding.tiSet3.getText().toString()) : 0;
            double max = Double.parseDouble(binding.tiSet2.getText().toString());
            double target = Double.parseDouble(binding.tiSet1.getText().toString());
            boolean needRefresh = false;
            switch (setType) {
                case 0:
                    //设置温度
                    if (min > target || max < target || min > max) {
                        new ConfirmDialog(context, context.getString(R.string.warning), "预警区间设置不合理，请重新调整", null).show();
                        return;
                    }
                    if (!checkInputInTemperatureMode(target, min, max)) {
                        return;
                    }
                    //保存自动模式-温度设置
                    double oldTarget = AutoModelSet.getTargetTemperature();
                    double oldMax = AutoModelSet.getMaxTemperature();
                    double oldMin = AutoModelSet.getMinTemperature();
                    boolean oldEnabled = AutoModelSet.isAutoTemperature();
                    boolean enabled = binding.ivAuto.getDrawable().getConstantState()
                            .equals(context.getDrawable(R.mipmap.on).getConstantState());
                    MMKVUtil.put(AutoModelSet.TARGET_TEMPERATURE, target);
                    MMKVUtil.put(AutoModelSet.MAX_TEMPERATURE, max);
                    MMKVUtil.put(AutoModelSet.MIN_TEMPERATURE, min);
                    MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE, enabled);
                    UserLog.operate("本机屏幕", "自动温度参数变化：启用=" + oldEnabled + " → " + enabled
                            + "，目标=" + oldTarget + " → " + target + "℃，上限=" + oldMax + " → " + max
                            + "℃，下限=" + oldMin + " → " + min + "℃");
                    MyLog.app("自动温度参数修改：启用=" + oldEnabled + "→" + enabled
                            + "，目标=" + oldTarget + "→" + target + "℃，上限=" + oldMax + "→" + max
                            + "℃，下限=" + oldMin + "→" + min + "℃");
                    dismiss();
                    needRefresh = true;
                    break;
                case 1:
                    //设置湿度
                    if (checkInput(context, binding.tvSet1, binding.tiSet1, 1, 100)
                            && checkInput(context, binding.tvSet2, binding.tiSet2, 1, 100)
                            && checkInput(context, binding.tvSet3, binding.tiSet3, 1, 100)) {
                        if (min > target || max < target || min > max) {
                            new ConfirmDialog(context, context.getString(R.string.warning), "预警区间设置不合理，请重新调整", null).show();
                            return;
                        }
                        //保存自动模式-湿度设置
                        double humidityOldTarget = AutoModelSet.getTargetHumidity();
                        double humidityOldMin = AutoModelSet.getMinHumidity();
                        double humidityOldMax = AutoModelSet.getMaxHumidity();
                        boolean humidityOldEnabled = AutoModelSet.isAutoHumidity();
                        boolean humidityEnabled = binding.ivAuto.getDrawable().getConstantState()
                                .equals(context.getDrawable(R.mipmap.on).getConstantState());
                        MMKVUtil.put(AutoModelSet.TARGET_HUMIDITY, target);
                        MMKVUtil.put(AutoModelSet.MIN_HUMIDITY, min);
                        MMKVUtil.put(AutoModelSet.MAX_HUMIDITY, max);
                        MMKVUtil.put(AutoModelSet.AUTO_HUMIDITY, humidityEnabled);
                        UserLog.operate("本机屏幕", "自动湿度参数变化：启用=" + humidityOldEnabled + " → " + humidityEnabled
                                + "，目标=" + humidityOldTarget + " → " + target + "% ，上限=" + humidityOldMax
                                + " → " + max + "% ，下限=" + humidityOldMin + " → " + min + "%");
                        MyLog.app("自动湿度参数修改：启用=" + humidityOldEnabled + "→" + humidityEnabled
                                + "，目标=" + humidityOldTarget + "→" + target + "% ，上限=" + humidityOldMax + "→" + max
                                + "% ，下限=" + humidityOldMin + "→" + min + "%");
                        dismiss();
                        needRefresh = true;
                    }
                    break;
                case 2:
                    //设置换气
                    if (checkInput(context, binding.tvSet1, binding.tiSet1, 1, 1440)
                            && checkInput(context, binding.tvSet2, binding.tiSet2, 1, 1440)
                            && checkInput(context, binding.tvSet3, binding.tiSet3, 500, 3000)) {
                        //保存自动模式-换气设置
                        try {
                            int start = Integer.parseInt(binding.tiSet1.getText().toString());
                            int stop = Integer.parseInt(binding.tiSet2.getText().toString());
                            int maxCo2 = Integer.parseInt(binding.tiSet3.getText().toString());
                            int oldStart = AutoModelSet.getCycleStart();
                            int oldStop = AutoModelSet.getCycleStop();
                            int oldMaxCo2 = AutoModelSet.getMaxDensityCO2();
                            boolean ventilatorOldEnabled = AutoModelSet.isAutoVentilator();
                            boolean ventilatorEnabled = binding.ivAuto.getDrawable().getConstantState()
                                    .equals(context.getDrawable(R.mipmap.on).getConstantState());
                            MMKVUtil.put(AutoModelSet.CYCLE_START, start);
                            MMKVUtil.put(AutoModelSet.CYCLE_STOP, stop);
                            MMKVUtil.put(AutoModelSet.MAX_DENSITY_CO2, maxCo2);
                            MMKVUtil.put(AutoModelSet.AUTO_VENTILATOR, ventilatorEnabled);
                            UserLog.operate("本机屏幕", "自动换气参数变化：启用=" + ventilatorOldEnabled + " → "
                                    + ventilatorEnabled + "，开启=" + oldStart + " → " + start + "分钟，关闭="
                                    + oldStop + " → " + stop + "分钟，CO₂上限=" + oldMaxCo2 + " → " + maxCo2 + "ppm");
                            MyLog.app("自动换气参数修改：启用=" + ventilatorOldEnabled + "→" + ventilatorEnabled
                                    + "，开启=" + oldStart + "→" + start + "分钟，关闭=" + oldStop + "→"
                                    + stop + "分钟，CO₂上限=" + oldMaxCo2 + "→" + maxCo2 + "ppm");
                            VentilatorController.getInstance().reloadSchedule("本机屏幕-自动换气参数");
                            dismiss();
                            needRefresh = true;
                        } catch (NumberFormatException e) {
                            infoTips("请输入整数");
                        }
                    }
                    break;
                case 3:
                    //设置智能模式-温湿度
                    if (checkInput(context, binding.tvSet2, binding.tiSet2, 1, 100)) {
                        //保存智能模式-温湿度设置
                        double temperature = Double.parseDouble(binding.tiSet1.getText().toString());
                        double humidity = Double.parseDouble(binding.tiSet2.getText().toString());
                        int hour = AIModelSet.getStartToNowHours();
                        List<AITHMode> modes = MyAIModeUtil.getMyAiMode();
                        int age = 0;
                        for (int i = 0; i < modes.size(); i++) {
                            hour -= modes.get(i).getExpectedHours();
                            if (hour < 0) {
                                age = i;
                                break;
                            }
                        }
                        AITHMode mode = MyAIModeUtil.getMyAiMode().get(age);
                        double oldTemperature = mode.getTargetTemp();
                        double oldHumidity = mode.getTargetHumi();
                        //修改当前龄期的湿度
                        mode.setTargetTemp(temperature);
                        mode.setTargetHumi(humidity);
                        MyAIModeUtil.update(mode);
                        UserLog.operate("本机屏幕", "智能模式当前龄期参数变化：温度=" + oldTemperature + " → "
                                + temperature + "℃，湿度=" + oldHumidity + " → " + humidity + "%");
                        MyLog.app("智能模式当前龄期参数修改：温度=" + oldTemperature + "→" + temperature
                                + "℃，湿度=" + oldHumidity + "→" + humidity + "%");
                        RxBusUtils.get().post(RxTag.AI_INFO, 0);
                        dismiss();
                        needRefresh = true;
                    }
                    break;
                case 4:
                    //设置智能模式-换气扇
                    if (checkInput(context, binding.tvSet1, binding.tiSet1, 1, 1440) && checkInput(context, binding.tvSet2, binding.tiSet2, 1, 1440)) {
                        //保存智能模式-换气扇设置
                        int start = Integer.parseInt(binding.tiSet1.getText().toString());
                        int stop = Integer.parseInt(binding.tiSet2.getText().toString());
                        int hour = AIModelSet.getStartToNowHours();
                        List<AITHMode> modes = MyAIModeUtil.getMyAiMode();
                        int age = 0;
                        for (int i = 0; i < modes.size(); i++) {
                            hour -= modes.get(i).getExpectedHours();
                            if (hour < 0) {
                                age = i;
                                break;
                            }
                        }
                        AITHMode mode = MyAIModeUtil.getMyAiMode().get(age);
                        int oldStart = mode.getTargetVentOpen();
                        int oldStop = mode.getTargetVentClose();
                        mode.setTargetVentOpen(start);
                        mode.setTargetVentClose(stop);
                        MyAIModeUtil.update(mode);
                        UserLog.operate("本机屏幕", "智能模式当前龄期换气参数变化：开启=" + oldStart + " → "
                                + start + "分钟，关闭=" + oldStop + " → " + stop + "分钟");
                        MyLog.app("智能模式当前龄期换气参数修改：开启=" + oldStart + "→" + start
                                + "分钟，关闭=" + oldStop + "→" + stop + "分钟");
                        VentilatorController.getInstance().reloadSchedule("本机屏幕-智能换气参数");
                        RxBusUtils.get().post(RxTag.AI_INFO, 0);
                        dismiss();
                        needRefresh = true;
                    }
                    break;
                default:
            }
            if (needRefresh) {
                RxBusUtils.get().post(RxTag.UPDATE_AUTO, 3);
            }
        });

    }

    /**
     * 输入框中数字增大减小事件
     *
     * @param ti    输入框
     * @param type  设置类型 0温度 1湿度 2换气 3智能模式-温湿度 4智能模式-换气扇
     * @param isAdd true增加 false减少
     * @return 事件
     */
    private View.OnClickListener getAutoSetAddAndMinusOnClickListener(TextView ti, int type, boolean isAdd) {
        double value;
        if (type == 0 || type == 3) {
            value = .1;
        } else {
            //(type == 1 || type == 2 || type == 4)
            value = 1;
        }
        return view -> {
            double d = Double.parseDouble(ti.getText().toString());
            if (isAdd) {
                d += value;
            } else {
                d -= value;
            }
            if (type == 0 || type == 3) {
                ti.setText(String.format("%.1f", d));
            } else {
                ti.setText(String.format("%.0f", d));
            }
        };
    }

    /**
     * 输入框中数字增大减小事件
     *
     * @param t1    输入框
     * @param t2    输入框
     * @param t3    输入框
     * @param type  设置类型 0温度 1湿度
     * @param isAdd true增加 false减少
     * @return 事件
     */
    private View.OnClickListener getTargetListener(TextView t1, TextView t2, TextView t3, int type, boolean isAdd) {
        double value;
        if (type == 0 || type == 3) {
            value = .1;
        } else {
            //(type == 1 || type == 2 || type == 4)
            value = 1;
        }
        return view -> {
            double d1 = Double.parseDouble(format(t1.getText().toString()));
            double d2 = Double.parseDouble(format(t2.getText().toString()));
            double d3 = Double.parseDouble(format(t3.getText().toString()));
            double[] minTargetMax = MyUtil.getTHMinMax(d1, isAdd ? value : -value, d2, d3, type);
            t1.setText(String.format("%.1f", minTargetMax[1]));
            t2.setText(String.format("%.1f", minTargetMax[2]));
            t3.setText(String.format("%.1f", minTargetMax[0]));
        };
    }

    private String format(String str) {
        if (str == null) {
            return "0.0";
        }
        if (str.contains("|")) {
            // 删除|
            str = str.replace("|", "");
        }
        return str;
    }

    /**
     * 检查输入
     * 是否超过最小值或最大值
     *
     * @param tvSet         被设置的内容，如“湿度”、“换气值”
     * @param inputEditText 用户输入的文本框
     * @param min           最小值
     * @param max           最大值
     * @return 是否符合规定要求
     */
    private boolean checkInput(Context context, TextView tvSet, TextView inputEditText, double min, double max) {
        String input = inputEditText.getText().toString();
        try {
            double value = Double.parseDouble(input);
            if (value > max) {
                // 检查是否超过最大值
                new ConfirmDialog(context, context.getString(R.string.warning), tvSet.getText().toString() + "最大值为" + max + "，请重新调整", null).show();
                return false;
            } else if (value < min) {
                // 检查是否低于最小值
                new ConfirmDialog(context, context.getString(R.string.warning), tvSet.getText().toString() + "最小值为" + min + "，请重新调整", null).show();
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            new ConfirmDialog(context, context.getString(R.string.error), context.getString(R.string.input_error), null).show();
            return false;
        }
    }
    private boolean checkInputInTemperatureMode(double target, double min, double max) {
        String mode = AutoModelSet.getAutoTemperatureMode();
        double minBias;
        String warningMessage;
        // 根据不同模式设置相应的最小偏差和提示信息
        if (SpinnerList.TEMPERATURE_MODE[0].equals(mode)) {
            minBias = Variable.AUTO_DO_NOTHING_TEMPERATURE_FULL;
            warningMessage = "高精度模式下";
        } else if (SpinnerList.TEMPERATURE_MODE[1].equals(mode)) {
            minBias = Variable.AUTO_DO_NOTHING_TEMPERATURE_NORMAL;
            warningMessage = "普通模式下";
        } else if (SpinnerList.TEMPERATURE_MODE[2].equals(mode)) {
            minBias = Variable.AUTO_DO_NOTHING_TEMPERATURE_SAVING;
            warningMessage = "节能模式下";
        } else {
            return true;  // 未知模式，直接返回 true
        }
        // 检查最低温度和最高温度是否符合条件
        if (target - min < minBias) {
            new ConfirmDialog(mContext, mContext.getString(R.string.warning), warningMessage + "，最低温度需小于目标温度至少"
                    + minBias + "℃，请重新设置最小值", null).show();
            return false;
        } else if (max - target < minBias) {
            new ConfirmDialog(mContext, mContext.getString(R.string.warning), warningMessage + "，最高温度需大于目标温度至少"
                    + minBias + "℃，请重新设置最大值", null).show();
            return false;
        }
        return true;
    }
}
