@page "/return/empty/{records}"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;

<RadzenFieldset Text="药品信息">
    <RadzenStack Orientation="Orientation.Horizontal" Gap="10px" JustifyContent="JustifyContent.Center" AlignItems="AlignItems.Center" Wrap="FlexWrap.NoWrap" Style="height: 80px;padding:20px;">
        <RadzenStack class="rz-p-1  rz-text-align-center" Style="width:500px">
            药品：@drugName
        </RadzenStack>
        <RadzenStack class="rz-p-1 rz-text-align-center" Style="width:500px">
            规格：@drugSpec
        </RadzenStack>
        <RadzenStack class="rz-p-1 rz-text-align-center" Style="width:500px">
            厂家：@drugManufactory
        </RadzenStack>
        <RadzenStack class="rz-p-1   rz-text-align-center" Style="width:500px">
            可还空瓶数：@emptyQuantity
        </RadzenStack>
    </RadzenStack>
</RadzenFieldset>
<div  Style="height:50vh;overflow:auto;">
    <RadzenDataGrid @ref="grid"
    LoadData="@LoadData"
    IsLoading="@isLoading"
    Count="@count"
    EmptyText="无数据"
    Data="@_returnEmptys"
    AllowColumnResize="true" AllowAlternatingRows="false"
    AllowRowSelectOnRowClick="true"
    CellClick="@((DataGridCellMouseEventArgs<MachineRecord> args) => OnCellClick(args))"
    AllowPaging="false" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
        <Columns>
            <RadzenDataGridColumn Width="60px" Sortable="false" Filterable="false">
                <HeaderTemplate>
                    选择
                </HeaderTemplate>
                <Template Context="LoadData">
                    <RadzenCheckBox TriState="false" Value="@LoadData.IsSelected" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select item" }})"
                    TValue="bool" />
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn Frozen="true" Title="操作人" Property="OperatorUser.NickName"></RadzenDataGridColumn>
            <RadzenDataGridColumn Width="170px" Title="操作时间" Property="OperationTime"></RadzenDataGridColumn>
            <RadzenDataGridColumn Title="批次" Property="ManuNo">
                <Template Context="mr">
                    <RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@mr.ManuNo</RadzenText>
                    <RadzenText TextStyle="TextStyle.Caption"> @mr.EffDate?.ToString("yyyy-MM-dd")</RadzenText>
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn Title="数量" Property="Quantity"></RadzenDataGridColumn>
            <RadzenDataGridColumn Title="已还药品" Property="ReturnQuantity1"></RadzenDataGridColumn>
            <RadzenDataGridColumn Title="已还空瓶" Property="ReturnQuantity2"></RadzenDataGridColumn>
            <RadzenDataGridColumn Title="本次归还" Property="CurrentReturnQuantity">
                <EditTemplate Context="mr">
                    <RadzenNumeric Min="0" Style="display: block" Max="@(mr.Quantity - mr.ReturnQuantity1 - mr.ReturnQuantity2)" Name="Quantity" @bind-Value=@mr.CurrentReturnQuantity />
                </EditTemplate>
            </RadzenDataGridColumn>
        </Columns>
    </RadzenDataGrid>
</div>
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem" Style="margin-top:15px;">
    @if (status < 2)
    {
        <RadzenButton Click="@StartAdd" IsBusy="status > 0" BusyText="还空瓶中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="归还" Style="width: 120px" />
    }
    @if (status == 2)
    {
        <RadzenButton Click="@AddFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
    }
    @if (status < 2)
    {
        <RadzenButton Click="@((args) => CancelOpera())" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
    }
</RadzenStack>
@code
{
    @inject IMachineRecordDao machineRecordDao;
    @inject Radzen.DialogService dialogService;
    @inject IMachineRecordDao machineRecordDao;
    @inject IOptions<DrawerConfig> setting;
    @inject NotificationService _message
    @inject PortUtil PortUtil;

    [Parameter]
    public ChannelStock records { get; set; }
    // public PageData<MachineRecord> data { get; set; }
    string drugName = string.Empty;
    string drugSpec = string.Empty;
    string drugManufactory = string.Empty;
    int emptyQuantity = 0;

    RadzenDataGrid<MachineRecord> grid;
    bool isLoading;
    int count;
    private List<MachineRecord>? _returnEmptys;
    async Task LoadData(LoadDataArgs args)
    {
        isLoading = true;
        drugName = records.Drug.DrugName;
        drugSpec = records.Drug.DrugSpec;
        drugManufactory = records.Drug.Manufactory;

        var result = await machineRecordDao.getReturnEmptyInfoByRecords(records);
        // Update the Data property
        _returnEmptys = result.Desserts;
        emptyQuantity = _returnEmptys.Sum(it => it.Quantity - it.ReturnQuantity1 - it.ReturnQuantity2);
        // Update the count
        count = result.TotalDesserts;

        isLoading = false;
    }

    async Task reloadGrid()
    {
        await grid.Reload();
    }
    void OnCellClick(DataGridCellMouseEventArgs<MachineRecord> args)
    {
        MachineRecord machineRecord = args.Data;
        grid.EditRow(machineRecord);
        if (machineRecord.CurrentReturnQuantity > 0 && args.Column.ColumnPickerTitle == "本次归还")
        {
            machineRecord.IsSelected = true;
        }
        else
        {
            machineRecord.IsSelected = !machineRecord.IsSelected;
            if (machineRecord.IsSelected)
            {
                machineRecord.CurrentReturnQuantity = machineRecord.Quantity - machineRecord.ReturnQuantity1 - machineRecord.ReturnQuantity2;
            }
            else
            {
                machineRecord.CurrentReturnQuantity = 0;
            }
        }
    }


    private readonly ILog logger = LogManager.GetLogger(typeof(RecordReturnEmptyDialog));
    int status = 0;
    async Task StartAdd()
    {
        if (_returnEmptys.Where(it => it.CurrentReturnQuantity > 0).Count() <= 0)
        {
            _message.Notify(
                new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请选择药品！", Duration = 4000 }
            );

        }
        else
        {
            await OpenDrawer();
        }
    }

    async Task CancelOpera()
    {
        PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
        status = 0;
        dialogService.Close(false);
    }


    async Task OpenDrawer()
    {
        this.status = 1;
        PortUtil.PowerOn();
        await Task.Delay(200);
        // 解析需要打开的抽屉列表

        int drawerNo = records.DrawerNo;

        // 根据抽屉类型来决定打开前是否需要查询数量
        int index = 0;
        var BeforeQuantity = new int[9];
        var AfterQuantity = new int[9];
        await new PromiseUtil<int>().taskAsyncLoop(500, 0, async (options, next, stop) =>
        {
            try
            {
                if (this.status == 0)
                {
                    stop();
                }
                // 开启抽屉
                else if (this.status == 1)
                {
                    if (options._data == 0)
                    {
                        BeforeQuantity = new int[9];
                        AfterQuantity = new int[9];
                        // 判断是否为单支抽屉
                        if (setting.Value.single.Contains(drawerNo))
                        {
                            byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo);
                            BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
                            logger.Info($"单支抽屉【{drawerNo}】，开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】");

                            //await PortUtil.NoLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast<int>().ToArray());
                        }
                        var b = await PortUtil.OpenDrawerStatus(drawerNo);
                        if (b)
                        {
                            PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
                            PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开，请放入空瓶");
                            options._data = 1;
                            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();
                            }
                            PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
                            PortUtil.SpeakAsync($"加药完成，请，点击完成按钮进行确认");
                            this.status = 2;
                            stop();
                        }
                        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();
                }
                stop();
            }
        });
        PortUtil.PowerOff();
    }

    void RestData()
    {
        PortUtil.PowerOff();
        this.status = 0;
    }

    async Task AddFinish()
    {

        // 保存账册、操作记录
        var b = await machineRecordDao.ReturnEmptyFinish(_returnEmptys.Where(it => it.CurrentReturnQuantity > 0).ToList(), records);
        if (!b)
        {
            _message.Notify(new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
            logger.Error($"还空瓶保存数据库失败，数据{JsonConvert.SerializeObject(_returnEmptys)}");
            // 关闭弹窗
            dialogService.Close(false);
        }
        else
        {
            // 关闭弹窗
            dialogService.Close(true);
            _message.Notify(new NotificationMessage { Style = "position: absolute; inset-inline-start: -1000px;", Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"还空瓶操作完成！", Duration = 4000 });

        }
        //重置状态
        this.RestData();
    }
}
