@using AyCode.Blazor.Components.Components.Grids
@using AyCode.Core.Loggers;
@using AyCode.Core.Extensions
@using AyCode.Core.Helpers
@using AyCode.Core.Interfaces
@using AyCode.Utils.Extensions
@using FruitBank.Common.Dtos
@using FruitBank.Common.Entities
@using FruitBank.Common.Enums
@using FruitBank.Common.Interfaces
@using FruitBankHybrid.Shared.Components.Grids.ShippingItems
@using FruitBankHybrid.Shared.Databases
@using FruitBankHybrid.Shared.Services.Loggers;
@using FruitBankHybrid.Shared.Services.SignalRs

@inject IEnumerable<IAcLogWriterClientBase> LogWriters
@inject FruitBankSignalRClient FruitBankSignalRClient

<MgGridWithInfoPanel ShowInfoPanel="@IsMasterGrid">
    <GridContent>
        <GridShippingItemBase @ref="Grid" ParentDataItem="ParentDataItem" DataSource="ShippingItems" AutoSaveLayoutName="GridShippingItem"
                              SignalRClient="FruitBankSignalRClient" Logger="_logger"
                              CssClass="@GridCss" ValidationEnabled="false" CustomizeElement="Grid_CustomizeElement"
                              OnGridFocusedRowChanged="Grid_FocusedRowChanged">
            <Columns>
                <DxGridDataColumn FieldName="Id" Caption="oiId" Width="125" SortIndex="0" SortOrder="GridColumnSortOrder.Descending" ReadOnly="true" />
                <DxGridDataColumn FieldName="ShippingDocumentId" Caption="ShippingDocument"
                                  Visible="@(!ParentDataItemIsShippingDocument)" ReadOnly="@(ParentDataItemIsShippingDocument)">
                    <EditSettings>
                        <DxComboBoxSettings Data="ShippingDocuments"
                                            ValueFieldName="Id"
                                            TextFieldName="@nameof(ShippingDocument.PdfFileName)"
                                            DropDownBodyCssClass="dd-body-class"
                                            ListRenderMode="ListRenderMode.Entire"
                                            SearchMode="ListSearchMode.AutoSearch"
                                            SearchFilterCondition="ListSearchFilterCondition.Contains"
                                            ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto">
                            <Columns>
                                <DxListEditorColumn FieldName="@nameof(ShippingDocument.Id)" />
                                <DxListEditorColumn FieldName="@nameof(ShippingDocument.DocumentIdNumber)" />
                                <DxListEditorColumn FieldName="@nameof(ShippingDocument.PdfFileName)" />
                                <DxListEditorColumn FieldName="@("Partner.Name")" />
                            </Columns>
                        </DxComboBoxSettings>
                    </EditSettings>
                </DxGridDataColumn>

                <DxGridDataColumn FieldName="@("ShippingDocument.Partner.Name")" Caption="Patner" Width="125" ReadOnly="true" Visible="@(!ParentDataItemIsShippingDocument)" />

                <DxGridDataColumn FieldName="ProductId" Caption="Product">
                    <EditSettings>
                        <DxComboBoxSettings Data="ProductDtos"
                                            ValueFieldName="Id"
                                            TextFieldName="Name"
                                            DropDownBodyCssClass="dd-body-class"
                                            ListRenderMode="ListRenderMode.Entire"
                                            SearchMode="ListSearchMode.AutoSearch"
                                            SearchFilterCondition="ListSearchFilterCondition.Contains"
                                            ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto">
                            <Columns>
                                <DxListEditorColumn FieldName="@nameof(ProductDto.Id)" />
                                <DxListEditorColumn FieldName="@nameof(ProductDto.Name)" />
                                <DxListEditorColumn FieldName="@nameof(ProductDto.AvailableQuantity)" />
                                <DxListEditorColumn FieldName="@nameof(ProductDto.StockQuantity)" />
                                <DxListEditorColumn FieldName="@nameof(ProductDto.IncomingQuantity)" />
                                <DxListEditorColumn FieldName="@nameof(ProductDto.NetWeight)" />
                                <DxListEditorColumn FieldName="@nameof(ProductDto.IsMeasurable)" />
                            </Columns>
                        </DxComboBoxSettings>
                    </EditSettings>
                </DxGridDataColumn>

                <DxGridDataColumn FieldName="NameOnDocument" MinWidth="120" Caption="Name(OnDoc)" />
                <DxGridDataColumn FieldName="Name" MinWidth="120" Caption="Name" Visible="false" />
                <DxGridDataColumn FieldName="PalletsOnDocument" Caption="Raklap(OnDoc)" />
                <DxGridDataColumn FieldName="QuantityOnDocument" Caption="Mennyiség(OnDoc)" />
                <DxGridDataColumn FieldName="NetWeightOnDocument" Caption="Net.súly(OnDoc)" />
                <DxGridDataColumn FieldName="GrossWeightOnDocument" Caption="Br.súly(OnDoc)" />
                <DxGridDataColumn FieldName="MeasuringCount" Caption="Mérések száma" />

                <DxGridDataColumn FieldName="MeasuredQuantity" Name="MeasuredQuantity" Caption="Mért mennyiség" ReadOnly="true" />
                <DxGridDataColumn FieldName="MeasuredNetWeight" Name="MeasuredNetWeight" Caption="Mért net.súly(kg)" ReadOnly="true" />
                <DxGridDataColumn FieldName="MeasuredGrossWeight" Name="MeasuredGrossWeight" Caption="Mért br.súly(kg)" ReadOnly="true" />

                <DxGridDataColumn FieldName="IsMeasurable" ReadOnly="true" />
                <DxGridDataColumn FieldName="IsMeasured" ReadOnly="true" />
                <DxGridDataColumn FieldName="UnitPriceOnDocument" Caption="Bekerülési ár" />

                <DxGridDataColumn FieldName="Created" ReadOnly="true" Visible="false" />
                <DxGridDataColumn FieldName="Modified" ReadOnly="true" Visible="false" />
                <DxGridCommandColumn Visible="!IsMasterGrid" Width="120"></DxGridCommandColumn>
            </Columns>
            @* 	<DataColumnCellDisplayTemplate>
		@{
			if (context.DataColumn.FieldName == nameof(ShippingItem.ShippingDocumentId))
			{
				<span>@(String.Format("{0:P2}", context.Value))</span>
				// format the value as percentage
			}
			else
			{
				<span>@context.DisplayText</span>
			}
		}
	</DataColumnCellDisplayTemplate>
 *@	<DetailRowTemplate>
                @{
                    var shippingItemPallets = ((ShippingItem)context.DataItem).ShippingItemPallets;
                    <GridShippingItemPallets ShippingItemPallets="shippingItemPallets" IsMasterGrid="false"></GridShippingItemPallets>
                }
            </DetailRowTemplate>
            <ToolbarTemplate>
                @if (IsMasterGrid)
                {
                    <MgGridToolbarTemplate Grid="Grid" @ref="toolbar" OnReloadDataClick="() => ReloadDataFromDb(true)" />
                }
            </ToolbarTemplate>
            <GroupSummary>
                <DxGridSummaryItem SummaryType="GridSummaryItemType.Sum"
                                   FieldName="MeasuredQuantity"
                                   FooterColumnName="Quantity" />
                <DxGridSummaryItem SummaryType="GridSummaryItemType.Sum"
                                   FieldName="MeasuredGrossWeight"
                                   FooterColumnName="GrossWeight" />
                <DxGridSummaryItem SummaryType="GridSummaryItemType.Sum"
                                   FieldName="MeasuredNetWeight"
                                   FooterColumnName="NetWeight" />
            </GroupSummary>
        </GridShippingItemBase>
    </GridContent>
</MgGridWithInfoPanel>

@code {
    //[Inject] public required ObjectLock ObjectLock { get; set; }
    [Inject] public required DatabaseClient Database { get; set; }

    //[Parameter] public int GetAllMessageTag { get; set; }
    [Parameter] public IId<int>? ParentDataItem { get; set; }

    [Parameter] public IEnumerable<ProductDto>? ProductDtos { get; set; }
    [Parameter] public AcObservableCollection<ShippingItem>? ShippingItems { get; set; }
    [Parameter] public AcObservableCollection<ShippingDocument>? ShippingDocuments { get; set; }

    public bool IsMasterGrid => ParentDataItem == null;
    public bool ParentDataItemIsShippingDocument => (ParentDataItem is ShippingDocument);
    string GridCss => !IsMasterGrid ? "hide-toolbar" : string.Empty;

    MgGridToolbarTemplate toolbar;

    const string ExportFileName = "ExportResult";
    string _localStorageKey = "GridShippingItem_";

    string GridSearchText = "";
    bool EditItemsEnabled { get; set; } = true;
    int FocusedRowVisibleIndex { get; set; }

    public GridShippingItemBase Grid { get; set; }
    private LoggerClient<GridShippingItemTemplate> _logger;

    protected override async Task OnInitializedAsync()
    {
        _logger = new LoggerClient<GridShippingItemTemplate>(LogWriters.ToArray());

        await ReloadDataFromDb(false);
    }

    public async Task ReloadDataFromDb(bool forceReload = false)
    {
        //using (await ObjectLock.GetSemaphore<ProductDto>().UseWaitAsync())
        {
            if (ProductDtos == null || !ProductDtos.Any() || forceReload) ProductDtos = await Database.ProductDtoTable.LoadDataAsync(!forceReload);
        }

        if (!IsMasterGrid)
        {
            if (ShippingDocuments == null && ParentDataItem is ShippingDocument shippingDocumentParent) ShippingDocuments = [shippingDocumentParent];
            return;
        }

        using (await ObjectLock.GetSemaphore<ShippingDocument>().UseWaitAsync())
        {
            if (ShippingDocuments == null)
            {
                ShippingDocuments = new AcObservableCollection<ShippingDocument>(await FruitBankSignalRClient.GetShippingDocuments() ?? []);
            }
            else if (ShippingDocuments.Count == 0 || forceReload)
            {
                ShippingDocuments.Replace(await FruitBankSignalRClient.GetShippingDocuments() ?? []);
            }
        }

        if (Grid == null) return;

        using (await ObjectLock.GetSemaphore<ShippingItem>().UseWaitAsync())
            if (forceReload) await Grid.ReloadDataSourceAsync();

        if (forceReload) Grid.Reload();
    }

    static void Grid_CustomizeElement(GridCustomizeElementEventArgs e)
    {
        if (e.ElementType != GridElementType.DataCell) return;

        if (e.Column.Name != nameof(ShippingItem.MeasuredNetWeight) &&
            e.Column.Name != nameof(ShippingItem.MeasuredGrossWeight) &&
            e.Column.Name != nameof(ShippingItem.MeasuredQuantity)) return;

        var isMeasured = (bool)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.IsMeasured));
        if (!isMeasured) return;

        switch (e.Column.Name)
        {
            case nameof(ShippingItem.MeasuredNetWeight) or nameof(ShippingItem.MeasuredGrossWeight):
                {
                    var isMeasurable = (bool)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.IsMeasurable));
                    if (!isMeasurable) return;

                    var valueOnDocument = 0d;
                    var measuredValue = 0d;

                    if (e.Column.Name == nameof(ShippingItem.MeasuredGrossWeight))
                    {
                        valueOnDocument = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.GrossWeightOnDocument));
                        measuredValue = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredGrossWeight));
                    }
                    else
                    {
                        valueOnDocument = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.NetWeightOnDocument));
                        measuredValue = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredNetWeight));
                    }

                    if (valueOnDocument > 0 && valueOnDocument > measuredValue) e.CssClass = "text-danger";
                    else if (valueOnDocument > 0 && valueOnDocument < measuredValue) e.CssClass = "text-success";

                    break;
                }
            case nameof(ShippingItem.MeasuredQuantity):
                {
                    var quantityOnDocument = (int)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.QuantityOnDocument));
                    var measuredQuantity = (int)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredQuantity));

                    if (quantityOnDocument > 0 && quantityOnDocument > measuredQuantity) e.CssClass = "text-danger";
                    //else if (quantityOnDocument <= measuredQuantity) e.CssClass = "text-success";
                    break;
                }
        }
    }

    async Task Grid_FocusedRowChanged(GridFocusedRowChangedEventArgs args)
    {
        if ((args.Grid.IsEditing() || args.Grid.IsEditingNewRow()) && (args.DataItem as IId<int>).Id > 0)
            await args.Grid.SaveChangesAsync();

        if (toolbar != null)
        {
            var shippingItem = (args.DataItem as ShippingItem)!;
            toolbar.EnableDelete = shippingItem.MeasuringStatus == MeasuringStatus.NotStarted;

        }

        FocusedRowVisibleIndex = args.VisibleIndex;
        EditItemsEnabled = true;
    }

    async Task Grid_DataItemDeleting(GridDataItemDeletingEventArgs e)
    {
    }

    async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e)
    {
        ShippingItem? resultShippingItem = null;

        if (!e.IsNew)
        {
            resultShippingItem = await FruitBankSignalRClient.UpdateShippingItem((ShippingItem)e.EditModel);
        }
        else
        {
            resultShippingItem = await FruitBankSignalRClient.AddShippingItem((ShippingItem)e.EditModel);
            EditItemsEnabled = true;
        }

        // if (resultShippingItem != null)
        // 	ShippingItems!.UpdateCollection(resultShippingItem, false);

        EditItemsEnabled = true;
    }
}