using Khd.Core.Domain.Dto.waring;
using Khd.Core.Domain.Models;
using Khd.Core.EntityFramework;
using Khd.Core.Library.Mapper;
using Khd.Core.Wcs.Global;
using Z.EntityFramework.Plus;

namespace Khd.Core.Wcs
{
    public class SystemData
    {
        public readonly static int maxTray = 10;

        private static long _serialNo { get; set; } = 1;

        private static object serialLock = new object();

        public static long GetSerialNo(DefaultDbContext dbContext)
        {
            lock (serialLock)
            {
                List<long?> list = dbContext.WcsTask.Select(t => t.serialNo).ToList();
                while (list.Contains(_serialNo))
                {
                    _serialNo++;
                    if (_serialNo > 9999)
                    {
                        _serialNo = 1;
                    }
                }
                return _serialNo;
            }
        }
        public static object outStockLock = new object();

        /// <summary>
        /// 出入库锁定浅库位
        /// </summary>
        /// <param name="wmsBaseLocation"></param>
        /// <param name="dbContext"></param>
        public static void LockOutLocation(WmsBaseLocation wmsBaseLocation, DefaultDbContext dbContext)
        {
            if (wmsBaseLocation.locDeep == 1)
            {
                WmsBaseLocation? wmsLocation = dbContext.WmsBaseLocation.Where(t => t.locDeep == 2 && t.locRow == wmsBaseLocation.locRow && t.locColumn == (wmsBaseLocation.locColumn % 2 == 0 ? wmsBaseLocation.locColumn - 1 : wmsBaseLocation.locColumn + 1)).FirstOrDefault();
                if (wmsLocation != null && wmsLocation.locationStatus == "1")
                {
                    wmsLocation.locationStatus = "2";
                    dbContext.Update(wmsLocation);
                }
            }
        }

        /// <summary>
        /// 出入库解锁浅库位
        /// </summary>
        /// <param name="wmsBaseLocation"></param>
        /// <param name="dbContext"></param>
        public static void UnLockOutLocation(WmsBaseLocation wmsBaseLocation, DefaultDbContext dbContext)
        {
            if (wmsBaseLocation.locDeep == 1)
            {
                WmsBaseLocation? wmsLocation = dbContext.WmsBaseLocation.Where(t => t.locDeep == 2 && t.locRow == wmsBaseLocation.locRow && t.locColumn == (wmsBaseLocation.locColumn % 2 == 0 ? wmsBaseLocation.locColumn - 1 : wmsBaseLocation.locColumn + 1)).FirstOrDefault();
                if (wmsLocation != null && wmsLocation.locationStatus != "3" && wmsLocation.locationStatus != "9")
                {
                    wmsLocation.locationStatus = "1";
                    dbContext.Update(wmsLocation);
                }
            }
        }

        /// <summary>
        /// 报警库位
        /// </summary>
        public static void AlarmLocation(WmsBaseLocation wmsBaseLocation, DefaultDbContext dbContext)
        {
            if (wmsBaseLocation.locDeep == 2)
            {
                WmsBaseLocation? wmsLocation = dbContext.WmsBaseLocation.Where(t => t.locDeep == 1 && t.locRow == wmsBaseLocation.locRow && t.locColumn == (wmsBaseLocation.locColumn % 2 == 0 ? wmsBaseLocation.locColumn - 1 : wmsBaseLocation.locColumn + 1)).FirstOrDefault();
                if (wmsLocation != null && wmsLocation.locationStatus != "3")
                {
                    wmsLocation.locationStatus = "8";
                    wmsLocation.ExceptionDesc = "外侧库位异常导致内测库位异常";
                    dbContext.Update(wmsLocation);
                }
            }
        }

        /// <summary>
        /// 解除报警库位
        /// </summary>
        public static void UnAlarmLocation(WmsBaseLocation wmsBaseLocation, DefaultDbContext dbContext)
        {
            if (wmsBaseLocation.locDeep == 2)
            {
                WmsBaseLocation? wmsLocation = dbContext.WmsBaseLocation.Where(t => t.locDeep == 1 && t.locRow == wmsBaseLocation.locRow && t.locColumn == (wmsBaseLocation.locColumn % 2 == 0 ? wmsBaseLocation.locColumn - 1 : wmsBaseLocation.locColumn + 1)).FirstOrDefault();
                if (wmsLocation != null && wmsLocation.locationStatus == "8")
                {
                    wmsLocation.locationStatus = "1";
                    dbContext.Update(wmsLocation);
                }
            }
        }

        public static void InsertWaringLog(DefaultDbContext dbContext, WaringType WaringType, string message = "")
        {
            try
            {
                var alarmRule = StaticData.DmsBaseAlarmRuleList.Where(t => t.AlarmRuleId == (long)WaringType).FirstOrDefault();
                if (alarmRule != null)
                {
                    var alarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.AlarmRuleId == (long)WaringType).FirstOrDefault();
                    if (alarmTime == null)
                    {
                        alarmTime = new DmsRecordAlarmTime()
                        {
                            AlarmId = StaticData.SnowId.NextId(),
                            AlarmRuleId = (long)WaringType,
                            DeviceId = alarmRule.DeviceId,
                            AlarmBeginTime = DateTime.Now,
                            ContinueTime = alarmRule.ContinueTime,
                            AlarmReason = alarmRule.AlarmReason,
                            HandleSuggest = alarmRule.HandleSuggest,
                            CreateBy = "WCS",
                            CreateTime = DateTime.Now,
                            AlarmData = message
                        };
                        var dmsRecordAlarmInfo = CoreMapper.Map<DmsRecordAlarmInfo>(alarmTime);
                        dmsRecordAlarmInfo.NoticeStatus = "0";
                        dmsRecordAlarmInfo.AlarmStatus = "0";
                        dbContext.Add(dmsRecordAlarmInfo);
                        dbContext.Add(alarmTime);
                        dbContext.SaveChanges();
                    }
                }
            }
            catch
            {

            }

        }


        public static void DeleteWaringLog(DefaultDbContext dbContext, WaringType WaringType)
        {
            try
            {
                var alarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.AlarmRuleId == (long)WaringType).FirstOrDefault();
                if (alarmTime != null)
                {
                    dbContext.DmsRecordAlarmTime.Where(t=>t.AlarmId==alarmTime.AlarmId).Delete();
                    dbContext.DmsRecordAlarmInfo.Where(t => t.AlarmId == alarmTime.AlarmId)
                        .Update(t => new DmsRecordAlarmInfo() { AlarmStatus = "2" });
                }
            }
            catch
            {
            }

        }

        public static void SendPlcLocation(WmsBaseLocation wmsBaseLocation)
        {
            Task.Run(() =>
            {
                try
                {
                    var locationPlcDto = StaticData.LocationToPlcList.Where(t => t.Id == wmsBaseLocation.locationId).FirstOrDefault();
                    if (locationPlcDto != null)
                    {
                        if (wmsBaseLocation != null && !string.IsNullOrEmpty(wmsBaseLocation.containerCode))
                        {
                            if (wmsBaseLocation.warehouseId == 512)
                            {
                                if (wmsBaseLocation.ContainerStatus == "1")
                                {
                                    StaticData.PlcDic[2].Write(locationPlcDto.Address, true);
                                }
                                else
                                {
                                    StaticData.PlcDic[2].Write(locationPlcDto.Address, false);
                                }
                            }
                            else
                            {
                                StaticData.PlcDic[2].Write(locationPlcDto.Address, true);
                            }
                        }
                        else
                        {
                            StaticData.PlcDic[2].Write(locationPlcDto.Address, false);
                        }
                    }
                }
                catch
                {

                }
            });

        }

        public readonly static object SecondTaskLock = new();
        public readonly static object ThirdTaskLock = new();
        public readonly static object FiveTaskLock = new();

    }
}
