using Pms.DataLibrary.Order;
using ProjectManagementSystem.Common.Config;
using ProjectManagementSystem.Common.Core;
using ProjectManagementSystem.Common.Extenions;
using ProjectManagementSystem.Common.WebApi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectManagementSystem.TaskBookEvent
{
    /// <summary>
    /// IO交互行为码，使用类似PLC地址的方式，输出Y1-Y8，输入X1-X8
    /// </summary>
    public class TaskBookBehavior_IOAddress : TaskBookBehavior_PLC<bool>
    {
        //private static readonly object locker = new object();

        public TaskBookBehavior_IOAddress(int behavior) : base(behavior)
        {
        }

        protected override bool Interaction(int flag, string[] addrArray, string valueArray, TaskData taskDetailInfo, StepData taskStepInfo, bool logicBit)
        {
            if (addrArray.Length <= 0) return true;

            var routeConfig = ExcelConfig.Instance.GetRouteConfig(taskStepInfo.WareHouseID);
            if (routeConfig == null)
            {
                Log(taskDetailInfo, taskStepInfo, "查找库位配置信息失败");
                return false;
            }

            if (routeConfig.IOTransID <= 0)
            {
                Log(taskDetailInfo, taskStepInfo, "获取库位对接盒ID失败");
                return false;
            }

            int id = routeConfig.IOTransID;
            if (!DeviceControl.Instance.Communication.InfoIODictionary.ContainsKey(id))
            {
                Log(taskDetailInfo, taskStepInfo, $"获取库位对接盒{id}，没有此盒子数据，检查盒子是否连接网络");
                return false;
            }

            var infoIO = DeviceControl.Instance.Communication.InfoIODictionary[id];
            if (!infoIO.DataValid)
            {
                Log(taskDetailInfo, taskStepInfo, $"获取库位对接盒{id}，盒子已掉线！");
                return false;
            }

            //构造地址数组
            string[] realAddrArray = new string[addrArray.Length];
            for (int i = 0; i < addrArray.Length; i++)
            {
                string addrDesc = addrArray[i];
                string plcAddr = taskStepInfo.WareHouseID.GetPlcTaskAddr(addrDesc);
                if (string.IsNullOrEmpty(plcAddr))
                {
                    Log(taskDetailInfo, taskStepInfo, $"查找地址失败：“{addrDesc}”");
                    return false;
                }

                realAddrArray[i] = plcAddr;
            }

            //构造地址值数组
            var tempRealValues = valueArray.ToValueArray<bool>();
            var realValues = new bool[realAddrArray.Length];
            for (int i = 0; i < realValues.Length; i++)
            {
                realValues[i] = GetArrayValue(tempRealValues, i);
                //根据逻辑位来确定写的值
                if (PlcBehavior.LogicBitTrue > 0
                    && logicBit == false)
                {
                    realValues[i] = false;
                }
            }

            if (flag == 0)
            {
                //写入
                var result = DeviceControl.Instance.SetOutputIO_ThenCheck(id, realAddrArray, realValues, out string setMsg);
                if(!result)
                {
                    Log(taskDetailInfo, taskStepInfo, setMsg);
                    return result;
                }

                //DeviceControl.Instance.SetOutputIO(id, realAddrArray, realValues);
                //System.Threading.Thread.Sleep(100);

                //for (int i = 0; i < realAddrArray.Length; i++)
                //{
                //    string plcAddr = realAddrArray[i];
                //    bool plcValue = realValues[i];

                //    bool result = DeviceControl.Instance.GetOutputIO(id, realAddrArray[i]);
                //    if (result != plcValue)
                //    {
                //        Log(taskDetailInfo, taskStepInfo, $"写入失败({plcAddr}写入{plcValue})");
                //        return false;
                //    }
                //}
            }
            else
            {
                //读取
                var result = DeviceControl.Instance.CheckInputIO(id, realAddrArray, realValues, out string setMsg);
                if (!result)
                {
                    Log(taskDetailInfo, taskStepInfo, setMsg);
                    return result;
                }

                //for (int i = 0; i < realAddrArray.Length; i++)
                //{
                //    string plcAddr = realAddrArray[i];
                //    bool plcValue = realValues[i];

                //    bool result2 = DeviceControl.Instance.GetInputIO(id, realAddrArray[i]);
                //    if (result2 != plcValue)
                //    {
                //        Log(taskDetailInfo, taskStepInfo, $"等待信号({plcAddr}={plcValue})");
                //        return false;
                //    }
                //}
            }



            return true;
        }

        private bool GetArrayValue(bool[] array, int index)
        {
            if (array.Length == 0) return false;
            return array.Length > index ? array[index] : array[array.Length - 1];
        }
    }
}
