using HandyControl.Controls;
using MiniExcelLibs;
using Ping9719.WpfEx.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media;
using SqlSugar;
using HandyControl.Data;
using System.Windows;
using Newtonsoft.Json.Linq;
using 智慧物流软件系统.Views.Controls;
using WCS.Model.ApiModel.User;
using 智慧物流软件系统.Api;
using WCS.Model;
using WCS.Model.ApiModel;
using System.Windows.Controls;
using WCS.Model.ApiModel.InterfaceRecord;
using TouchSocket.Sockets;
using TouchSocket.Core;
using System.Text.RegularExpressions;
using System.Collections.ObjectModel;
using WCS.BLL.DbModels;
using WCS.Model.ApiModel.MatBaseInfo;
using System.Security.Cryptography;
using Ping9719.WpfEx;
using System.Diagnostics.Eventing.Reader;

namespace 智慧物流软件系统.ViewModel
{
    public class InInventoryViewModel : BindableBase
    {
        public InInventoryViewModel()
        {
            //初始化串口接收事件
            var scanners = ScannerManager.Scanners;
            foreach (var scanner in scanners)
            {
                scanner.SerialPortClient.Received = (client, e) =>
                {
                    //获取串口号
                    var COM = client.MainSerialPort.PortName;
                    //获取扫码枪对象
                    var scanner = ScannerManager.Scanners.Where(t => t.COM == COM).FirstOrDefault();
                    if (scanner == null)
                        return EasyTask.CompletedTask;
                    int newBytes = e.ByteBlock.Len;
                    if (newBytes > 0)
                    {
                        var currentScanedCode = Encoding.UTF8.GetString(e.ByteBlock, 0, e.ByteBlock.Len);
                        Logs.Write($"接收到扫码枪[{scanner.COM}]扫码数据{currentScanedCode}", LogsType.Scanner);
                        scanner.TempCode += currentScanedCode;
                        //校验末尾码
                        CheckDataCompleteness(scanner);
                        scanner.ScannerDisplayControl.RefreshValues(scanner.ShelfCode, scanner.MatSn, scanner.InstoreUser);
                    }
                    return EasyTask.CompletedTask;
                };
            }
            RevertScannerStatus();
        }

        #region Property
        private string shelfCode;
        public string ShelfCode
        {
            get { return shelfCode; }
            set
            {
                SetProperty(ref shelfCode, value);
            }
        }
        #endregion

        #region Command
        /// <summary>
        /// 第一次加载时 获取服务器对应货架是否在入库模式 是否是扫码枪启动的 还原扫码枪的状态
        /// </summary>
        public void RevertScannerStatus()
        {
            Task.Run(() =>
            {
                Thread.Sleep(1000);
                try
                {
                    var body = new GetShelfStatusRequest()
                    {
                        UserName = LocalStatic.CurrentUser,
                        DeviceType = "WCS前端",
                        GroupNames = LocalFile.Config.GroupName,
                    };
                    var Result = ApiHelp.Post<GetShelfStatusResponse>([LocalFile.Config.ApiIpHost, "home/getShelfStatus"], body).Result;
                    if (Result != null && Result.Data != null && Result.Data?.Count > 0)
                    {
                        var shelfs = Result.Data.Where(t => t.CurentMode == 1 && !string.IsNullOrEmpty(t.CurrentCom)).ToList();
                        if (shelfs == null || shelfs.Count == 0)
                            return;

                        Logs.Write($"【启动时发现需要恢复扫码枪状态】{string.Join(",", shelfs.Select(t => t.CurrentCom).ToList())}", LogsType.Scanner);
                        foreach (var shelf in shelfs)
                        {
                            var scanner = ScannerManager.Scanners.Where(t => t.COM == shelf.CurrentCom).FirstOrDefault();
                            if (scanner != null)
                            {

                                scanner.IsInstoreMode = true;
                                scanner.IsInstoreModeTime = shelf.SetCurrentModeTime;
                                scanner.ShelfCode = shelf.ShelfCode;
                                scanner.ModulesStr = shelf.ModulesStr;

                                scanner.ScannerDisplayControl.RefreshValues(scanner.ShelfCode, scanner.MatSn, scanner.InstoreUser);
                                Logs.Write($"【恢复扫码枪】{scanner.COM}", LogsType.Scanner);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                }
                finally
                {
                }
            });
        }

        public void CheckDataCompleteness(Scanner scanner)
        {
            if (scanner.TempCode.EndsWith("\r"))//结束符 TODO结束符是否需要自定义 现场配置
            {
                scanner.TempCode = scanner.TempCode.Replace("\r", string.Empty).Replace("\n", string.Empty);
                //金川项目-扫物料码生成本地物料码流程
                if (LocalStatic.IsScanGenarateMatInfoWindowOpen)
                {
                    try
                    {
                        LocalStatic.ScanGenarateMatInfoWindow.viewModel.ParsingBarcode(scanner.TempCode);
                    }
                    catch (Exception ex)
                    {
                        var message = "物料扫码发生异常:" + ex.Message;
                        Logs.Write(message, LogsType.Scanner);
                    }
                    finally
                    {
                        scanner.TempCode = string.Empty;
                    }
                }
                else
                    //入库流程的情况下
                    try
                    {
                        //数据处理
                        //获取配置文件的正则表达式
                        var configModuleCodePattern = LocalFile.Config.ModuleCodePattern;
                        string ModuleCodePattern = string.IsNullOrEmpty(configModuleCodePattern) ? "^[ABCD][0-9]{2}-R[0-9]{1,2}C[0-9]{1,2}$" : configModuleCodePattern;
                        var isModuleCode = Regex.IsMatch(scanner.TempCode, ModuleCodePattern);
                        if (isModuleCode)
                        {
                            Logs.Write($"[{scanner.COM}]校验到扫码数据为货架码【{scanner.TempCode}】", LogsType.Scanner);
                            ModuleCodeProcess(scanner);
                        }
                        else if (scanner.TempCode == "shelfGoOutInStore")
                        {
                            Logs.Write($"[{scanner.COM}]校验到扫码数据为结束入库码【{scanner.TempCode}】", LogsType.Scanner);
                            ShelfGoOutInstoreProcess(scanner);
                        }
                        else if (scanner.TempCode.ToUpper().Contains("MXID") && scanner.TempCode.ToUpper().Contains("NAME"))
                        {
                            string pattern = @"\b\d{6}\b"; // 匹配一个完整的6位数字
                            Match match = Regex.Match(scanner.TempCode, pattern);
                            if (match.Success)
                            {
                                scanner.InstoreUser = match.Value;
                            }
                            else
                            {
                                //
                                Logs.Write($"扫码枪扫到{scanner.TempCode}，无法解析出工号！", LogsType.Scanner);
                            }
                        }
                        else if (Regex.IsMatch(scanner.TempCode, @"^\d{6}$"))
                        {
                            scanner.InstoreUser = scanner.TempCode;
                        }
                        else
                        {
                            Logs.Write($"[{scanner.COM}]校验到扫码数据为物料码【{scanner.TempCode}】", LogsType.Scanner);
                            MatSnProcess(scanner);
                        }
                    }
                    catch (Exception ex)
                    {
                        var message = "入库扫码枪扫码发生异常:" + ex.Message;
                        Logs.Write(message, LogsType.Scanner);
                    }
                    finally
                    {
                        //不管入库成功与否 认为本次扫码完毕 清空暂存数据
                        scanner.TempCode = string.Empty;
                    }
            }
        }
        /// <summary>
        /// 扫到模组码的数据处理
        /// </summary>
        /// <param name="scanner"></param>
        public void ModuleCodeProcess(Scanner scanner)
        {
            //如果扫码枪前一个货架未退出入库
            if (scanner.IsInstoreMode)
            {
                //判断当前入库货架是否包含本次扫码的模组 表示用户重复对货架码进行扫码 不能让其多次进入入库
                if (scanner.ModulesStr.Contains(scanner.TempCode))
                {
                    Logs.Write($"当前扫码模组{scanner.TempCode},是当前入库货架{scanner.ShelfCode}的模组，不进行操作！", LogsType.Scanner);
                    return;
                }
                else
                {
                    Logs.Write($"当前扫码模组{scanner.TempCode},不是当前入库货架{scanner.ShelfCode}的模组，先进行当前入库货架的退出入库操作！", LogsType.Scanner);
                    #region 调用接口结束扫码枪占用入库的货架
                    try
                    {
                        var body = new ShelfGoOutInStoreRequest()
                        {
                            ShelfCode = scanner.ShelfCode,
                            IPAdress = scanner.COM,
                            DeviceType = LocalFile.Config.DeviceType,
                            UserName = string.IsNullOrEmpty(scanner.InstoreUser) ? LocalStatic.CurrentUser : scanner.InstoreUser,
                        };
                        var Result = ApiHelp.GetDataFromHttp<ResponseBase>(LocalFile.Config.ApiIpHost + "instore/shelfGoOutInStore", body, "POST", true);
                        if (Result != null && Result.Code == 200)
                        {
                            Logs.Write($"货架{scanner.ShelfCode}已成功退出入库！", LogsType.Scanner);
                            scanner.IsInstoreMode = false;
                            scanner.ShelfCode = string.Empty;
                            scanner.ModulesStr = string.Empty;
                        }
                        else
                        {
                            Logs.Write($"货架{scanner.ShelfCode}退出入库失败！", LogsType.Scanner);
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        Logs.Write($"货架{scanner.ShelfCode}退出入库失败！发生异常：{ex.Message}", LogsType.Scanner);
                    }
                    #endregion
                }
            }
            //调用接口 本次扫码的货架进入入库模式
            #region 调用接口进入入库模式
            try
            {
                Logs.Write($"扫码模组{scanner.TempCode},请求进入入库！", LogsType.Scanner);
                var body = new ShelfGoInInstoreRequest()
                {
                    ModuleCode = scanner.TempCode,
                    DeviceType = LocalFile.Config.DeviceType,
                    UserName = string.IsNullOrEmpty(scanner.InstoreUser) ? LocalStatic.CurrentUser : scanner.InstoreUser,
                    IpAdress = scanner.COM,
                };
                var Result = ApiHelp.GetDataFromHttp<ShelfGoInInstoreResponse>(LocalFile.Config.ApiIpHost + "instore/shelfGoInInStore", body, "POST");
                if (Result != null && Result.Code == 200)
                {
                    Logs.Write($"扫码模组{scanner.TempCode},进入入库模式成功！", LogsType.Scanner);
                    scanner.IsInstoreMode = true;
                    scanner.IsInstoreModeTime = DateTime.Now;
                    scanner.ShelfCode = Result.Data.ShelfCode;
                    scanner.ModulesStr = Result.Data.ModulesStr;

                    //清除其他扫码枪的占用
                    var sacnners = ScannerManager.Scanners
                                                 .Where(t => ShelfCode == Result.Data.ShelfCode)
                                                 .Where(t => t.COM != scanner.COM)
                                                 .ToList();
                    foreach (var scanner1 in sacnners)
                    {
                        scanner1.ShelfCode = string.Empty;
                        scanner1.ModulesStr = string.Empty;
                    }
                }
                else if (Result != null && !string.IsNullOrEmpty(Result.Message))
                {
                    Logs.Write($"扫码模组{scanner.TempCode},进入入库模式失败！{Result.Message}", LogsType.Scanner);
                    Growl.Warning(Result.Message);
                }
            }
            catch (Exception ex)
            {
                Growl.Warning(ex.Message);
            }
            #endregion
        }

        /// <summary>
        /// 扫码枪扫到结束码
        /// </summary>
        /// <param name="scanner"></param>
        public void ShelfGoOutInstoreProcess(Scanner scanner)
        {
            #region 调用接口结束扫码枪占用入库的货架
            try
            {
                var body = new ShelfGoOutInStoreRequest()
                {
                    ShelfCode = scanner.ShelfCode,
                    IPAdress = scanner.COM,
                    DeviceType = LocalFile.Config.DeviceType,
                    UserName = string.IsNullOrEmpty(scanner.InstoreUser) ? LocalStatic.CurrentUser : scanner.InstoreUser,
                };
                var Result = ApiHelp.GetDataFromHttp<ResponseBase>(LocalFile.Config.ApiIpHost + "instore/shelfGoOutInStore", body, "POST");
                if (Result != null && Result.Code == 200)
                {
                    scanner.IsInstoreMode = false;
                    scanner.ShelfCode = string.Empty;
                    scanner.ModulesStr = string.Empty;
                }
            }
            catch (Exception ex)
            {

            }
            #endregion
        }
        /// <summary>
        /// 扫到物料码的数据处理
        /// </summary>
        public void MatSnProcess(Scanner scanner)
        {
            #region 调用接口 扫物料码获取物料信息并绑定
            try
            {
                var body = new QueryByMatSnRequest()
                {
                    MatSn = scanner.TempCode,
                    ShelfCode = scanner.ShelfCode,
                    IpAddress = scanner.COM,
                    DeviceType = LocalFile.Config.DeviceType,
                    UserName = string.IsNullOrEmpty(scanner.InstoreUser) ? LocalStatic.CurrentUser : scanner.InstoreUser,
                };
                var Result = ApiHelp.GetDataFromHttp<ResponseCommon<MatInfoModel>>(LocalFile.Config.ApiIpHost + "instore/queryByMatSn", body, "POST");
                if (Result != null && Result.Code == 200)
                {
                    scanner.MatSn = Result.Data.MatSN;
                    #region 调用接口获取入库状态
                    Task.Run(() =>
                    {
                        try
                        {
                            var body = new QueryByMatSnRequest()
                            {
                                MatSn = scanner.MatSn,
                                ShelfCode = scanner.ShelfCode,
                                IpAddress = scanner.COM,
                                DeviceType = LocalFile.Config.DeviceType,
                                UserName = string.IsNullOrEmpty(scanner.InstoreUser) ? LocalStatic.CurrentUser : scanner.InstoreUser,
                            };
                            var Result = ApiHelp.GetDataFromHttp<ResponseCommon<MatInfoModel>>(LocalFile.Config.ApiIpHost + "instore/queryInstoreStatus", body, "POST");
                            if (Result != null && !string.IsNullOrEmpty(Result.Message))
                            {
                                TextBoxLog.AddLog($"物料[{scanner.MatSn}]" + Result.Message, "InstoreLog", DateTime.Now);
                                scanner.MatSn = string.Empty;
                                scanner.ScannerDisplayControl.RefreshValues(scanner.ShelfCode, scanner.MatSn, scanner.InstoreUser);
                            }
                        }
                        catch (Exception ex)
                        {
                            Growl.Warning(ex.Message);
                        }
                    });
                    #endregion
                }
                else if (Result != null && !string.IsNullOrEmpty(Result.Message))
                {
                    Growl.Warning(Result.Message);
                }
            }
            catch (Exception ex)
            {
                Growl.Warning(ex.Message);
            }
            #endregion
        }
        public ICommand BtnEndCommand { get => new DelegateCommand(BtnEnd); }
        public void BtnEnd()
        {
            try
            {
                //获取当前入库的货架
                ScannerManager.Scanners.Where(t => t.IsInstoreMode).ToList().ForEach(t =>
                {
                    if (!string.IsNullOrEmpty(t.ShelfCode))
                    {
                        var body = new ShelfGoOutInStoreRequest()
                        {
                            ShelfCode = t.ShelfCode,
                            DeviceType = LocalFile.Config.DeviceType,
                            UserName = string.IsNullOrEmpty(t.InstoreUser) ? LocalStatic.CurrentUser : t.InstoreUser,
                        };
                        var Result = ApiHelp.GetDataFromHttp<ResponseCommon>(LocalFile.Config.ApiIpHost + "instore/shelfGoOutInStore", body, "POST");
                        if (Result != null && Result.Code == 200)
                        {
                            t.IsInstoreMode = false;
                            t.ShelfCode = string.Empty;
                            t.MatSn = string.Empty;

                            t.ScannerDisplayControl.RefreshValues(t.ShelfCode, t.MatSn, t.InstoreUser);
                            Growl.Success(Result.Message);
                        }
                    }
                    else
                    {
                        t.IsInstoreMode = false;
                        Logs.Write($"扫码枪{t.COM}的货架码因为某种原因丢失！");
                    }
                });
            }
            catch (Exception ex)
            {
                Growl.Warning(ex.Message);
            }
        }

        public ICommand ClearTextInfoCommand { get => new DelegateCommand(ClearTextInfo); }
        /// <summary>
        /// 清除信息文本
        /// </summary>
        public void ClearTextInfo()
        {
            TextBoxLog.ClearLog("InstoreLog");
        }
        #endregion
    }
}
