using AduSkin.Controls.Metro;
using AduSkin.Controls;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualBasic;
using NVelocity.Util.Introspection;
using Prism.Events;
using SlnMesnac.Common;
using SlnMesnac.Config;
using SlnMesnac.Serilog;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.Event;
using SlnMesnac.WPF.ViewModel.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows.Documents;
using SlnMesnac.Business;
using static Microsoft.WindowsAPICodePack.Shell.PropertySystem.SystemProperties.System;
using System.Windows.Markup;

namespace SlnMesnac.WPF.ViewModel.Index
{
    [RegisterAsSingletonAttribute]
    public partial class IndexViewModel : BaseViewModel
    {
        public readonly SerilogHelper _logger;

        private readonly AppConfig _appConfig;

        private readonly StringChange _stringChange;

        private readonly IEventAggregator _eventAggregator;

        private readonly SerialBusiness _serialBusiness;

        public IndexViewModel(SerilogHelper logger,AppConfig appConfig,StringChange stringChange, IEventAggregator eventAggregator, SerialBusiness serialBusiness)
        {
            _logger = logger;
            _appConfig = appConfig;
            _stringChange = stringChange;
            _eventAggregator = eventAggregator;
            _serialBusiness = serialBusiness;

            _serialBusiness.OpenPort();

        }

        [ObservableProperty]
        private string firstBatchEpcBarcode = string.Empty;

        [ObservableProperty]
        private string secondBatchEpcBarcode = string.Empty;

        [ObservableProperty]
        private string thirdBatchEpcBarcode = string.Empty;

        [ObservableProperty]
        private string fourthBatchEpcBarcode = string.Empty;

        [ObservableProperty]
        private string fifthBatchEpcBarcode = string.Empty;

        [ObservableProperty]
        private string sixthBatchEpcBarcode = string.Empty;

        /// <summary>
        /// 加载产品信息
        /// </summary>
        /// <param name="deviceCode"></param>
        [RelayCommand]
        private void LoadProductInfo(string deviceCode)
        {
            string code = deviceCode as string;

            _eventAggregator.GetEvent<ProductCodeEvent>().Publish(code);

            var mainWindow = App.ServiceProvider.GetService<MainWindowViewModel>();
            mainWindow.ControlOnClick("ProductInfo");
        }

        [RelayCommand]
        private void ReadEpcCode(string deviceCode)
        {
            try
            {
                string configKey = string.Empty;
                if (deviceCode == "050-B" || deviceCode == "I68")
                {
                    configKey = "I68";
                }
                else
                {
                    configKey = deviceCode;
                }
                var rfidConfig = _appConfig.rfidConfig.Where(x => x.equipKey == configKey).FirstOrDefault();

                if (rfidConfig != null)
                {
                    var session = rfidConfig.session as TcpClient;

                    if (session != null)
                    {
                        var waitClinet = session.CreateWaitingClient(new WaitingOptions()
                        {
                            FilterFunc = response =>
                            {
                                return true;
                            }
                        });

                        byte[] buffer = null;

                        if (deviceCode == "I90" || deviceCode == "RFR-RFLY")
                        {
                            buffer = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x10, 0x00, 0x04 };
                        }

                        if (deviceCode == "050-B")  //站1
                        {
                            buffer = new byte[] { 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04 };
                        }

                        if (deviceCode == "I68")    //站2
                        {
                            buffer = new byte[] { 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x06, 0x00, 0x04 };
                        }

                        ResponsedData responsedData = waitClinet.SendThenResponse(buffer, 5000);

                        string str = _stringChange.bytesToHexStr(responsedData.Data, responsedData.Data.Length).Substring(18, 16);

                        SetEpcBarCode(deviceCode, str);

                        NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                        {
                            Title = "通知",
                            Content = $"{deviceCode}设备读取成功：{str}",
                            NotifiactionType = EnumPromptType.Success
                        });
                    }
                    else
                    {
                        NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                        {
                            Title = "通知",
                            Content = $"{deviceCode}设备未连接",
                            NotifiactionType = EnumPromptType.Warn
                        });
                    }
                }
                else
                {
                    NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                    {
                        Title = "通知",
                        Content = $"{deviceCode}设备未获取到配置信息",
                        NotifiactionType = EnumPromptType.Warn
                    });
                }
            }catch (Exception ex)
            {
                NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                {
                    Title = "通知",
                    Content = $"条码读取异常：{ex.Message}",
                    NotifiactionType = EnumPromptType.Error
                });
            }
        }

        [RelayCommand]
        private void WriteEpcCode(string deviceCode)
        {
            try
            {
                string configKey = string.Empty;
                if (deviceCode == "050-B" || deviceCode == "I68")
                {
                    configKey = "I68";
                }
                else
                {
                    configKey = deviceCode;
                }
                var rfidConfig = _appConfig.rfidConfig.Where(x => x.equipKey == configKey).FirstOrDefault();

                if (rfidConfig != null)
                {
                    var session = rfidConfig.session as TcpClient;

                    if (session != null)
                    {
                        var waitClinet = session.CreateWaitingClient(new WaitingOptions()
                        {
                            FilterFunc = response =>
                            {
                                return true;
                            }
                        });

                        byte[] buffer = null;

                        if (deviceCode == "I90" || deviceCode == "RFR-RFLY")
                        {
                            byte[] FixedPart = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x00, 0x10, 0x00, 0x04};

                            string epcBarCode = string.Empty;

                            if (deviceCode == "I90")
                            {
                                epcBarCode = FirstBatchEpcBarcode;
                            }
                            else
                            {
                                epcBarCode = SecondBatchEpcBarcode;
                            }

                            int inputByteLength = epcBarCode.Length / 2;
                            byte[] fixedPartWithLength = new byte[FixedPart.Length + 1];
                            Array.Copy(FixedPart, fixedPartWithLength, FixedPart.Length);
                            fixedPartWithLength[fixedPartWithLength.Length - 1] = (byte)inputByteLength;

                            byte[] inputBytes = Enumerable.Range(0, epcBarCode.Length)
                                .Where(x => x % 2 == 0)
                                .Select(x => Convert.ToByte(FirstBatchEpcBarcode.Substring(x, 2), 16))
                                .ToArray();
                            buffer = new byte[fixedPartWithLength.Length + inputBytes.Length];

                            Array.Copy(fixedPartWithLength, buffer, fixedPartWithLength.Length);

                            Array.Copy(inputBytes, 0, buffer, fixedPartWithLength.Length, inputBytes.Length);
                        }

                        if (deviceCode == "050-B")
                        {
                            buffer = new byte[] { 0x00, 0x82, 0x00, 0x00, 0x00, 0x1F, 0x01, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };

                            byte[] inputBytes = Enumerable.Range(0, FourthBatchEpcBarcode.Length)
                                .Where(x => x % 2 == 0)
                                .Select(x => Convert.ToByte(FourthBatchEpcBarcode.Substring(x, 2), 16))
                                .ToArray();
                            buffer = buffer.Concat(inputBytes).ToArray();
                        }

                        if (deviceCode == "I68")
                        {
                            buffer = new byte[] { 0x00, 0x89, 0x00, 0x00, 0x00, 0x27, 0x01, 0x10, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
                            
                            byte[] inputBytes = Enumerable.Range(0, ThirdBatchEpcBarcode.Length)
                                .Where(x => x % 2 == 0)
                                .Select(x => Convert.ToByte(ThirdBatchEpcBarcode.Substring(x, 2), 16))
                                .ToArray();
                            buffer = buffer.Concat(inputBytes).ToArray();

                        }



                        ResponsedData responsedData = waitClinet.SendThenResponse(buffer, 5000);

                        //string str = _stringChange.bytesToHexStr(responsedData.Data, responsedData.Data.Length).Substring(18, 16);

                        //SetEpcBarCode(deviceCode, str);

                        NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                        {
                            Title = "通知",
                            Content = $"{deviceCode}设备写入成功",
                            NotifiactionType = EnumPromptType.Success
                        });
                    }
                    else
                    {
                        NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                        {
                            Title = "通知",
                            Content = $"{deviceCode}设备未连接",
                            NotifiactionType = EnumPromptType.Warn
                        });
                    }
                }
                else
                {
                    NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                    {
                        Title = "通知",
                        Content = $"{deviceCode}设备未获取到配置信息",
                        NotifiactionType = EnumPromptType.Warn
                    });
                }
            }
            catch (Exception ex)
            {
                NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                {
                    Title = "通知",
                    Content = $"{deviceCode}设备写入异常：{ex.Message}",
                    NotifiactionType = EnumPromptType.Error
                });
            }
        }

        [RelayCommand]
        private void ReadEpcCodeByRtu(string deviceCode)
        {
            try
            {

                byte[] buffer = null;

                if (deviceCode == "I40") //站1
                {
                    buffer = new byte[] { 0x01, 0x03, 0x00, 0x10, 0x00, 0x04, 0x45, 0xCC, };
                }

                if (deviceCode == "RFR-050")    //站2
                {
                    buffer = new byte[] { 0x02, 0x03, 0x00, 0x10, 0x00, 0x04, 0x45, 0xFF, };
                }

                byte[] response = _serialBusiness.SendDataAndWaitForResponse(buffer);

                if (response.Length == 13)
                {
                    string str = _stringChange.bytesToHexStr(response, response.Length).Substring(6, 16);

                    SetEpcBarCode(deviceCode, str);

                    NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                    {
                        Title = "通知",
                        Content = $"{deviceCode}设备读取成功：{str}",
                        NotifiactionType = EnumPromptType.Success
                    });
                }
                else
                {
                    SetEpcBarCode(deviceCode, string.Empty);
                    NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                    {
                        Title = "通知",
                        Content = $"{deviceCode}设备读取失败",
                        NotifiactionType = EnumPromptType.Success
                    });
                }


            }
            catch (Exception ex)
            {
                NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                {
                    Title = "通知",
                    Content = $"条码读取异常：{ex.Message}",
                    NotifiactionType = EnumPromptType.Error
                });
            }
        }

        [RelayCommand]
        private void WriteEpcCodeByRtu(string deviceCode)
        {
            try
            {
                //站1
                //01 10 00 10 00 04 08 11 11 22 22 11 11 22 22 85 41 
                //01 10 00 10 00 04 08 11 11 11 11 11 11 11 11 85 41
                //站2        02 10 00 10 00 04 08 11 11 11 11 11 11 11 11 93 62
                byte[] buffer = null;
                if (deviceCode == "I40")
                {
                    buffer = new byte[] { 0x01, 0x10, 0x00, 0x10, 0x00, 0x04, 0x08, };
                    byte[] inputBytes = Enumerable.Range(0, SixthBatchEpcBarcode.Length)
                        .Where(x => x % 2 == 0)
                        .Select(x => Convert.ToByte(SixthBatchEpcBarcode.Substring(x, 2), 16))
                        .ToArray();
                    buffer = buffer.Concat(inputBytes).ToArray();
                    byte[] crcBytes = CRCCalc(buffer);

                    buffer = buffer.Concat(crcBytes).ToArray();
                }

                if (deviceCode == "RFR-050")
                {
                    buffer = new byte[] { 0x02, 0x10, 0x00, 0x10, 0x00, 0x04, 0x08, };
                    byte[] inputBytes = Enumerable.Range(0, FifthBatchEpcBarcode.Length)
                        .Where(x => x % 2 == 0)
                        .Select(x => Convert.ToByte(FifthBatchEpcBarcode.Substring(x, 2), 16))
                        .ToArray();
                    buffer = buffer.Concat(inputBytes).ToArray();
                    byte[] crcBytes = CRCCalc(buffer);

                    buffer = buffer.Concat(crcBytes).ToArray();

                }

                _logger.Info($"{deviceCode}发送:{_stringChange.bytesToHexStr(buffer, buffer.Length)}");
                var responsedData = _serialBusiness.SendDataAndWaitForResponse(buffer);

                NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                {
                    Title = "通知",
                    Content = $"{deviceCode}设备写入成功",
                    NotifiactionType = EnumPromptType.Success
                });
            }
            catch (Exception ex)
            {
                NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
                {
                    Title = "通知",
                    Content = $"{deviceCode}设备写入异常：{ex.Message}",
                    NotifiactionType = EnumPromptType.Error
                });
            }
        }

        public static byte[] CRCCalc(byte[] data)
        {
            int crc = 0xffff;
            for (int i = 0; i < data.Length; i++)
            {
                crc ^= data[i];
                for (int j = 0; j < 8; j++)
                {
                    int temp = crc & 1;
                    crc >>= 1;
                    crc &= 0x7fff;
                    if (temp == 1)
                    {
                        crc ^= 0xa001;
                    }
                    crc &= 0xffff;
                }
            }
            byte[] crc16 = new byte[2];
            crc16[1] = (byte)((crc >> 8) & 0xff);
            crc16[0] = (byte)(crc & 0xff);
            return crc16;
        }

        private void SetEpcBarCode(string deviceCode,string str)
        {
            switch (deviceCode)
            {
                case "I90":
                    FirstBatchEpcBarcode = str;
                    break;
                case "RFR-RFLY":
                    SecondBatchEpcBarcode = str;
                    break;
                case "I68":
                    ThirdBatchEpcBarcode = str;
                    break;
                case "050-B":
                    FourthBatchEpcBarcode = str;
                    break;
                case "RFR-050":
                    FifthBatchEpcBarcode = str;
                    break;
                case "I40":
                    SixthBatchEpcBarcode= str;
                    break;
                default:
                    break;
            }
        }
    }
}