@page "/invoice/add/{invoice}"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;
    
        单据号:
        @(invoice?.InvoiceNo)
        时间:
        @(invoice?.InvoiceDate)
    
    
        
            
                
                    
                        
                            
                                @s.DrawerNo - @s.ColNo
                            
                        
                        
                        @*       
                         *@
                        
                            
                                @ManuNo.ManuNo
                                @if (ManuNo.Quantity > 0)
                                {
                                            
                                        @ManuNo.ManuNo
                                            
                                }
                            
                            
                                @if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId))
                                {
                                
                                    
                                        @((context as DrugManuNo)?.ManuNo)
                                            @if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
                                            {
                                                    @((context as DrugManuNo).EffDate.ToString().Substring(0, 10))
                                            }
                                            else
                                            {
                                                    @((context as DrugManuNo)?.EffDate)
                                            }
                                    
                                    
                                        
                                            @((context as DrugManuNo)?.ManuNo)
                                                @if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
                                                {
                                                        @((context as DrugManuNo).EffDate.ToString().Substring(0, 10))
                                                }
                                                else
                                                {
                                                        @((context as DrugManuNo)?.EffDate)
                                                }
                                        
                                    
                                
                                
                                }
                                else
                                {
                                @channel.drugManuNo?.ManuNo
                                @channel.drugManuNo?.EffDate
                                }
                            
                        
                        
                            
                                
                                
                                
                            
                        
                    
                
            
            
                
                
                
                    
                        @(ManuNo.Invoice.DrugManuNo == "X" ? "无" : ManuNo.Invoice.DrugManuNo)
                    
                
                
                
                
            
        
    
    
        @if (status < 2)
        {
                    
        }
        @if (status == 2)
        {
                    
        }
        @if (status < 2)
        {
                    
        }
    
@code {
    @inject Radzen.DialogService dialogService;
    @inject IInOutInvoiceDao inOutInvoiceDao;
    @inject IOptions setting;
    @inject NotificationService _message
    @inject PortUtil PortUtil;
    RadzenDataGrid grid;
    private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceAddDialog));
    [Parameter] public InOutInvoice invoice { get; set; }
    private bool CanTakeDrug = true;
    int status = 0;
    public List data { get; set; }
    //称重取药数量
    int[] WeightFinnalQuantity { get; set; } = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    // 当前操作的库位号列表
    public List ColNos { get; set; } = new List();
    int currentCol = 0;
    //开抽屉前操作标识
    private List _flagList = new List();
    async Task StartAdd()
    {
        if (data.Any(it => it.Quantity != it.ChannelStocks.Sum(cs => cs.AddQuantity)))
        {
            _message.Notify(
                new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的入库数量!", Duration = 4000 }
            );
        }
        else
        {
            await OpenDrawer();
        }
    }
    async Task CancelOpera()
    {
        PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
        PortUtil.Operate = false;
        status = 0;
        dialogService.Close(false);
    }
    async Task OpenDrawer()
    {
        this.status = 1;
        PortUtil.PowerOn();
        await Task.Delay(200);
        // 解析需要打开的抽屉列表
        List channels = new();
        for (int i = 0; i < data.Count; i++)
        {
            channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.AddQuantity > 0)).ToList();
        }
        List drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList();
        // 根据抽屉类型来决定打开前是否需要查询数量
        int index = 0;
        var BeforeQuantity = new int[9];
        var AfterQuantity = new int[9];
        await new PromiseUtil().taskAsyncLoop(500, 0, async (options, next, stop) =>
        {
            var drawerNo = drawerNos[index];
            try
            {
                if (this.status == 0)
                {
                    stop();
                }
                // 开启抽屉
                else if (this.status == 1)
                {
                    if (options._data == 0)
                    {
                        BeforeQuantity = new int[9];
                        AfterQuantity = new int[9];
                        for (int j = 0; j < data[index].ChannelStocks.Count; j++)
                        {
                            // _flagList.Add(flag);
                            //单支-查数
                            if (data[index].ChannelStocks[j].BoardType.ToString().Contains("2"))
                            {
                                byte[] quantity = await PortUtil.CheckQuantityByDrawer(data[index].ChannelStocks[j].DrawerNo);
                                data[index].BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
                                logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", data[index].BeforeQuantity)}】");
                                await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast().ToArray());
                            }
                            //称重-查数
                            if (data[index].ChannelStocks[j].BoardType.ToString().Contains("6"))
                            {
                                PortUtil.DrawerNo = data[index].ChannelStocks[j].DrawerNo;// drawerNo;
                                PortUtil.ColNoLst.Add(data[index].ChannelStocks[j].ColNo);
                                data[index].BeforeQuantity[data[index].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[index].ChannelStocks[j].ColNo);
                                logger.Info($"称重抽屉【{data[index].ChannelStocks[j].DrawerNo}】,开抽屉前检测数量【{string.Join(",", data[index].BeforeQuantity)}】");
                                await Task.Delay(200);
                            }
                            //药盒-开药盒
                            if (data[index].ChannelStocks[j].BoardType.ToString().Contains("3"))
                            {
                                PortUtil.DrawerNo = data[index].ChannelStocks[j].DrawerNo;
                                await PortUtil.OpenBoxByColNo(data[index].ChannelStocks[j].ColNo);
                                await Task.Delay(200);
                            }
                        }
                        var b = await PortUtil.OpenDrawerStatus(drawerNo);
                        if (b)
                        {
                            PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
                            PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药");
                            options._data = 1;
                            PortUtil.Operate = true;
                            next();
                        }
                        else
                        {
                            _message.Notify(
                                new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
                            );
                            logger.Info($"抽屉打开失败");
                            PortUtil.PowerOff();
                            RestData();
                            stop();
                        }
                    }
                    // 检测状态
                    else if (options._data == 1)
                    {
                        // 查询抽屉是否为关闭状态
                        var b = await PortUtil.CheckDrawerStatus2(drawerNo);
                        // 关闭则改变状态并终止循环
                        if (b)
                        {
                            options._data = 0;
                            if (setting.Value.single.Contains(drawerNo))
                            {
                                PortUtil.PowerOff();
                            }
                            if (index == drawerNos.Count - 1)
                            {
                                PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
                                PortUtil.SpeakAsync($"加药完成,请,点击完成按钮进行确认");
                                this.status = 2;
                                string alertMessage = string.Empty;
                                bool cancelFlag = false;
                                for (int i = 0; i < data.Count; i++)
                                {
                                    for (int j = 0; j < data[i].ChannelStocks.Count; j++)
                                    {
                                        string flag = "关" + data[i].ChannelStocks[j].DrawerNo.ToString() + data[i].ChannelStocks[j].ColNo.ToString();
                                        if (!_flagList.Contains(flag))
                                        {
                                            _flagList.Add(flag);
                                            //关闭抽屉后获取称重数量
                                            PortUtil.DrawerNo = data[i].ChannelStocks[j].DrawerNo;// drawerNo;
                                            // 判断是否为称重抽屉
                                            //单支-查数
                                            if (data[i].ChannelStocks[j].BoardType.ToString().Contains("6"))
                                            {
                                                PortUtil.ColNoLst = this.ColNos;
                                                AfterQuantity[data[i].ChannelStocks[j].ColNo - 1] = await PortUtil.CheckQuantityForSingle(data[i].ChannelStocks[j].ColNo);
                                                logger.Info($"称重抽屉,关抽屉后检测数量【{string.Join(",", AfterQuantity)}】");
                                                WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] - AfterQuantity[data[i].ChannelStocks[j].ColNo - 1];
                                                if (data[i].ChannelStocks[j].Quantity != WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1])
                                                {
                                                    //称重自动计数数量与实际要取数量不一致弹出提示,确认后保存数据
                                                    alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1]}】";
                                                }
                                            }
                                            //单支-查数
                                            if (data[i].ChannelStocks[j].BoardType.ToString().Contains("2"))
                                            {
                                                byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo);
                                                AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
                                                logger.Info($"单支抽屉,关抽屉后检测数量【{string.Join(",", AfterQuantity)}】");
                                                WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1] = data[i].BeforeQuantity[data[i].ChannelStocks[j].ColNo - 1] - AfterQuantity[data[i].ChannelStocks[j].ColNo - 1];
                                                if (data[i].ChannelStocks[j].Quantity != WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1])
                                                {
                                                    alertMessage += $"{data[i].Drug.DrugName}应取数量【{data[i].ChannelStocks[j].Quantity}】,实际取出数量【{WeightFinnalQuantity[data[i].ChannelStocks[j].ColNo - 1]}】";
                                                }
                                            }
                                            if (!string.IsNullOrEmpty(alertMessage))
                                            {
                                                //弹出确认对话框
                                                alertMessage += "应取数与实际取出数不一致确认要保存吗?";
                                                //弹出确认提示框
                                                var confirm = await dialogService.OpenAsync
                                                                (
                                                                    $"保存确认",
                                                                    new Dictionary
                                                                    () { { "confirmInfo", alertMessage } },
                                                                    new DialogOptions()
                                                                        { Width = "45vw", Resizable = true, Draggable = true, ShowClose = false });
                                                if (!confirm)
                                                {
                                                    RestData();
                                                    logger.Info("取消保存");
                                                    cancelFlag = true;
                                                    // 关闭弹窗
                                                    dialogService.Close(false);
                                                    break;
                                                }
                                                else
                                                {
                                                    logger.Info(alertMessage);
                                                }
                                                alertMessage = string.Empty;
                                            }
                                        }
                                    }
                                    if (cancelFlag)
                                    {
                                        break;
                                    }
                                }
                                stop();
                            }
                            else
                            {
                                index += 1;
                                next();
                            }
                        }
                        else
                        {
                            // if (setting.Value.single.Contains(drawerNo))
                            // {
                            //     byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo);
                            //     AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
                            //     logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】");
                            //     data.ForEach(cl =>
                            //     {
                            //         cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs =>
                            //         {
                            //             logger.Info($"单支抽屉【{drawerNo}】,应加药品数量【{cs.AddQuantity}】,现实取数量【{AfterQuantity[cs.ColNo - 1] - BeforeQuantity[cs.ColNo - 1]}】");
                            //         });
                            //     });
                            // }
                            next(); // continue iteration
                        }
                    }
                }
            }
            catch (Exception e)
            {
                RestData();
                logger.Info($"调拨加药发生错误,{e.Message}");
                _message.Notify(
            new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 }
            );
                if (setting.Value.single.Contains(drawerNo))
                {
                    PortUtil.PowerOff();
                }
            }
        });
        PortUtil.PowerOff();
    }
    void RestData()
    {
        PortUtil.PowerOff();
        PortUtil.Operate = false;
        this.status = 0;
        _flagList.Clear();
        this.ColNos.Clear();
    }
    async Task AddFinish()
    {
        // 保存账册、操作记录
        var b = await inOutInvoiceDao.InvoiceAddFinish(data);
        if (!b)
        {
            _message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
            logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(data)}");
            // 关闭弹窗
            dialogService.Close(false);
        }
        else
        {
            // 关闭弹窗
            dialogService.Close(true);
        }
        //重置状态
        this.RestData();
    }
    protected override async Task OnInitializedAsync()
    {
        data = await inOutInvoiceDao.getAddInfoByInvoiceNo(invoice.InvoiceNo);
        // 如果有库位列表未空则说明不能取药,需要增加库位
        if (data.Any(it => it.ChannelStocks.Count == 0))
        {
            CanTakeDrug = false;
        }
        base.OnInitializedAsync();
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {
            await Task.Delay(15);
            await grid.ExpandRows(grid.PagedView.Where(it => it.ChannelStocks.Count > 0));
        }
    }
    void RowRender(RowRenderEventArgs
        args)
    {
        args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0;
    }
    void OnCellClick(DataGridCellMouseEventArgs
        args, RadzenDataGrid
            Grid)
    {
        Grid.EditRow(args.Data);
    }
}