package com.example.bpa.service;

import com.example.bpa.Model.IRun;
import com.example.bpa.Model.IThread;
import com.example.bpa.Model.IWriteCallBack;
import com.example.bpa.Model.ResultA;
import com.example.bpa.config.DataBus;
import com.example.bpa.db.QueryDB;
import com.example.bpa.db.mode.BPA_GOODS;
import com.example.bpa.db.mode.BPA_SILOS;
import com.example.bpa.db.mode.BPA_SUBORDER;
import com.example.bpa.db.mode.BPA_SUGAR;
import com.example.bpa.helper.MessageLog;
import com.example.bpa.helper.ModbusTcpServer;
import com.example.bpa.helper.ThreadManager;
import com.example.bpa.view.mode.AlertLogEnum;
import com.example.bpa.view.mode.ResGoodsRecipe;
import com.example.bpa.view.mode.UserLogEnum;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 业务服务
 */
public class BusinessServer {
    private static volatile BusinessServer _instance;

    public static BusinessServer Get() {
        if (_instance == null)
            _instance = new BusinessServer();
        return _instance;
    }

    private BusinessServer() {
    }

    /**
     * 商品制作队列
     */
    public ConcurrentLinkedQueue<BPA_SUBORDER> Commoditys = new ConcurrentLinkedQueue<BPA_SUBORDER>();

    /**
     * 增加一个子订单
     *
     * @param info 配方信息
     */
    public void AddCommodity(BPA_SUBORDER info) {
        //1.添加制作队列
        Commoditys.offer(info);
        //2.数据中心添加制作队列商品数据
        DataBus.getInstance().AddGoodsMake(info);
    }

    /**
     * 订单制作线程新->增加物料检查(物料检测临时屏蔽-后续 需放开)
     */
    public void Init() {
        ThreadManager.Get().StartLong("订单执行业务流程-新", true, new IThread() {
            @Override
            public void Run() throws InterruptedException {
                while (Commoditys.size() > 0) {
                    //1.取出需要制作的订单商品 验证物料是否充足
                    BPA_SUBORDER suborder = Commoditys.peek();
                    String GoodId = suborder.goodsID;
                    try {
//                    boolean IsMake=true;
                        ResultA resultA = DataBus.getInstance().InspectMaterial(GoodId);
//                    if(resultA.IsMake==false)//如果商品物料不足
//                    {
//                        DataBus.getInstance().UpdateGoodsMake(GoodId,resultA.Message,0);
//                        MessageLog.ShowAlertMessage(AlertLogEnum.料仓缺料日志,resultA.Message);
//                        IsMake=false;
//                    }
//                    while (!IsMake) {
//                        IsMake=DataBus.getInstance().InspectMaterial(GoodId).IsMake;
//                        Thread.sleep(2000);
//                    }
                        //2.获取商品的配方信息
                        ArrayList<ResGoodsRecipe> goods = QueryDB.GetGoodsSrecipeList(GoodId);
                        BPA_GOODS good = QueryDB.GetGoodsId(GoodId);
                        //3.根据物料配方排序Sort步骤分组
                        //region 根据物料配方排序Sort步骤分组
                        LinkedHashMap<Integer, List<ResGoodsRecipe>> rgrs = new LinkedHashMap<>();
                        for (int i = 0; i < goods.size(); i++) {
                            if (!rgrs.containsKey(goods.get(i).sort))
                                rgrs.put(goods.get(i).sort, new ArrayList<>());
                            rgrs.get(goods.get(i).sort).add(goods.get(i));
                        }
                        //endregion
                        //4.根据步骤分组进行物料下发
                        //region 物料下发
                        int count = 0;
                        for (LinkedHashMap.Entry<Integer, List<ResGoodsRecipe>> entry : rgrs.entrySet()) {
                            final Integer key = entry.getKey();
                            //当前一次性下发物料集合
                            List<ResGoodsRecipe> goodsRecipes = entry.getValue();
                            String RecipesNames = "";
                            for (ResGoodsRecipe item : goodsRecipes) {
                                RecipesNames += item.materialName + ",";
                            }
                            DataBus.getInstance().UpdateGoodsMake(suborder.id, "步骤【" + key + "】准备下发物料:" + RecipesNames, count,key,false);
                            ArrayList<Integer> liaochang = new ArrayList<Integer>();
                            for (int m = 0; m < goodsRecipes.size(); m++) {
                                ResGoodsRecipe recipe = goodsRecipes.get(m);
                                int materialType = recipe.materialType;
                                final String message = "[" + good.name + "]步骤【" + key + "】下发【" + recipe.materialName + "】";
                                if (materialType == 1)//1.正常物料
                                {
                                    //获取物料关联的料仓信息
                                    BPA_SILOS silos = null;
                                    List<BPA_SILOS> siloslist = QueryDB.GetSolisByMaterialID(recipe.materialID);
                                    for (BPA_SILOS item : siloslist) {
                                        //临时屏蔽物料量检测
                                        // if(DeviceData.Get().getCallCurrentWeight(item.num)>=recipe.value){silos=item;break;}
                                        silos = item;
                                    }
                                    if (silos == null) {
                                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "下发失败！物料没有管理料仓！");
                                    } else {
                                        liaochang.add(silos.num);
                                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "准备下发【" + silos.num + "】号料仓PLC控制命令,需求量:=" + recipe.value);
                                        DeviceData.Get().setDemandValue((short) recipe.value, silos.num, new IWriteCallBack() {
                                            @Override
                                            public void onSuccess() {
                                                MessageLog.ShowInfo(message + "下发成功！");
                                            }
                                            @Override
                                            public void onFailure(String ErrorMsg) {
                                                MessageLog.ShowInfo(message + "下发失败！" + ErrorMsg);
                                            }
                                        });
                                    }
                                } else if (materialType == 2)//果糖-单按钮控制
                                {
                                    BPA_SUGAR bs = QueryDB.GetsugarId(recipe.materialID);
                                    ModbusTcpServer.get().WriteBool(bs.plcvar, true);
                                    Thread.sleep(200);
                                    ModbusTcpServer.get().WriteBool(bs.plcvar, false);
                                    MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "下发成功！");
                                }
                                //将其余料仓出料设置为0,重置
                                for (int k = 1; k <= 12; k++) {
                                    if (!liaochang.contains(k)) {
                                        DeviceData.Get().setDemandValue((short) 0, k, new IWriteCallBack() {
                                            @Override
                                            public void onSuccess() {
                                            }
                                            @Override
                                            public void onFailure(String ErrorMsg) {
                                            }
                                        });
                                    }
                                }
                            }
                            //等待配料完成，一直等待
                            final boolean[] IsComplete = {false};
                            DeviceData.Get().OnChargeMixtureCompleteNotify = new IRun() {
                                @Override
                                public void Run() {
                                    IsComplete[0] = true;
                                    MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + good.name + "]步骤【" + key + "】配料完成!");
                                }
                            };
                            //启动配料
                            DeviceData.Get().setChargeMixtureStart(new IWriteCallBack() {
                                @Override
                                public void onSuccess() {
                                    MessageLog.ShowInfo("[" + good.name + "]步骤【" + key + "】启动配料成功！");
                                }

                                @Override
                                public void onFailure(String ErrorMsg) {
                                    MessageLog.ShowInfo("[" + good.name + "]步骤【" + key + "】启动配料失败！");
                                    MessageLog.ShowAlertMessage(AlertLogEnum.异常订单未制作日志, "[" + good.name + "]步骤【" + key + "】启动配料失败！");
                                }
                            });
                            while (!IsComplete[0]) {
                                Thread.sleep(100);
                            }
                            //更新缓存商品制作列表状态
                            count += goodsRecipes.size();
                            DataBus.getInstance().UpdateGoodsMake(suborder.id, "步骤【" + key + "】:" + RecipesNames + "-配料完成!", count,key,true);
                            MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + good.name + "]步骤【" + key + "】下发" + RecipesNames + "执行完成!");
                        }
                        //endregion
                        //5.设置数据中心商品已制作完成
                        DataBus.getInstance().DeleteGoodsMake(suborder.id);
                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + good.name + "]-订单执行完成,请取餐!");
                        Commoditys.poll();
                    } catch (Exception ex) {
                    }
                }
                Thread.sleep(1000);
            }
            @Override
            public void RunComplete() throws InterruptedException {
                ;
            }
        });
    }
    /**
     * 测试专用
     */
    public void test() {
        ThreadManager.Get().StartLong("订单执行业务流程-测试", true, new IThread() {
            @Override
            public void Run() throws InterruptedException {
                while (Commoditys.size() > 0) {
                    //1.取出需要制作的订单商品 验证物料是否充足
                    BPA_SUBORDER suborder = Commoditys.peek();
                    String GoodId = suborder.goodsID;
                    try {
//                    boolean IsMake=true;
//                    ResultA resultA= DataBus.getInstance().InspectMaterial(GoodId);
//                    if(resultA.IsMake==false)//如果商品物料不足
//                    {
//                        DataBus.getInstance().UpdateGoodsMake(GoodId,resultA.Message,0);
//                        IsMake=false;
//                    }
//                    while (!IsMake) {
//                        IsMake=DataBus.getInstance().InspectMaterial(GoodId).IsMake;
//                        Thread.sleep(2000);
//                    }
                        //2.获取商品的配方信息
                        ArrayList<ResGoodsRecipe> goods = QueryDB.GetGoodsSrecipeList(GoodId);
                        BPA_GOODS good = QueryDB.GetGoodsId(GoodId);
                        //3.根据物料配方排序Sort步骤分组
                        //region 根据物料配方排序Sort步骤分组
                        LinkedHashMap<Integer, List<ResGoodsRecipe>> rgrs = new LinkedHashMap<>();
                        for (int i = 0; i < goods.size(); i++) {
                            if (!rgrs.containsKey(goods.get(i).sort))
                                rgrs.put(goods.get(i).sort, new ArrayList<>());
                            rgrs.get(goods.get(i).sort).add(goods.get(i));
                        }
                        //endregion
                        //4.根据步骤分组进行物料下发
                        //region 物料下发
                        int count = 0;
                        for (LinkedHashMap.Entry<Integer, List<ResGoodsRecipe>> entry : rgrs.entrySet()) {
                            final Integer key = entry.getKey();
                            //当前一次性下发物料集合
                            List<ResGoodsRecipe> goodsRecipes = entry.getValue();
                            String RecipesNames = "";
                            for (ResGoodsRecipe item : goodsRecipes) {
                                RecipesNames += item.materialName + ",";
                            }
                            DataBus.getInstance().UpdateGoodsMake(suborder.id, "步骤【" + key + "】准备下发物料:" + RecipesNames, count,key,false);
                            for (int m = 0; m < goodsRecipes.size(); m++) {
                                ResGoodsRecipe recipe = goodsRecipes.get(m);
                                int materialType = recipe.materialType;
                                final String message = "[" + good.name + "]步骤【" + key + "】下发【" + recipe.materialName + "】";
                                if (materialType == 1)//1.正常物料
                                {
                                    //获取物料关联的料仓信息
                                    BPA_SILOS silos = null;
                                    List<BPA_SILOS> siloslist = QueryDB.GetSolisByMaterialID(recipe.materialID);
                                    for (BPA_SILOS item : siloslist) {
                                        //临时屏蔽物料量检测
                                        // if(DeviceData.Get().getCallCurrentWeight(item.num)>=recipe.value){silos=item;break;}
                                        silos = item;
                                    }
                                    if (silos == null) {
                                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "下发失败！物料没有管理料仓！");
                                    } else {
                                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "准备下发【" + silos.num + "】号料仓PLC控制命令,需求量:=" + recipe.value);
//                                    DeviceData.Get().setDemandValue((short) recipe.value, silos.num, new IWriteCallBack() {
//                                        @Override
//                                        public void onSuccess() {
//                                            MessageLog.ShowInfo(message+"下发成功！");
//                                        }
//                                        @Override
//                                        public void onFailure(String ErrorMsg) {
//                                            MessageLog.ShowInfo(message+"下发失败！"+ErrorMsg);
//                                        }
//                                    });
                                        Thread.sleep(1000);
                                    }
                                } else if (materialType == 2)//果糖
                                {
//                                BPA_SUGAR bs = QueryDB.GetsugarId(recipe.materialID);
//                                ModbusTcpServer.get().WriteBool(bs.plcvar, true);
//                                Thread.sleep(200);
//                                ModbusTcpServer.get().WriteBool(bs.plcvar, false);
//                                MessageLog.ShowUserMessage(UserLogEnum.订单处理日志,message+"下发成功！");
                                }
                            }
                            //启动配料
//                        DeviceData.Get().setChargeMixtureStart(new IWriteCallBack() {
//                            @Override
//                            public void onSuccess() {
//                                MessageLog.ShowInfo("["+good.name+"]步骤【" + key+ "】启动配料成功！");
//                            }
//                            @Override
//                            public void onFailure(String ErrorMsg) {
//                                MessageLog.ShowInfo("["+good.name+"]步骤【" + key+ "】启动配料失败！");
//                            }
//                        });
                            Thread.sleep(1000);
                            //等待配料完成，一直等待
//                        final boolean[] IsComplete = {false};
//                        DeviceData.Get().OnChargeMixtureCompleteNotify = new IRun() {
//                            @Override
//                            public void Run() {
//                                IsComplete[0] = true;
//                                MessageLog.ShowUserMessage(UserLogEnum.订单处理日志,"["+good.name+"]步骤【" + key+ "】配料完成!");
//                            }
//                        };
//                        while (!IsComplete[0]) {
//                            Thread.sleep(100);
//                        }
                            //更新缓存商品制作列表状态
                            count += goodsRecipes.size();
                            DataBus.getInstance().UpdateGoodsMake(suborder.id, "步骤【" + key + "】:" + RecipesNames + "-配料完成!", count,key,true);
                            MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + good.name + "]步骤【" + key + "】下发" + RecipesNames + "执行完成!");
                        }
                        //endregion
                        //5.设置数据中心商品已制作完成
                        DataBus.getInstance().DeleteGoodsMake(suborder.id);
                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + good.name + "]-订单执行完成,请取餐!");
                        Commoditys.poll();
                    } catch (Exception ex) {
                        MessageLog.ShowInfo("异常信息！" + ex.getMessage());
                    }
                }
                Thread.sleep(1000);
            }

            @Override
            public void RunComplete() throws InterruptedException {
            }
        });
    }
}
