package com.bonait.bnframework.business;

import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import com.bonait.bnframework.common.constant.ConfigName;
import com.bonait.bnframework.common.db.QueryDB;
import com.bonait.bnframework.common.db.mode.BPA_GOODSRECIPE;
import com.bonait.bnframework.common.db.mode.BPA_SILOS;
import com.bonait.bnframework.common.helper.I.IWriteCallBack;
import com.bonait.bnframework.common.utils.ToastUtils;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExecuteTest {
    public static int whileTime = 80;

    /**
     * 商品是否强制结束
     */
    public static boolean IsForcedEnd = false;

    /**
     * 是否启动
     */
    public static boolean IsStart = false;

    //region 强制结束

    /**
     * 设置强制结束
     */
    public static void SetForcedEnd() {
        ToastUtils.info("客官,小菠萝正在强制结束,请耐心等候!!!");
        IsForcedEnd = true;
    }

    /**
     * 停止强制结束
     */
    public static void StopForcedEnd() {
        IsForcedEnd = false;
    }
    //endregion

    //region 执行配方
    /**
     * 执行工序步骤
     *
     * @param text
     */
    public static void ExecuteOperationSteps(String processname, String text) {
        try {
            if (!text.isEmpty() && !processname.isEmpty() && !IsForcedEnd) {
                //工序名称和值
                HashMap<String, String> formulation = new HashMap<>();
                //region 获取仓号和值
                List<String> data = new ArrayList<>();
                if (text.contains("|")) {
                    String[] res = text.split("[|]");
                    for (int i = 0; i < res.length; i++) {
                        data.add(res[i]);
                    }
                } else {
                    data.add(text);
                }
                for (String item : data) {
                    if (!item.isEmpty() && item.contains(",")) {
                        String[] wl = item.split("[,]");
                        if (wl != null && wl.length == 2) {
                            String name = wl[0];
                            String val = wl[1];
                            formulation.put(name, val);
                        }
                    }
                }
                //endregion
                //写入PLC
                if (formulation.size() > 0) {
                    switch (processname) {
                        case "搅拌":
                            Write_PLC_Stir(formulation);
                            break;
                        case "位置":
                            Write_PLC_Location(formulation);
                            break;
                        case "加热":
                            Write_PLC_Heating(formulation);
                            break;
                        case "主料":
                            Write_PLC_Ingredients(formulation);
                            break;
                        case "延迟":
                            Write_PLC_Delay(formulation);
                            break;
                        case "清洗":
                            Write_PLC_CleanPan(formulation);
                            break;
                    }
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }
    //endregion

    //region 物料PLC控制

    /**
     * 写入仓号需求值
     *
     * @param silos
     * @param val
     */
    public static void Write_PLC_Material(int silos, int val) {
        try {
            if(IsForcedEnd){ return;}
            ToastUtils.info("准备写入PLC仓号需求:" + silos + "," + val );

            String name = "料仓" + silos + "下料完成";
            ExecuteTheRecipe.WritePLC(name, false, null);

            final boolean[] IsComplete = {false};

            ExecuteTheRecipe.WritePLC("料仓" + silos + "需求值", val, new IWriteCallBack() {
                @Override
                public void onSuccess() {
                    BottomClick("料仓" + silos + "下料");
                    IsComplete[0] = true;
                }

                @Override
                public void onFailure(String ErrorMsg) {
                }
            });
            long a = System.currentTimeMillis();
            while (!IsComplete[0] && !IsForcedEnd) {
                if ((System.currentTimeMillis() - a) > 1000 * whileTime) {
                    break;
                }
                Thread.sleep(100);//10 *6
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }
    //endregion

    //region 写PLC工序

    /**
     * 写PLC搅拌
     *
     * @param data
     */
    private static void Write_PLC_Stir(HashMap<String, String> data) {
        try {
            int val = 0;

            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (key.contains("(秒)")) {
                    val = Integer.parseInt(value);
                } else {
                    ToastUtils.info("工序:" + key + "," + value);
                    int writeValue = GetMXValue(key, value);
                    ExecuteTheRecipe.WritePLC(key, writeValue, new IWriteCallBack() {
                        @Override
                        public void onSuccess() {
                            if (writeValue == 0) {
                                ExecuteTheRecipe.WritePLC("搅拌", false, null);
                            } else {
                                ExecuteTheRecipe.WritePLC("搅拌", true, null);
                            }
                        }

                        @Override
                        public void onFailure(String ErrorMsg) {
                        }
                    });
                }
            }

            if (val > 0) {
                ThreadDelay(val);
                //Thread.sleep(val * 1000);
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }

    /**
     * 写PLC位置
     *
     * @param data
     */
    private static void Write_PLC_Location(HashMap<String, String> data) {
        try {
            int val = 0;
            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (key.contains("(秒)")) {
                    val = Integer.parseInt(value);
                } else if (key.contains("速度")) {
                    int writeValue = GetMXValue(key, value);
                    //修改最高速度40
                    ExecuteTheRecipe.WritePLC(key, writeValue >= 30 ? 30 : writeValue, null);
                }
            }

            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (!key.contains("(秒)") && !key.contains("速度")) {
                    ToastUtils.info("工序:" + key + "," + value);

                    //原点位,等待机器移动倒响应位置
                    BottomClick1(value);
                    //一直等待机器移动到该位置，否则就一直等待 6s超时
                    String name = value + "反馈";
                    final boolean[] IsComplete = {false};
                    long a = System.currentTimeMillis();
                    Log.e("等待反馈", name + ",等待中");
                    while (!IsComplete[0] && !IsForcedEnd) {
                        if ((System.currentTimeMillis() - a) > 1000 * whileTime) {
                            break;
                        } else {
                            Object sb = ExecuteTheRecipe.ReadPLC(name);//ListeningValue.get(name);
                            if (sb != null) {
                                IsComplete[0] = (boolean) (sb);
                            }
                        }
                        Thread.sleep(100);//10 *6
                    }
                    Log.e("等待反馈", name + ",等待结束");

                    ToastUtils.info("炒锅到达" + value + ",继续制作!!!");
                }
            }

            if (val > 0 && !IsForcedEnd) {
                ThreadDelay(val);
                //Thread.sleep(val * 1000);
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }

    /**
     * 写PLC主料
     *
     * @param data
     */
    private static void Write_PLC_Ingredients(HashMap<String, String> data) {
        try {
            //是否手动
            boolean ishand = true;
            ToastUtils.info("准备倒入主料！");

            //region 判断是否手动
            if (ConfigName.getInstance().versionSelectionEnum.equals("大炒版本")) {
                ishand = true;
            } else {
                for (HashMap.Entry<String, String> entry : data.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    if (key.contains("投料动作")) {
                        if (value.contains("手动投料")) {
                            ishand = true;
                        } else {
                            ishand = false;
                        }
                    }
                }
            }
            //endregion


            if (ConfigName.getInstance().versionSelectionEnum.equals("大炒自动投料版本") || ConfigName.getInstance().versionSelectionEnum.equals("小炒版本")) {
                String writeValue = "1号位";
                for (HashMap.Entry<String, String> entry : data.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    if (key.contains("主料位置")) {
                        writeValue = value;
                    }
                }


                //1.去某一个位置
                BottomClick1("平移-去" + writeValue);


                Log.d("平移", "平移-去" + writeValue);
                //一直等待机器移动到该位置，否则就一直等待 6s超时
                String name = "平移轴在" + writeValue;
                final boolean[] IsComplete = {false};
                long a = System.currentTimeMillis();
                while (!IsComplete[0] && !IsForcedEnd) {
                    if ((System.currentTimeMillis() - a) > 1000 * whileTime) {
                        break;
                    } else {
                        Object sb = ExecuteTheRecipe.ReadPLC(name);// ListeningValue.get(name);
                        if (sb != null) {
                            IsComplete[0] = (boolean) (sb);
                        }
                    }
                    Thread.sleep(100);//10 *6
                }
                Log.d("平移", name + "已经就位");

                //2.给倒菜启动
                BottomClick1("主料");
                name = "倒菜完成";
                IsComplete[0] = false;
                a = System.currentTimeMillis();
                while (!IsComplete[0] && !IsForcedEnd) {
                    if ((System.currentTimeMillis() - a) > 1000 * whileTime) {
                        break;
                    } else {
                        Object sb = ExecuteTheRecipe.ReadPLC(name);// ListeningValue.get(name);
                        if (sb != null) {
                            IsComplete[0] = (boolean) (sb);
                        }
                    }
                    Thread.sleep(100);//10 *6
                }
                ToastUtils.info("主料倒入完成,继续制作！");

            }

            Log.d("倒菜", "倒菜完成了");
            //判断是否有烹饪时间
            int val = 0;
            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (key.contains("(秒)")) {
                    val = Integer.parseInt(value);
                }
            }
            if (val > 0 && !IsForcedEnd) {
                ThreadDelay(val);
                //Thread.sleep(val * 1000);
            }

            Log.d("烹饪时间", "烹饪时间完成了");


        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }

    /**
     * 按下
     *
     * @param name
     */
    public static void BottomClick(String name) {
        try {
            Log.e("按钮按下", name);
            ExecuteTheRecipe.WritePLC(name, true, null);
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    Log.e("按钮复位", name);
                    ExecuteTheRecipe.WritePLC(name, false, null);
                }
            }, 500);
        } catch (Exception ex) {
            Log.e("按钮异常", name + ex.getMessage());
        }
    }

    /**
     * 组断执行
     *
     * @param name
     */
    public static void BottomClick1(String name) {
        try {
            Log.e("按钮按下", name);
            ExecuteTheRecipe.WritePLC(name, true, null);
            Thread.sleep(200);
            ExecuteTheRecipe.WritePLC(name, false, null);
            Log.e("按钮复位", name);
        } catch (Exception ex) {
            Log.e("按钮异常", name + ex.getMessage());
            ExecuteTheRecipe.WritePLC(name, false, null);
        }
    }

    /**
     * 写PLC 加热
     *
     * @param data
     */
    private static void Write_PLC_Heating(HashMap<String, String> data) {
        try {
            int val = 0;
            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (key.contains("(秒)")) {
                    val = Integer.parseInt(value);
                } else {
                    ToastUtils.info("工序:" + key + "," + value);
                    int writeValue = GetMXValue(key, value);
                    //写加热挡位
                    ExecuteTheRecipe.WritePLC(key, writeValue, null);
                    if (writeValue == 0) {
                        ConfigName.getInstance().IsOpenHuoLi = false;
                        ExecuteTheRecipe.WritePLC("加热", false, null);
                    } else {
                        ConfigName.getInstance().IsOpenHuoLi = true;
                        ExecuteTheRecipe.WritePLC("加热", true, null);
                    }
                }
            }

            if (val > 0 && !IsForcedEnd) {
                ThreadDelay(val);
                //Thread.sleep(val * 1000);
            }

        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }

    /**
     * 火力点击
     *
     * @param data
     */
    public static void Write_PLC_HuoLI(int data) {
        try {
            ExecuteTheRecipe.WritePLC("加热功率", data, new IWriteCallBack() {
                @Override
                public void onSuccess() {
                    if (data == 0) {
                        ConfigName.getInstance().IsOpenHuoLi = false;
                        ExecuteTheRecipe.WritePLC("加热", false, null);
                    } else {
                        ConfigName.getInstance().IsOpenHuoLi = true;
                        ExecuteTheRecipe.WritePLC("加热", true, null);
                    }
                }

                @Override
                public void onFailure(String ErrorMsg) {
                }
            });
            ToastUtils.info("火力按钮点击,当前级别：" + data);

        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }

    /**
     * 写PLC 延迟
     *
     * @param data
     */
    private static void Write_PLC_Delay(HashMap<String, String> data) {
        try {
            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                ToastUtils.info("工序:" + key + "," + value);
                if (key.contains("(秒)") && !IsForcedEnd) {
                    int val = Integer.parseInt(value);
                    ThreadDelay(val);
                    //Thread.sleep(val * 1000);
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }

    /**
     * 写PLC 清洗
     *
     * @param data
     */
    private static void Write_PLC_CleanPan(HashMap<String, String> data) {
        try {
            ToastUtils.info("准备清洗！");
            //先延迟
            for (HashMap.Entry<String, String> entry : data.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                ToastUtils.info("工序:" + key + "," + value);
                if (key.contains("(秒)") && !IsForcedEnd) {
                    int val = Integer.parseInt(value);
                    ThreadDelay(val);
                    //Thread.sleep(val * 1000);
                }
            }



            //一直等待机器移动到该位置，否则就一直等待 6s超时
            String name = "炒锅清洗反馈";
            ExecuteTheRecipe.WritePLC(name,false,null);

            BottomClick1("炒锅清洗");

            final boolean[] IsComplete = {false};
            long a = System.currentTimeMillis();
            while (!IsComplete[0] && !IsForcedEnd) {
                if ((System.currentTimeMillis() - a) > 1000 * (whileTime * 5)) {
                    break;
                } else {
                    Object sb = ExecuteTheRecipe.ReadPLC(name);//ListeningValue.get(name);
                    if (sb != null) {
                        IsComplete[0] = (boolean) (sb);
                    }
                }
                Thread.sleep(100);//10 *6
            }

            ToastUtils.info("炒锅清洗完成！");
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        }
    }
    //endregion

    //region 获取基础挡位变量
    /**
     * 获取挡位变量
     *
     * @param name
     * @param value
     * @return
     */
    public static int GetMXValue(String name, String value) {
        final int[] ReturnsVariable = {0};
        try {
            if (name.contains("速度")) {
                ReturnsVariable[0] = ConfigName.getInstance().StirringSpeed.get(value);
            } else if (name.contains("功率")) {
                ReturnsVariable[0] = ConfigName.getInstance().HeatingGear.get(value);
                int max = ConfigName.getInstance().HeatingGear.get(ConfigName.getInstance().HuoLi);
                if (ReturnsVariable[0] > max) {
                    ReturnsVariable[0] = max;
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
            return ReturnsVariable[0];
        }
    }
    //endregion

    //region 延迟函数

    /**
     * 线程延迟函数(避免线程阻塞等待)
     *
     * @param delay
     */
    public static void ThreadDelay(int delay) {
        long startTime = System.currentTimeMillis();
        while ((System.currentTimeMillis() - startTime) <= (delay * 1000) && !IsForcedEnd) //
        {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
        }
    }
    //endregion

    //region 获取工艺
    /**
     * 获取延迟
     *
     * @param time
     * @return
     */
    public static BPA_GOODSRECIPE Get延迟(int time) {
        BPA_GOODSRECIPE pf = new BPA_GOODSRECIPE();
        pf.materialType = 1;
        pf.processname = "延迟";
        pf.processms = "延迟(" + time + ")";
        pf.processvalue = "延迟(秒)," + time;
        return pf;
    }

    /**
     * 获取主料
     *
     * @param wz
     * @return
     */
    public static BPA_GOODSRECIPE Get主料(int wz) {
        String ms = "未知";
        BPA_GOODSRECIPE pf = new BPA_GOODSRECIPE();
        pf.materialType = 1;
        pf.processname = "主料";
        pf.processms = "主料(" + ms + "," + wz + "号位,0,直接投出,0)";
        pf.processvalue = "主料名称," + ms + "|主料位置," + wz + "号位|主料重量,0|投料动作,直接投出|烹饪(秒),0";
        return pf;
    }
    /**
     * 获取位置
     *
     * @param
     * @return
     */
    public static BPA_GOODSRECIPE Get位置(String name) {
        BPA_GOODSRECIPE pf = new BPA_GOODSRECIPE();
        pf.materialType = 1;
        pf.processname = "位置";
        pf.processms = "位置(高速," + name + ",0)";
        pf.processvalue = "转动速度,高速|位置动作," + name + "|延迟(秒),0";
        return pf;
    }

    /**
     * 获取搅拌
     *
     * @param sd
     * @return
     */
    public static BPA_GOODSRECIPE Get搅拌(String sd) {
        BPA_GOODSRECIPE pf = new BPA_GOODSRECIPE();
        pf.materialType = 1;
        pf.processname = "搅拌";
        pf.processms = "搅拌(" + sd + ",0)";
        pf.processvalue = "搅拌速度," + sd + "|延迟(秒),0";
        return pf;
    }

    /**
     * 获取加热
     *
     * @param sd
     * @return
     */
    public static BPA_GOODSRECIPE Get加热(String sd) {
        BPA_GOODSRECIPE pf = new BPA_GOODSRECIPE();
        pf.materialType = 1;
        pf.processname = "加热";
        pf.processms = "加热(" + sd + ",0)";
        pf.processvalue = "加热功率," + sd + "|延迟(秒),0";
        return pf;
    }

    /**
     * 获取清洗
     *
     * @return
     */
    public static BPA_GOODSRECIPE Get清洗(int k) {
        BPA_GOODSRECIPE pf = new BPA_GOODSRECIPE();
        pf.materialType = 1;
        pf.processname = "清洗";
        pf.processms = "清洗(" + k + ")";
        pf.processvalue = "等待(秒)," + k;
        return pf;
    }
    //endregion
}
