using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WCS.Data;
using WCS.Data.Models;
using WCS.Data.Utils;
using WCS.PLC;
namespace WCS.Workflow
{
    public class ConveyorPlc01 : Base_Conv
    {
        #region 只读变量
        private readonly string Conv_1002 = "1002";
        private readonly string Conv_1004 = "1004";
        private readonly string Conv_1013 = "1013";
        private readonly string Conv_1023 = "1023";
        private readonly string Conv_1009 = "1009";
        private readonly string Conv_1454 = "1454";
        private readonly string Conv_1455 = "1455";
        private readonly string Conv_1456 = "1456";
        private readonly string Conv_1441 = "1441";
        private readonly string Conv_1440 = "1440";
        private readonly string Conv_1442 = "1442";
        private readonly string Conv_1445 = "1445";
        private readonly string Conv_1447 = "1447";
        private readonly string Conv_1449 = "1449";
        private readonly string Conv_1451 = "1451";
        #endregion;
        #region 重载实现
        /// 
        /// 调度PLC执行任务
        /// 
        public override void Run()
        {
            //刷新任务数据
            WCSWorkflow.RefreshData();
            //扫码执行任务
            Conv_ScanBarCodeExeTask();
            //电控无扫码执行任务
            Conv_NoScanExeTask();
            //堆垛机出口任务执行
            SrmOutConvExeTask();
            //出口任务完成
            ConvTaskFinish();
            //输送机执行任务
            ConveyorWriteTaskExecute();
        }
        #endregion;
        #region 多线程调用
        #endregion;
        #region 模块调用
        private void Conv_NoScanExeTask()
        {
            Conv_NotScannExeTask(Conv_1013, string.Empty);
            //ThreadHelper.TaskThread(Conv_NotScannExeTask_1013);
            //ThreadHelper.TaskThread(Conv_NotScannExeTask_1004);
            //Conv_NotScannExeTask(Conv_1004, string.Empty, false, 1);
        }
        private static int _conv_NotScannExeTask = 0;
        /// 
        /// 1013请求入库
        /// 
        public void Conv_NotScannExeTask_1013()
        {
            if (Interlocked.Exchange(ref _conv_NotScannExeTask, 1) == 0)
            {
                Conv_NotScannExeTask(Conv_1013, string.Empty, false, 0);
                Interlocked.Exchange(ref _conv_NotScannExeTask, 0);
            }
        }
        //public void Conv_NotScannExeTask_1004()
        //{
        //    if (Interlocked.Exchange(ref _conv_NotScannExeTask, 1) == 0)
        //    {
        //        Conv_NotScannExeTask(Conv_1004, string.Empty, false, 0);
        //        Interlocked.Exchange(ref _conv_NotScannExeTask, 0);
        //    }
        //}
        private void ConvTaskFinish()
        {
            ConveyorTaskFinish(PlcName, Conv_1454);
            ConveyorTaskFinish(PlcName, Conv_1455);
            ConveyorTaskFinish(PlcName, Conv_1456, false, true);
            ConveyorTaskFinish(PlcName, Conv_1445, false, true);
            ConveyorTaskFinish(PlcName, Conv_1447, false, true);
            ConveyorTaskFinish(PlcName, Conv_1449, false, true);
        }
        /// 
        /// 扫码执行任务
        /// 
        private void Conv_ScanBarCodeExeTask()
        {
            Conv_Scanning_1456();
            Conv_ScanningRequestIn(Conv_1451, Conv_1451);
            Conv_ScanningRequest(Conv_1004, Current.WareHouseId, Conv_1002);
        }
        /// 
        /// WCS写入输送线执行任务
        /// 
        private void ConveyorWriteTaskExecute()
        {
            ConveyorWriteTaskExecute(Conv_1009);
            ConveyorWriteTaskExecute(Conv_1023);
        }
        private void SrmOutConvExeTask()
        {
            SrmOutConvExeTask(PlcName, Conv_1454, true);
            SrmOutConvExeTask(PlcName, Conv_1455, true);
            SrmOutConvExeTask(PlcName, Conv_1456, true);
            SrmOutConvExeTask(PlcName, Conv_1441, false);
            SrmOutConvExeTask(PlcName, Conv_1442, true);
        }
        #endregion;
        #region 功能实现
        private void Conv_ScanningRequestIn(string convNo, string exitNo, bool iscurPosNo = true)
        {
            try
            {
                var plc = Current.PlcSet.FirstOrDefault(v => v.PLC_NAME == PlcName);
                var conveyor = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == convNo);
                var cs = conveyor.EquSignal_Conv;
                if (!cs.DB521_Request) return;
                if (cs.DB520_Confirm) return;
                WCS_TASK task = QueryTaskByBarcode(cs, convNo);
                if (task == null)
                {
                    var param = new GetInTaskParam()
                    {
                        ContainerBarCode = cs.BarCodeStr,
                        ContainerType = cs.DB521_Goodstype > 0 ? cs.DB521_Goodstype : 1,
                        MatBarCode = string.Empty,
                        WareHouseId = Current.Pvchouseputong,
                        EquipmentNo = convNo,
                        EndPostion = srm,
                        Memo2 = exitNo
                    };
                    task = ThreadHelper.TaskThread(BaseWorkflow.GetWcsInTask, param);
                }
                if (task == null) return;
                //判断任务是否已经执行
                if (task.TASK_WKSTATUS >= 2) return;
                bool notask = false;
                int goodsend = 0;
                if (task.TASK_COMTYPE == (int)ComTypeEnum.托盘异常退回)
                {
                    notask = true;
                    goodsend = Convert.ToInt32(exitNo);
                }
                else
                {
                    if (iscurPosNo)
                    {
                        goodsend = Convert.ToInt32(convNo);
                    }
                    else
                    {
                        var routeSet = EquRouteHelper.QueryRoute(convNo, task.TASK_POSIDTO);
                        var route = routeSet.FirstOrDefault(v => v.ROUTE_STARTPOS == convNo);
                        goodsend = Convert.ToInt32(route.ROUTE_SONPOS);
                    }
                }
                if (goodsend == 0) return;
                var converywrite = new WCSWriteToConveyorSignal()
                {
                    Plc = plc.Plc,
                    DBName = plc.WriteDBName,
                    ConveyorNo = convNo,
                    WriteStartAddress = cs.EquDbInfo_ReadWrite.DBReadIndox,
                    Tasknum = task.TASK_NO,
                    Goodstype = 1,
                    Goodssize = 0,//
                    Goodsstart = Convert.ToInt32(convNo),
                    Goodsend = goodsend,
                    Notask = notask
                };
                if (convNo == Conv_1451)
                {
                    LogMessageHelper.RecordLogMessage(string.Format("输送线[{0}]任务[{1}]条码[{2}]外检高度[{3}](零值默认为1)。", convNo, task.TASK_NO, cs.BarCodeStr, cs.DB521_Goodstype), true, LogLevelEnum.INFO.ToString());
                }
                WriteInfoToConv(cs, converywrite);
            }
            catch (Exception ex)
            {
                LogMessageHelper.RecordLogMessage(ex);
            }
        }
        
        protected override WCS_TASK ScanningCallWmsInterface(GetInTaskParam param)
        {
            //if (param.EquipmentNo == Conv_1004)
            //{
            //    param.Memo1 = "1";
            //}
            return base.ScanningCallWmsInterface(param);
        }
        /// 
        /// 输送线扫码执行
        /// 
        private void Conv_Scanning_1456()
        {
            try
            {
                var plc = Current.PlcSet.FirstOrDefault(v => v.PLC_NAME == PlcName);
                var conveyor = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == Conv_1456);
                var cs = conveyor.EquSignal_Conv;
                if (!cs.DB521_Request) return;
                if (cs.DB520_Confirm) return;
                if (cs.DB521_Tasknum <= 0) return;
                //if (cs.DB521_BCR_Noread) throw new Exception(string.Format("输送线[{0}]报读码错误,但是存在请求。", Conv_1456));
                //if (string.IsNullOrWhiteSpace(cs.BarCodeStr)) throw new Exception(string.Format("输送线[{0}]存在请求信号,但没读取到条码信息。", Conv_1456));
                //if (cs.BarCodeStr.ToUpper().Contains("ERROR") ||
                //    cs.BarCodeStr.ToUpper().Contains("N") ||
                //    cs.BarCodeStr.Contains("?"))
                //{
                //    throw new Exception(string.Format("输送线[{0}]存在请求信号,但条码是:[{1}]存在报错,PLC应该报条码错误信号", Conv_1456, cs.BarCodeStr));
                //}
                var converywrite = new WCSWriteToConveyorSignal();
                converywrite.Plc = plc.Plc;
                converywrite.DBName = plc.WriteDBName;
                converywrite.ConveyorNo = Conv_1456; 
                converywrite.WriteStartAddress = cs.EquDbInfo_ReadWrite.DBReadIndox;
                var tasktemp = Current.TaskSet.FirstOrDefault(v => v.TASK_POSIDTO == Conv_1456 && v.TASK_WKSTATUS > 1 && v.TASK_COMTYPE == 2);
                if (tasktemp != null) 
                {
                    converywrite.Notask = true;
                    string msg = string.Format("出入口[{0}]存在出库任务[{1}]不能执行入库", Conv_1456, tasktemp.TASK_NO);
                    BaseWorkflow.AddLedErrorMsg(Conv_1456, msg, 1);
                }
                else
                {
                    var task = QueryTaskByBarcode(cs, Conv_1456);
                    //var task = Current.TaskSet.FirstOrDefault(v => v.TASK_BOXBARCODE == cs.BarCodeStr);
                    if (task == null)
                    {
                        var param = new GetInTaskParam()
                        {
                            ContainerBarCode = cs.BarCodeStr,
                            ContainerType = 1,
                            MatBarCode = string.Empty,
                            WareHouseId = Current.Pvchouseputong,
                            EquipmentNo = Conv_1456,
                            EndPostion = srm,
                            Memo1 = "1",
                            Memo2 = Conv_1456
                        };
                        task = ThreadHelper.TaskThread(BaseWorkflow.GetWcsInTask, param);
                    }
                    if (task == null) return;
                    //判断任务是否已经执行
                    if (task.TASK_WKSTATUS >= 2) return;
                    if (task.TASK_COMTYPE == (int)ComTypeEnum.托盘异常退回)
                    {
                        converywrite.Notask = true;
                    }
                    converywrite.Tasknum = task.TASK_NO;
                    converywrite.Goodstype = 1;
                    converywrite.Goodssize = 0;//
                    converywrite.Goodsstart = Convert.ToInt32(Conv_1456);
                    converywrite.Goodsend = converywrite.Goodsstart;
                }
                
                //WriteInfoToConveyor(cs, converywrite);
                WriteInfoToConv(cs, converywrite);
            }
            catch (Exception ex)
            {
                LogMessageHelper.RecordLogMessage(ex);
            }
        }
        /// 
        /// 输送线无扫码执行任务
        /// 
        /// 扫码输送线
        /// 扫码异常退出口
        /// 目标地址是否当前输送线
        /// PLC索引
        private void Conv_NotScannExeTask(string convNo, string exitNo, bool endPosIsCurConv = false, int plcindex = 0)
        {
            try
            {
                var plc = Current.PlcSet.FirstOrDefault(v => v.PLC_NAME == PlcName);
                var conveyor = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == convNo);
                var cs = conveyor.EquSignal_Conv;
                if (cs.DB523_Fault) return;
                if (!cs.DB521_Request) return;
                var task = Current.TaskSet.FirstOrDefault(v => v.TASK_POSIDFROM == convNo && v.TASK_POSIDCUR == convNo && v.TASK_POSIDNEXT == convNo && v.TASK_WKSTATUS <= 1);
                if (task == null)
                {
                    throw new Exception(string.Format("输送线[{0}]有请求未查询到任务信息", convNo));
                }
                var converywrite = new WCSWriteToConveyorSignal();
                converywrite.Plc = plc.PlcInstanceSet[plcindex];//plc.Plc;
                converywrite.DBName = plc.WriteDBName;
                converywrite.ConveyorNo = convNo;
                converywrite.WriteStartAddress = cs.EquDbInfo_ReadWrite.DBReadIndox;
                converywrite.Tasknum = task.TASK_NO;
                converywrite.Goodscode = 0;
                converywrite.Goodstype = 0;
                converywrite.Goodssize = 0;
                converywrite.Goodsstart = Convert.ToInt32(convNo);
                if (endPosIsCurConv)
                {
                    converywrite.Goodsend = converywrite.Goodsstart;
                }
                else
                {
                    //if (task.TASK_POSIDTO == srm)
                    //{
                    //    ThreadHelper.TaskThread(BaseWorkflow.AssignSrm, task, 2000);
                    //    return;
                    //}
                    var routeSet = EquRouteHelper.QueryRoute(convNo, task.TASK_POSIDTO);
                    var routes = routeSet.Where(v => v.ROUTE_STARTPOS == convNo).ToList();
                    if (routes.Count == 1)
                    {
                        converywrite.Goodsend = Convert.ToInt32(routes[0].ROUTE_SONPOS);
                    }
                    else
                    {
                        converywrite.Goodsend = ConveyorWriteTaskExecuteToMoreAddress(convNo, task, routes);
                    }
                }
                WriteInfoToConv(cs, converywrite);
            }
            catch (Exception ex)
            {
                LogMessageHelper.RecordLogMessage(ex);
            }
        }
        /// 
        /// 堆垛机出口输送线任务执行(任务目标地址的下个地址只支持单一地址)
        /// 
        private void SrmOutConvExeTask(string plcName, string convNo, bool endPosIsCurConv = false)
        {
            try
            {
                var plc = Current.PlcSet.FirstOrDefault(v => v.PLC_NAME == plcName);
                var conveyor = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == convNo);
                var cs = conveyor.EquSignal_Conv;
                if (!cs.DB521_Request) return;
                if (cs.DB523_Fault) return;
                var taskSet = Current.TaskSet.Where(v => v.TASK_POSIDNEXT == convNo).ToList();
                var task = taskSet.SingleOrDefault(v => v.TASK_WKSTATUS == (int)WkStatus.堆垛机完成);
                if (task == null)
                {
                    throw new Exception(string.Format("堆垛机出口输送线[{0}]存在请求信号,但没查询到任务信息。", convNo));
                }
                var converywrite = new WCSWriteToConveyorSignal();
                converywrite.Plc = plc.Plc;
                converywrite.DBName = plc.WriteDBName;
                converywrite.ConveyorNo = convNo;
                converywrite.WriteStartAddress = cs.EquDbInfo_ReadWrite.DBReadIndox;
                converywrite.Tasknum = task.TASK_NO;
                converywrite.Goodscode = 0;
                converywrite.Goodstype = 0;
                converywrite.Goodssize = 0;
                converywrite.Goodsstart = Convert.ToInt32(convNo);
                if (endPosIsCurConv)
                {
                    converywrite.Goodsend = converywrite.Goodsstart;
                }
                else
                {
                    var routeSet = EquRouteHelper.QueryRoute(convNo, task.TASK_POSIDTO);
                    var routes = routeSet.Where(v => v.ROUTE_STARTPOS == convNo).ToList();
                    if (routes.Count == 1)
                    {
                        converywrite.Goodsend = Convert.ToInt32(routes[0].ROUTE_SONPOS);
                    }
                    else
                    {
                        throw new Exception(string.Format("输送线[{0}]任务[{1}]请求该函数不支持多个分支输送地址,请编写扩展函数。", convNo, task.TASK_NO));
                    }
                }
                //WriteInfoToConveyor(cs, converywrite);
                WriteInfoToConv(cs, converywrite);
            }
            catch (Exception ex)
            {
                LogMessageHelper.RecordLogMessage(ex);
            }
        }
        public override int ConveyorWriteTaskExecuteToMoreAddress(string convNo, WCS_TASK task, List routes)
        {
            int goodsend = 0;
            if (convNo == Conv_1013 || convNo == Conv_1009)
            {
                if (task.TASK_EndTunnelNum == "1" && task.TASK_SRMNO == "srm01")
                {
                    goodsend = 1027;
                }
                else if (task.TASK_EndTunnelNum == "2" && task.TASK_SRMNO == "srm01")
                {
                    goodsend = 1026;
                }
                else
                {
                    throw new Exception(string.Format("任务[{0}]堆垛机编号[{1}]目标巷道[{2}]不正确。", task.TASK_NO, task.TASK_SRMNO, task.TASK_EndTunnelNum));
                }
            }
            else if (convNo == Conv_1023)
            {
                BaseWorkflow.AssignSrm(task);
                if (task.TASK_EndTunnelNum == "1")
                {
                    goodsend = 1027;
                }
                else if (task.TASK_EndTunnelNum == "2")
                {
                    goodsend = 1026;
                }
                else
                {
                    throw new Exception(string.Format("任务[{0}]分配巷道失败。", task.TASK_NO));
                }
            }
            else
            {
                throw new Exception(string.Format("该函数不支持多个分支输送地址,请编写扩展接口。"));
            }
            return goodsend;
        }
        #endregion;
    }
}