package com.example.iot_controlhost.ui.fragment;

import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Typeface;

import com.example.iot_controlhost.R;
import com.example.iot_controlhost.base.BaseFragment;
import com.example.iot_controlhost.base.BaseMode;
import com.example.iot_controlhost.databinding.FragmentModelIntelligenceBinding;
import com.example.iot_controlhost.model.AITHMode;
import com.example.iot_controlhost.model.MyTask;
import com.example.iot_controlhost.model.Silkworm;
import com.example.iot_controlhost.model.SilkwormNew;
import com.example.iot_controlhost.model.thread.QueueIOUITask;
import com.example.iot_controlhost.ui.dialog.SetAutoParamDialog;
import com.example.iot_controlhost.ui.dialog.ConfirmDialog;
import com.example.iot_controlhost.ui.dialog.UvTaskDialog;
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.database.MyAIModeUtil;
import com.example.iot_controlhost.utils.database.SilkwormDBManager;
import com.example.iot_controlhost.utils.global.AIModelSet;
import com.example.iot_controlhost.utils.global.RoomController;
import com.example.iot_controlhost.utils.global.RoomSetting;
import com.example.iot_controlhost.utils.log.UserLog;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.timer.UVTaskUtil;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.DefaultAxisValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.xuexiang.rxutil2.rxjava.RxJavaUtils;
import com.xuexiang.rxutil2.rxjava.task.RxUITask;

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

/**
 * 智能模式
 */
public class IntelligenceFragment extends BaseFragment<FragmentModelIntelligenceBinding, IntelligenceFragmentPresenter> implements BaseMode {
    /**
     * 当前蚕季所有信息
     */
    List<AITHMode> modes;
    /**
     * 今日信息
     */
    AITHMode mode;
    /**
     * 图表折线两边的空白边距
     */
    private static final int MARGIN = 20;
    /**
     * 当前龄期，亦为当前模板下标
     */
    int age = 0;
    /**
     * 当前龄期的第几天
     */
    int day;
//    private static IntelligenceFragment INSTANCE = new IntelligenceFragment();

    public IntelligenceFragment() {
    }

//    public static IntelligenceFragment getInstance() {
//        return INSTANCE;
//    }

    @Override
    public void init() {
        binding.setVm(presenter);
        modes = MyAIModeUtil.getMyAiMode();
        //禁止Y轴缩放
        binding.chart.setScaleYEnabled(false);
        binding.chart.getDescription().setEnabled(false);
        binding.chart.setDrawGridBackground(false);
        binding.chart.setNoDataText("智能模式已暂停，设备已停止");
        binding.chart.setNoDataTextTypeface(Typeface.create("sans-serif", Typeface.BOLD));
        //图例
        Legend legend = binding.chart.getLegend();
        legend.setWordWrapEnabled(false);
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(true);
        legend.setTextColor(Color.parseColor("#424242"));
        legend.setTextSize(20f);
        //Y轴-左侧
        YAxis leftAxis = binding.chart.getAxisLeft();
        leftAxis.setDrawGridLines(true);
        leftAxis.setDrawTopYLabelEntry(true);
        leftAxis.setTextSize(20f);
        leftAxis.setDrawZeroLine(true);
        leftAxis.setAxisMaximum(32);
        leftAxis.setTextColor(Color.parseColor("#424242"));
        leftAxis.setGridDashedLine(new DashPathEffect(new float[]{5, 5}, 0));
        leftAxis.setGridColor(Color.GRAY);
        //Y轴-右侧
        YAxis rightAxis = binding.chart.getAxisRight();
        rightAxis.setTextSize(20f);
        rightAxis.setDrawGridLines(false);
        rightAxis.setDrawTopYLabelEntry(true);
        rightAxis.setAxisMaximum(100);
        rightAxis.setTextColor(Color.parseColor("#424242"));
        rightAxis.setAxisMinimum(50);
        //X轴
        XAxis xAxis = binding.chart.getXAxis();
        xAxis.setTextSize(20f);
        xAxis.setTextColor(Color.parseColor("#424242"));
        xAxis.setGranularity(24f);
        binding.chart.setExtraBottomOffset(5);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawGridLines(false);
        xAxis.setAvoidFirstLastClipping(true);
        xAxis.setValueFormatter(new DefaultAxisValueFormatter(0) {
            @Override
            public String getFormattedValue(float value) {
                int i = getI((int) value - MARGIN);
                if (i < 0) {
                    return "";
                }
                return modes.get(i).getName();
            }
        });
        if (RoomSetting.isDarkTheme()) {
            setGlobalTextColor(binding.chart, Color.WHITE);
        }
        String name = (RoomSetting.getType() == 4 ? "催青" : "共育");
        presenter.getNoticeLiveData().observe(this, integer -> {
            switch (integer) {
                case 0 -> //刷新模板
                        new ConfirmDialog(mContext, getString(R.string.warning), "确定要重新获取温湿度模板吗？\n注：此操作将清除自定义模板参数及"+name+"时间前后移量",
                               () -> presenter.refreshTemplate()).show();
                case 1 -> //暂停
                        new ConfirmDialog(mContext, getString(R.string.warning), "确定要关闭所有设备,暂停智能模式吗？", () -> {
                            DialogUtil.showLoadingDialog(mContext, "正在停止中...");
                            MyQueue.start(MyQueue.TYPE_CONTROLLER, new QueueIOUITask<>() {
                                @Override
                                public Object doInQueueThread() {
                                    stopMode();
                                    presenter.confirmPauseCultivate();
                                    return null;
                                }

                                @Override
                                public void doInUIThread(Object o) {
                                    hideLoadingDialog();
                                }
                            });
                        }).show();
                case 2 -> //退回半天
                        new ConfirmDialog(mContext, getString(R.string.warning), "确定将"+name+"计划返回至12小时前吗", () -> {
                            int oldBias = AIModelSet.getAiBiasTime();
                            MMKVUtil.put(AIModelSet.AI_BIAS_TIME, AIModelSet.getAiBiasTime() - 12);
                            UserLog.operate("本机屏幕", name + "计划后移12小时");
                            MyLog.app(name + "计划偏移量修改：" + oldBias + "→" + AIModelSet.getAiBiasTime() + "小时");
                            refreshInfo();
                        }).show();
                case 3 -> //提前半天
                        new ConfirmDialog(mContext, getString(R.string.warning), "确定将"+name+"计划提前到12小时后吗", () -> {
                            int oldBias = AIModelSet.getAiBiasTime();
                            MMKVUtil.put(AIModelSet.AI_BIAS_TIME, AIModelSet.getAiBiasTime() + 12);
                            UserLog.operate("本机屏幕", name + "计划前移12小时");
                            MyLog.app(name + "计划偏移量修改：" + oldBias + "→" + AIModelSet.getAiBiasTime() + "小时");
                            refreshInfo();
                        }).show();
                case 4 -> {//消毒
                    List<MyTask> myTaskList = UVTaskUtil.getUvTask();
                    Collections.sort(myTaskList);
                    new UvTaskDialog(mContext,myTaskList).show();
                }
                case 5 -> //自定义智能模式-温湿度
                        new SetAutoParamDialog(mContext, 3, new String[]{String.valueOf(AIModelSet.getTargetTemperature()),
                                String.valueOf(AIModelSet.getTargetHumidity())}).show();
                case 6 -> //修改当前龄期的关闭通风时间
                        new SetAutoParamDialog(mContext, 4, new String[]{String.valueOf(AIModelSet.getAiCycleStart()),
                                String.valueOf(AIModelSet.getAiCycleStop())}).show();
                case 7 ->//
                        refreshInfo();
                case 8 ->//更新开始暂停图标显示
                        binding.btnStartStop.setImageDrawable(mContext.getDrawable(AIModelSet.isAiProcessing() ? R.mipmap.pause : R.mipmap.play));
            }
        });
        if (RoomSetting.getMode() == 2) {
            initMode();
        }
    }

    @Override
    public void initMode() {
        //开始硬件控制
        if (AIModelSet.isAiProcessing()) {
            presenter.startAICultivate();
        }
        binding.btnStartStop.setImageDrawable(mContext.getDrawable(AIModelSet.isAiProcessing() ? R.mipmap.pause : R.mipmap.play));
    }

    @Override
    public void stopMode() {
        presenter.stopIntelligenceControl();
        RoomController.closeAllControllers();
        binding.chart.setData(null);
        RxJavaUtils.doInUIThread(new RxUITask<Object>(null) {
            @Override
            public void doInUIThread(Object o) {
                binding.chart.invalidate();
            }
        });
    }

    private void setGlobalTextColor(LineChart lineChart, int textColor) {
        // 设置 X 轴文字颜色
        XAxis xAxis = lineChart.getXAxis();
        xAxis.setTextColor(textColor);
        // 设置左侧 Y 轴文字颜色
        YAxis leftYAxis = lineChart.getAxisLeft();
        leftYAxis.setTextColor(textColor);
        // 设置右侧 Y 轴文字颜色
        YAxis rightYAxis = lineChart.getAxisRight();
        rightYAxis.setTextColor(textColor);
        // 设置图例文字颜色
        Legend legend = lineChart.getLegend();
        legend.setTextColor(textColor);
        // 更新图表
        lineChart.invalidate();
    }

    /**
     * 根据当前所处时间获取当前模板下标
     */
    private int getI(int hour) {
        for (int i = 0; i < modes.size(); i++) {
            hour -= modes.get(i).getExpectedHours();
            if (hour < 0) {
                return i;
            }
        }
        //时间大于全部时间
        return -1;
    }

    /**
     * 根据当前所处时间获取当前龄期的第几天
     */
    private int getDay() {
        int hour = AIModelSet.getStartToNowHours();
        for (int i = 0; i < modes.size(); i++) {
            hour -= modes.get(i).getExpectedHours();
            if (hour < 0) {
                return (int) (modes.get(i).getExpectedHours() + hour) / 24 + 1;
            }
        }
        //时间大于全部时间
        return -1;
    }

    /**
     * 刷新全部显示信息
     */
    public void refreshInfo() {
        modes = MyAIModeUtil.getMyAiMode();
        int hourTotal = AIModelSet.getStartToNowHours();
        age = getI(hourTotal);
        day = getDay();
        if (age < 0) {
            // 当前在模板中的时间已经超出模板范围
            return;
        }
        modes = MyAIModeUtil.getMyAiMode();
        mode = modes.get(age);
        SilkwormNew silkworm = SilkwormDBManager.getLatestSilkworm();
        binding.tvRoomName.setText((RoomSetting.getType() == 4 ? "催青" : "共育") + "第");
        binding.tvInstar.setText(mode.getName() + "第" + day + "天");
        binding.tvDay.setText("" + SilkwormDBManager.getStartToNowDays());
        binding.tvSeason.setText(silkworm.getName());
        binding.tvVariety.setText(silkworm.getVariety());
        binding.tvMode.setText(AIModelSet.getAiSchemeName());
        binding.tvTemperature.setText(mode.getTargetTemp() + "\t℃");
        binding.tvHumidity.setText(mode.getTargetHumi() + "\t%");
        binding.tvVentilator.setText("启" + mode.getTargetVentOpen() + "停" + mode.getTargetVentClose());
        AIModelSet.setTargetTemperature(mode.getTargetTemp());
        AIModelSet.setAiTargetHumidity(mode.getTargetHumi());
        AIModelSet.setAiCycleStart(mode.getTargetVentOpen());
        AIModelSet.setAiCycleStop(mode.getTargetVentClose());
        LimitLine limitLine = new LimitLine(AIModelSet.getStartToNowHours() + MARGIN, "★");
        limitLine.setLineColor(Color.parseColor("#FF8D28"));
        limitLine.setLineWidth(2f);
        limitLine.setTextSize(50f);
        limitLine.setTextColor(Color.parseColor("#FF8D28"));
        List<ILineDataSet> dataSets = new ArrayList<>();
        LineDataSet temperatureData = generateTemperatureData(modes);
        LineDataSet humidityData = generateHumidityData(modes);
        temperatureData.setValueTextColor(RoomSetting.isDarkTheme() ? Color.WHITE : Color.BLACK);
        humidityData.setValueTextColor(RoomSetting.isDarkTheme() ? Color.WHITE : Color.BLACK);
        dataSets.add(temperatureData);
        dataSets.add(humidityData);
        XAxis xAxis = binding.chart.getXAxis();
        xAxis.removeAllLimitLines();
        xAxis.addLimitLine(limitLine);
        xAxis.setAxisMaximum(Math.max(temperatureData.getXMax(), humidityData.getXMax()) + MARGIN);
        xAxis.setAxisMinimum(Math.min(temperatureData.getXMin(), humidityData.getXMin()) - MARGIN);
        binding.chart.setData(new LineData(dataSets));
        binding.chart.invalidate();
    }

    /**
     * 获取温度曲线数据
     */
    private LineDataSet generateTemperatureData(List<AITHMode> modes) {
        ArrayList<Entry> entries = new ArrayList<>();
        float x = MARGIN;
        float y = 0;
        for (AITHMode mode : modes) {
            y = (float) mode.getTargetTemp();
            entries.add(new Entry(x, y));
            x += mode.getExpectedHours();
        }
        entries.add(new Entry(x, y));
        LineDataSet set = new LineDataSet(entries, "温度(°C)    ");
        set.setColor(Color.parseColor("#00D262"));
        set.setLineWidth(2f);
        set.setCircleColor(Color.parseColor("#00D262"));
        set.setCircleRadius(5f);
        set.setFillColor(Color.parseColor("#00D262"));
        set.setMode(LineDataSet.Mode.STEPPED);
        set.setDrawValues(true);
        set.setAxisDependency(YAxis.AxisDependency.LEFT);
        set.setValueTextSize(22);
        set.setValueTextColor(Color.parseColor("#424242"));
        return set;
    }

    /**
     * 获取湿度曲线数据
     */
    private LineDataSet generateHumidityData(List<AITHMode> modes) {
        ArrayList<Entry> entries = new ArrayList<>();
        float x = MARGIN;
        float y = 0;
        for (AITHMode mode : modes) {
            y = (float) mode.getTargetHumi();
            entries.add(new Entry(x, y));
            x += mode.getExpectedHours();
        }
        entries.add(new Entry(x, y));
        LineDataSet set = new LineDataSet(entries, "湿度(%)");
        set.setColor(Color.parseColor("#00A1FF"));
        set.setLineWidth(2f);
        set.setCircleColor(Color.parseColor("#00A1FF"));
        set.setCircleRadius(5f);
        set.setFillColor(Color.parseColor("#00A1FF"));
        set.setMode(LineDataSet.Mode.STEPPED);
        set.setDrawValues(true);
        set.setAxisDependency(YAxis.AxisDependency.RIGHT);
        set.setValueTextSize(22);
        set.setValueTextColor(Color.parseColor("#424242"));
        return set;
    }

}
