using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.OscarClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WCS.BLL.Config;
using WCS.BLL.DbModels;
using WCS.BLL.HardWare;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model.ApiModel.InOutRecord;
using WCS.Model.WebSocketModel;

namespace WCS.BLL.Manager
{
    /// <summary>
    /// 报警信息
    /// </summary>
    public static class WarningManager
    {
        public static object flag = new object();
        public static void StartWarningMessageThread()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        var noReceivedWarningMessage = Warnings.Where(t => t.ClientIsReceived == false && t.LastSendTime < DateTime.Now.AddSeconds(-5))
                                                               .ToList();
                        foreach (var warning in noReceivedWarningMessage)
                        {
                            WebSoceketManager.TrySendMessage(warning.ClientIp, JsonConvert.SerializeObject(warning));
                            warning.LastSendTime = DateTime.Now;
                        }
                    }
                    catch (Exception ex)
                    {

                    }
                    Thread.Sleep(5000);
                }
            });
        }
        public static List<WebSocketMessageModel> Warnings { get; set; } = new List<WebSocketMessageModel>();
        public static void SendWarning(WebSocketMessageModel warning)
        {
            lock (flag)
            {
                Warnings.Add(warning);
                //发送WebSocket记录
                Logs.Write(JsonConvert.SerializeObject(warning), LogsType.WebSocket);

                WebSoceketManager.TrySendMessage(warning.ClientIp, JsonConvert.SerializeObject(warning));
                warning.LastSendTime = DateTime.Now;
            }
        }

        public static void ClearWarning(WebSocketMessageModel warning, SolveTypeEnum solveType)
        {
            try
            {
                var shelfIsWarning = true;
                var warningInManager = Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault();
                if (warningInManager != null)
                {
                    if (solveType == SolveTypeEnum.处理)
                    {
                        switch (warningInManager.WarningType)
                        {
                            case WarningTypeEnum.入库自检丢失:
                                SolveLoss(warningInManager);
                                break;
                            case WarningTypeEnum.出库自检丢失:
                                SolveLoss(warningInManager);
                                break;
                            case WarningTypeEnum.自检丢失:
                                SolveLoss(warningInManager);
                                break;
                        }
                    }
                    else if (solveType == SolveTypeEnum.屏蔽库位)
                    {
                        switch (warningInManager.WarningType)
                        {
                            case WarningTypeEnum.出库自检未扫描上架:
                                DisableNoScan(warningInManager);
                                break;
                            case WarningTypeEnum.入库自检未扫描上架:
                                DisableNoScan(warningInManager);
                                break;
                            case WarningTypeEnum.自检未扫描上架:
                                DisableNoScan(warningInManager);
                                break;
                        }
                    }
                    else if (solveType == SolveTypeEnum.忽略)
                    {
                        //不发指令了
                    }

                    //消除报警缓存信息
                    lock (flag)
                    {
                        Warnings.Remove(warningInManager);
                    }
                }

                //货架是否还存在报警信息
                shelfIsWarning = Warnings.Where(t => t.ShelfId == warning.ShelfId)
                                             .Where(t => t.IsWarning)
                                             .Any();
                //对应货架如果不存在报警信息了 指示灯回到对应的状态
                Logs.Write($"shelfIsWarning{shelfIsWarning}", LogsType.WebSocket);
                if (!shelfIsWarning)
                {
                    Logs.Write("货架不存在报警信息", LogsType.WebSocket);
                    var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == warning.ShelfId)
                                        .FirstOrDefault();
                    if (shelf != null)
                    {
                        try
                        {
                            Logs.Write("smartShelf?.ClearWarning();", LogsType.WebSocket);
                            var smartShelf = shelf as SmartShelf;
                            smartShelf?.ClearWarning();
                            smartShelf.IsWarning = false;
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                }

                if (warning.WarningType == WarningTypeEnum.入库中未扫描上架 ||
                    warning.WarningType == WarningTypeEnum.入库中异常取出 ||
                    warning.WarningType == WarningTypeEnum.出库中丢失 ||
                    warning.WarningType == WarningTypeEnum.出库中未扫描上架)
                {
                    return;
                }

                #region 重新发指令进入对应模式
                Logs.Write($"GoInRightMode", LogsType.WebSocket);
                GoInRightMode(warning);
                #endregion

            }
            catch (Exception e)
            {
                Logs.Write($"消除报警信息失败:发生异常" + e.Message);
            }
        }

        public static void RemoveMessage(WebSocketMessageModel warning)
        {
            var warningInManager = Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault();
            lock (flag)
            {
                Warnings.Remove(warningInManager);
            }
        }


        #region 报警消除的处理
        /// <summary>
        /// 未扫描上架禁用库位
        /// </summary>
        /// <param name="warning"></param>
        public static void DisableNoScan(WebSocketMessageModel warning)
        {
            #region 【后台】未扫描上架库位的处理
            try
            {
                //获取库位  
                var storeInfo = DbHelp.db.Queryable<StoreInfo>()
                                         .Where(t => t.ShelfId == warning.ShelfId)
                                         .Where(t => t.Id == warning.StoreId)
                                         .First();
                if (storeInfo != null)
                {
                    storeInfo.CurrentMatSn = "禁用";
                    DbHelp.db.Updateable(storeInfo).ExecuteCommand();
                    if (LocalFile.Config.IsMx)
                    {
                        var DingDing = string.Empty;
                        MXBackgroundThread.SendDingDingMsg($"【智能货架】库位{storeInfo.StoreCode}被 {warning.SolvedUser} “未扫描上架弹窗”屏蔽，请及时调查或维保硬件！", new List<string> { "104379", "103595" }, ref DingDing);
                        Logs.Write($"【智能货架】库位{storeInfo.StoreCode}被 {warning.SolvedUser} “未扫描上架弹窗”屏蔽，请及时调查或维保硬件！");
                    }

                }
            }
            catch (Exception e)
            {
                DbHelp.db.RollbackTran();
            }

            #endregion
        }

        public static void SolveLoss(WebSocketMessageModel warning)
        {
            #region 【后台】丢失的数据处理
            try
            {
                //获取库位  
                var storeInfo = DbHelp.db.Queryable<StoreInfo>()
                                         .Where(t => t.ShelfId == warning.ShelfId)
                                         .Where(t => t.Id == warning.StoreId)
                                         .First();
                if (storeInfo != null)
                {
                    DbHelp.db.BeginTran();
                    //库位表字段清空
                    storeInfo.CurrentMatSn = string.Empty;
                    DbHelp.db.Updateable(storeInfo).ExecuteCommand();

                    //库存表记录删除、插入出入记录
                    var inventoryDetail = DbHelp.db.Queryable<InventoryDetail>().Where(t => t.StoreId == storeInfo.Id).First();
                    if (inventoryDetail != null)
                    {
                        var inOutRecord = new InOutRecord()
                        {
                            StoreCode = storeInfo.StoreCode,
                            StoreId = storeInfo.Id,
                            StoreInfo = storeInfo,

                            R = storeInfo.R,
                            C = storeInfo.C,
                            Wei = storeInfo.Wei,
                            BigShelfCode = storeInfo.BigShelfCode,
                            GroupName = storeInfo.GroupName,

                            MatSN = inventoryDetail.MatSN,
                            MatCode = inventoryDetail.MatCode,
                            MatName = inventoryDetail.MatName,
                            MatBatch = inventoryDetail.MatBatch,
                            MatQty = inventoryDetail.MatQty,
                            MatSpec = inventoryDetail.MatSpec,
                            MatCustomer = inventoryDetail.MatCustomer,
                            MatSupplier = inventoryDetail.MatSupplier,

                            Direction = DirectionEnum.丢失,
                            OperateUser = warning.SolvedUser,
                        };
                        DbHelp.db.Insertable(inOutRecord).ExecuteCommand();
                        DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand();

                        #region 如果是出库 删除正在出库缓存的数据
                        if (warning.WarningType == WarningTypeEnum.出库自检丢失)
                        {
                            Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失，用户点击【处理】，删除数据", LogsType.Outstore);
                            //清掉需要出库的缓存
                            var shelf = ShelfManager.Shelves
                                                    .Where(t => t.ShelfId == warning.ShelfId)
                                                    .FirstOrDefault();
                            if (shelf != null)
                            {
                                var smartShelf = shelf as SmartShelf;
                                if (smartShelf != null)
                                {
                                    //删除货架上缓存的那一条数据
                                    smartShelf.CurrentOutStoreMatSNs.RemoveAll(t => t == inventoryDetail.MatSN);
                                    Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失，已删除货架缓存，剩余物料为{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore);

                                    //删除模组上缓存的那一条数据
                                    var module = smartShelf.Modules.Where(t => t.ModuleId == warning.ModuleId).FirstOrDefault();
                                    if (module != null)
                                    {
                                        module.CurrentOutSns.RemoveAll(t => t == inventoryDetail.MatSN);
                                        Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失，已删除模组缓存，剩余物料为{string.Join(",", module.CurrentOutSns)}", LogsType.Outstore);
                                    }

                                    //删除已丢失的出库明细数据
                                    var outOrderMatDetail = DbHelp.db.Queryable<OutOrderMatDetail>()
                                        .Where(t => t.OrderId == smartShelf.CurrentOutOrder.Id)
                                        .Where(t => t.MatSN == inventoryDetail.MatSN && t.IsSended == false)
                                        .ToList();
                                    Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失，删除出库物料明细数据{outOrderMatDetail.Count}条！");
                                    DbHelp.db.Deleteable(outOrderMatDetail).ExecuteCommand();
                                }
                            }
                        }
                        #endregion
                    }
                    DbHelp.db.CommitTran();
                }
            }
            catch (Exception e)
            {
                DbHelp.db.RollbackTran();
            }

            #endregion
        }


        public static void GoInRightMode(WebSocketMessageModel warning)
        {
            try
            {
                //模组还存在其他异常 暂时不进入对应模式
                var moduleOtherError = WarningManager.Warnings.Where(t => t.ShelfId == warning.ShelfId && t.ModuleId == warning.ModuleId).Any();
                if (moduleOtherError)
                {
                    var guids = WarningManager.Warnings.Where(t => t.ShelfId == warning.ShelfId && t.ModuleId == warning.ModuleId).Select(t => t.Guid.ToString()).ToList();
                    Logs.Write($"模组还存在其他异常 暂时不进入对应模式.{string.Join("''", guids)}", LogsType.WebSocket);
                    return;
                }

                var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == warning.ShelfId)
                                                .FirstOrDefault();
                if (shelf != null)
                {
                    Logs.Write($"shelf != null", LogsType.WebSocket);
                    var smartShelf = shelf as SmartShelf;
                    if (smartShelf != null)
                    {
                        var module = smartShelf.Modules.Where(t => t.ModuleId == warning.ModuleId).FirstOrDefault();
                        if (module != null)
                        {
                            switch (smartShelf.CurrentMode)
                            {
                                case Mode.入库模式:
                                    module.GoInInstoreMode(smartShelf.TcpCleint);
                                    smartShelf.WarningLight.BlueLight(smartShelf.TcpCleint);
                                    break;
                                case Mode.出库模式:
                                    Logs.Write("smartShelf.GoInOutstoreByWebSocket", LogsType.WebSocket);
                                    smartShelf.GoInOutstoreByWebSocket(module.ModuleId);
                                    break;
                                case Mode.待机模式:
                                    module.Reset(smartShelf.TcpCleint);
                                    smartShelf.WarningLight.CloseLight(smartShelf.TcpCleint);
                                    break;
                                default: break;
                            }
                        }
                    }
                    else
                    {
                        Logs.Write($"smartShelf != null", LogsType.WebSocket);
                    }
                }
                else
                {
                    Logs.Write($"shelf == null", LogsType.WebSocket);
                }
            }
            catch (Exception e)
            {
                Logs.Write("重置模组状态异常" + e.Message);
            }
        }
        #endregion

    }
}
