using HandyControl.Controls;
using Newtonsoft.Json;
using Ping9719.WpfEx;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using TouchSocket.Core;
using TouchSocket.Http.WebSockets;
using TouchSocket.Sockets;
using WCS.Model.WebSocketModel;
using 智慧物流软件系统.Views.Controls;

namespace 智慧物流软件系统
{
    public static class WebSocket
    {
        public static WebSocketClient client = null;
        public static void InitWebSocket()
        {
            client = new WebSocketClient();
            client.Setup(new TouchSocketConfig()
                .SetRemoteIPHost(LocalFile.Config.WebSocketUrl)
                .ConfigureContainer(a =>
                {
                    a.AddConsoleLogger();
                })
                   .ConfigurePlugins(a =>
                   {
                       a.Add<WebSocketClientPlugin>();
                       //配置心跳
                       //a.UseWebSocketHeartbeat()//使用心跳插件
                       // .SetTick(TimeSpan.FromSeconds(5));//每5秒ping一次。
                       //配置断线重连
                       a.UseReconnection(-1, true, 1000);//-1表示一直重连
                   }));
            client.Connect();
            //自定义实现心跳和重连
            Task.Run(async () =>
            {
                while (true)
                {
                    await Task.Delay(4000);
                    try
                    {
                        WebSocket.client.Ping();
                        await Task.Delay(200);
                        if (WebSocket.client.LastReceivedTime < DateTime.Now.AddSeconds(-10))
                        {
                            WebSocket.client.TryConnect();
                        }
                    }
                    catch (Exception ex)
                    {

                    }
                }
            });
        }
    }
    public class WebSocketClientPlugin : PluginBase, IWebSocketReceivedPlugin
    {
        private readonly ILog m_logger;

        public WebSocketClientPlugin(ILog logger)
        {
            this.m_logger = logger;
        }
        public async Task OnWebSocketReceived(IWebSocket client, WSDataFrameEventArgs e)
        {
            switch (e.DataFrame.Opcode)
            {
                case WSDataType.Cont:
                    m_logger.Info($"收到中间数据，长度为：{e.DataFrame.PayloadLength}");
                    return;

                case WSDataType.Text:
                    m_logger.Info(e.DataFrame.ToText());
                    if (!client.Client.IsClient)
                    {
                        client.Send("已收到");
                    }
                    //返回的报警信息 出入库盘点等日志信息
                    else
                    {
                        try
                        {
                            var message = e.DataFrame.ToText();
                            var warning = JsonConvert.DeserializeObject<WebSocketMessageModel>(message);
                            if (warning != null)
                            {
                                //通知类的
                                if (warning.IsWarning == false)
                                {
                                    switch (warning.WarningType)
                                    {
                                        case WarningTypeEnum.通知刷新出库:
                                            if (LocalFile.Config.IsMx)
                                                ;
                                            //MXOutInventoryView.viewModel.RefreshDataGridItemSource();
                                            else
                                                OutVentoryView.viewModel.RefreshDataGridItemSource();
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.通知刷新出库单列表:
                                            if (LocalFile.Config.IsMx)
                                                ;
                                            //MXOutInventoryView.viewModel.RefreshOutOrderList(MXOutInventoryView.viewModel.SelectedOutOrderNumber);
                                            else
                                                ;
                                                //OutVentoryView.viewModel.RefreshOutOrderList(MXOutInventoryView.viewModel.SelectedOutOrderNumber);
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.通知刷新盘点:
                                            StockTakingView.viewModel.RefreshDataGridItemSource();
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.通知刷新盟讯盘点:
                                            ;
                                            //MXPDView.viewModel.RefreshDataGridItemSource();
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.恢复正常:
                                            var SolvedGuids = warning.SolvedGuids;
                                            SolvedGuids.ForEach(guid =>
                                            {
                                                WarningManager.RemoveWarning(guid);
                                            });
                                            TextBoxLog.AddLog(warning.WarningMessage, "InstoreLog", DateTime.Now);
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.通知前台结束入库:
                                            var scanner = ScannerManager.Scanners.Where(t => t.IsInstoreMode && t.ShelfCode == warning.ShelfCode && t.IsInstoreModeTime < warning.CreateTime)
                                                                                 .FirstOrDefault();
                                            if (scanner != null)
                                            {
                                                scanner.IsInstoreMode = false;
                                                scanner.ShelfCode = string.Empty;
                                                scanner.ModulesStr = string.Empty;

                                                scanner.ScannerDisplayControl.RefreshValues(string.Empty, string.Empty, string.Empty);
                                            }
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.通知自检进度:
                                            TextBoxLog.AddLog(warning.WarningMessage, "selfCheck", warning.CreateTime);
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        case WarningTypeEnum.自检未响应:
                                            TextBoxLog.AddLog(warning.WarningMessage, "selfCheck", warning.CreateTime);
                                            client.Send(e.DataFrame.ToText());
                                            break;
                                        default: break;
                                    }
                                    return;
                                }
                                else
                                {
                                    Application.Current.Dispatcher.Invoke(() =>
                                    {
                                        WarningManager.AddWarning(warning);
                                        TextBoxLog.AddLog(warning.WarningMessage, "InstoreLog", DateTime.Now);
                                    });
                                }


                            }
                            client.Send(e.DataFrame.ToText());
                        }
                        catch
                        {
                        }

                    }
                    return;

                case WSDataType.Binary:
                    if (e.DataFrame.FIN)
                    {
                        m_logger.Info($"收到二进制数据，长度为：{e.DataFrame.PayloadLength}");
                    }
                    else
                    {
                        m_logger.Info($"收到未结束的二进制数据，长度为：{e.DataFrame.PayloadLength}");
                    }
                    return;

                case WSDataType.Close:
                    {
                        m_logger.Info("远程请求断开");
                        client.Close("断开");
                    }
                    return;

                case WSDataType.Ping:
                    client.Pong();
                    break;
                case WSDataType.Pong:
                    break;

                default:
                    break;
            }

            await e.InvokeNext();
        }
    }
}
