using DbCommon.BusinessCore.BaseCore;
using DbCommon.Enties.DbModels;
using HslCommunication.Core;
using HslCommunication.Profinet.Siemens;
using ProjectManagementSystem.Common.Config;
using ProjectManagementSystem.Common.Core;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectManagementSystem.DispatchPack.Entity
{
    public class EntityBase
    {
        public int Index { get; set; }

        public LineInfo LineInfo { get; set; }
        public PackEngine PackEngine { get; set; }
        public List<StationInfo> StationInfoList { get; set; }

        public virtual void Init()
        {
            StationInfoList = new List<StationInfo>();

            bool hasPLC地址 = LineInfo.DetailTable.Columns.Contains("IP地址");
            bool has放行DB = LineInfo.DetailTable.Columns.Contains("放行DB");
            bool has行驶状态DB = LineInfo.DetailTable.Columns.Contains("行驶状态DB");
            bool has故障DB = LineInfo.DetailTable.Columns.Contains("故障DB");
            bool hasAGVDB = LineInfo.DetailTable.Columns.Contains("AGVDB");


            for (int i = 0; i < LineInfo.DetailTable.Rows.Count; i++)
            {
                var row = LineInfo.DetailTable.Rows[i];
                StationInfo info = new StationInfo();

                string markString = row["工位地标"].ToString();
                if (string.IsNullOrEmpty(markString))
                {
                    break;
                }

                info.LineName = LineInfo.Name;
                info.SerialNumber = i;
                info.Id = int.Parse(row["工位地标"].ToString());
                info.Name = row["工位名称"].ToString();
                info.Mark = int.Parse(row["工位地标"].ToString());

                string routeString = row["放行路线"].ToString();
                info.ReleaseRoute = string.IsNullOrEmpty(routeString) ? 0 : int.Parse(routeString);

                PackEngine.StationInfoDict.AddOrUpdate(info.Mark, info, (key, value) => info);
                StationInfoList.Add(info);
                
                info.PlcIPAddress = hasPLC地址 ? row["IP地址"].ToString().Trim() : null;
                info.PlcRelease = has放行DB ? row["放行DB"].ToString().Trim() : null;
                info.PlcAgvStatus = has行驶状态DB ? row["行驶状态DB"].ToString().Trim() : null;
                info.PlcAgvFalut = has故障DB ? row["故障DB"].ToString().Trim() : null;
                info.PlcAgvId = hasAGVDB ? row["AGVDB"].ToString().Trim() : null;


                string plcIpAddr = info.PlcIPAddress;
                if (!string.IsNullOrEmpty(plcIpAddr)
                    && !PackEngine.PlcDict.ContainsKey(plcIpAddr))
                {
                    var plc = new HslCommunication.Profinet.Siemens.SiemensS7Net(SiemensPLCS.S1200, plcIpAddr);
                    plc.ConnectTimeOut = 500;
                    plc.ReceiveTimeOut = 500;
                    plc.SetPersistentConnection();

                    PackEngine.PlcDict.AddOrUpdate(plcIpAddr, plc, (key, value) => plc);
                }
            }
        }

        private void StopPoint()
        {
            var infoAgv = DeviceControl.Instance.Communication.InfoAgvDictionary.Values.FirstOrDefault(d => d.Mark == LineInfo.Mark && d.InStation);
            if(infoAgv != null)
            {
                var station = StationInfoList.OrderBy(d => d.Priority).FirstOrDefault(d => d.Status == LocationStatus.Empty);
                if(station != null)
                {
                    DeviceControl.Instance.ReleaseAgvOnStop(LineInfo.Mark, station.ReleaseRoute, infoAgv.AgvId);
                }
            }
        }

        private void PLC()
        {
            for (int i = 0; i < StationInfoList.Count; i++)
            {
                var info = StationInfoList[i];

                if (string.IsNullOrEmpty(info.PlcIPAddress)
                    || !PackEngine.PlcDict.ContainsKey(info.PlcIPAddress))
                {
                    continue;
                }

                var plc = PackEngine.PlcDict[info.PlcIPAddress];
                var result = plc.Read(info.PlcRelease, 1);
                if (!result.IsSuccess)
                {
                    continue;
                }

                if (info.Online)
                {
                    byte plcRelease = result.Content[0];
                    switch (plcRelease)
                    {
                        case (byte)DBControlValues.OKRelease:
                            if (info.HasCar)
                            {
                                DeviceControl.Instance.ReleaseAgvOnStop(info.Mark, info.ReleaseRoute, info.AgvId);
                            }
                            break;
                        case (byte)DBControlValues.NGRelease:
                            if (info.HasCar)
                            {
                                DeviceControl.Instance.ReleaseAgvOnStop(info.Mark, info.ReleaseNGRoute, info.AgvId);
                            }
                            break;
                        case (byte)DBControlValues.StopImmediate:
                            if (!info.HasCar)
                            {
                                DeviceControl.Instance.RailAgv_StopButton(info.AgvId);
                            }
                            break;
                        case (byte)DBControlValues.StopRelease:
                            if (!info.HasCar)
                            {
                                DeviceControl.Instance.RailAgv_StartButton(info.AgvId);
                            }
                            break;
                        default:
                            break;
                    }
                }


                byte agvId = StationInfoTools.GetDBAgvId(info);
                plc.Write(info.PlcAgvId, agvId);

                byte agvStatus = StationInfoTools.GetDBRunValues(info);
                plc.Write(info.PlcAgvStatus, agvStatus);

                byte agvFalut = StationInfoTools.GetDBAgvFalut(info);
                plc.Write(info.PlcAgvFalut, agvFalut);
            }
        }

        private void MES()
        {
        }

        public virtual void CustomUpdate()
        {

            switch (LineInfo.CommunicationType)
            {
                case 1:
                    PLC();
                    break;
                case 2:
                    MES();
                    break;
                default:
                    break;
            }
        }


    }


}
