@inherits BandGridBase<MassDataReadDto>
@inject IMassDataApiClient Api

@if (!string.IsNullOrWhiteSpace(errorMessage))
{
    <div class="alert alert-danger" role="alert">@errorMessage</div>
}
else if (!string.IsNullOrWhiteSpace(infoMessage))
{
    <div class="alert alert-success" role="alert">@infoMessage</div>
}

@if (!hasLoaded || isLoading)
{
    <div class="loading-container">
        <div class="spinner-border text-primary" role="status">
            <span class="visually-hidden">Lade...</span>
        </div>
    </div>
}
else if (items.Count == 0)
{
    <p>Keine Einträge vorhanden.</p>
}
else
{
    
    <BandEditor Bands="@bandLayout.Bands"
                BandOptions="@bandOptions"
                Columns="@ColumnDefinitions"
                GetColumnBand="GetColumnBand"
                CanSave="@CanSaveBandLayout"
                OnAddBand="AddBand"
                OnSaveLayout="SaveLayoutWithFeedbackAsync"
                OnResetLayout="ResetLayoutWithFeedbackAsync"
                OnRemoveBand="RemoveBand"
                OnBandCaptionChanged="@(args => UpdateBandCaption(args.Band, args.Value))"
                OnColumnBandChanged="@(args => UpdateColumnBand(args.FieldName, args.BandId))" />

    <div class="mb-3 page-size-selector">
        <span class="page-size-label">Datensätze je Seite:</span>
        <DxComboBox Data="@pageSizeOptions"
                    TData="PageSizeOption"
                    TValue="int?"
                    TextFieldName="Text"
                    ValueFieldName="Value"
                    Value="@pageSize"
                    ValueChanged="OnPageSizeChanged"
                    CssClass="page-size-combo" />
    </div>

    <div class="grid-section">
        <DxGrid Data="@items"
                ColumnChooserButtonDisplayMode="GridColumnChooserButtonDisplayMode.Always"
                TItem="MassDataReadDto"
                KeyFieldName="@nameof(MassDataReadDto.Id)"
                SizeMode="@_sizeMode"
                ShowGroupPanel="true"
                ShowGroupedColumns="true"
                AllowGroup="true"
                FilterMenuButtonDisplayMode="GridFilterMenuButtonDisplayMode.Always"
                AllowColumnResize="true"
                ColumnResizeMode="GridColumnResizeMode.ColumnsContainer"
                AllowColumnReorder="true"
                PagerVisible="false"
                PageSize="@(pageSize ?? 100)"
                CssClass="mb-3 massdata-grid"
                EditMode="GridEditMode.PopupEditForm"
                PopupEditFormHeaderText="@popupHeaderText"
                CustomizeEditModel="OnCustomizeEditModel"
                EditModelSaving="OnEditModelSaving"
                DataItemDeleting="OnDataItemDeleting"
                FocusedRowEnabled="true"
                @bind-FocusedRowKey="focusedRowKey"
                RowClick="@(args => _focusedVisibleIndex = args.VisibleIndex)"
                @ref="gridRef">
            <ToolbarTemplate>
                <DxToolbar>
                    <DxToolbarItem Alignment="ToolbarItemAlignment.Left">
                        <Template Context="_">
                            <DxButton IconCssClass="bi bi-plus-lg"
                                      RenderStyle="ButtonRenderStyle.Secondary"
                                      RenderStyleMode="ButtonRenderStyleMode.Text"
                                      Click="@(() => gridRef!.StartEditNewRowAsync())" />
                        </Template>
                    </DxToolbarItem>
                    <DxToolbarItem Alignment="ToolbarItemAlignment.Left">
                        <Template Context="_">
                            <DxButton IconCssClass="bi bi-pencil"
                                      RenderStyle="ButtonRenderStyle.Secondary"
                                      RenderStyleMode="ButtonRenderStyleMode.Text"
                                      Click="EditFocusedRow" />
                        </Template>
                    </DxToolbarItem>
                    <DxToolbarItem Alignment="ToolbarItemAlignment.Left">
                        <Template Context="_">
                            <DxButton IconCssClass="bi bi-trash"
                                      RenderStyle="ButtonRenderStyle.Secondary"
                                      RenderStyleMode="ButtonRenderStyleMode.Text"
                                      Click="DeleteFocusedRow" />
                        </Template>
                    </DxToolbarItem>
                    <DxToolbarItem Alignment="ToolbarItemAlignment.Right">
                        <Template Context="_">
                            <DxButton Text="Spalten"
                                      RenderStyle="ButtonRenderStyle.Secondary"
                                      RenderStyleMode="ButtonRenderStyleMode.Text"
                                      Click="@(() => gridRef!.ShowColumnChooser())" />
                        </Template>
                    </DxToolbarItem>
                    <DxToolbarItem Alignment="ToolbarItemAlignment.Right">
                        <Template Context="_">
                            <DxDropDownButton Text="@FormatSizeText(_sizeMode)"
                                              RenderStyle="ButtonRenderStyle.Secondary"
                                              RenderStyleMode="ButtonRenderStyleMode.Text"
                                              ItemClick="OnSizeChange">
                                <Items>
                                    @foreach (var size in _sizeModes)
                                    {
                                        <DxDropDownButtonItem Text="@FormatSizeText(size)" Id="@size.ToString()" />
                                    }
                                </Items>
                            </DxDropDownButton>
                        </Template>
                    </DxToolbarItem>
                </DxToolbar>
            </ToolbarTemplate>
            <Columns>
                @RenderColumns()
            </Columns>
            <EditFormTemplate Context="editFormContext">
                @{
                    SetEditContext(editFormContext.EditContext); var editModel = (MassDataEditModel)editFormContext.EditModel; SetPopupHeaderText(editModel.IsNew);
                }
                <DxFormLayout ColCount="2">
                    <DxFormLayoutItem Caption="CustomerName">
                        <DxTextBox @bind-Text="editModel.CustomerName" Width="100%" />
                    </DxFormLayoutItem>
                    <DxFormLayoutItem Caption="Amount">
                        <DxTextBox @bind-Text="editModel.AmountText" Width="100%" />
                    </DxFormLayoutItem>
                    <DxFormLayoutItem Caption="Category">
                        <DxTextBox @bind-Text="editModel.Category" Width="100%" ReadOnly="@(!editModel.IsNew)" />
                    </DxFormLayoutItem>
                    <DxFormLayoutItem Caption="Status">
                        <DxCheckBox @bind-Checked="editModel.StatusFlag" ReadOnly="@(!editModel.IsNew)" />
                    </DxFormLayoutItem>
                    @if (!editModel.IsNew)
                    {
                        <DxFormLayoutItem Caption="Prozedur">
                            <DxComboBox Data="@procedureOptions"
                                        TData="ProcedureOption"
                                        TValue="int"
                                        TextFieldName="Text"
                                        ValueFieldName="Value"
                                        @bind-Value="editModel.UpdateProcedure"
                                        Width="100%" />
                        </DxFormLayoutItem>
                    }
                    <DxFormLayoutItem ColSpanMd="12">
                        <ValidationSummary />
                    </DxFormLayoutItem>
                </DxFormLayout>
            </EditFormTemplate>
        </DxGrid>

        @if (pageCount > 1)
        {
            <div class="pager-container">
                <DxPager PageCount="@pageCount" ActivePageIndex="@pageIndex" ActivePageIndexChanged="OnPageChanged" />
            </div>
        }
    </div>
}

@code {
    private List<MassDataReadDto> items = new();
    private int pageIndex;
    private int pageCount = 1;
    private int? pageSize = 100;
    private int? focusedRowKey;

    protected override string LayoutKey => "MassDataGrid";
    protected override bool ShowCommandColumn => false;

    protected override List<ColumnDefinition> ColumnDefinitions { get; } = new()
{
    new() { FieldName = nameof(MassDataReadDto.Id),           Caption = "Id",           Width = "90px", ReadOnly = true, FilterType = ColumnFilterType.Text },
    new() { FieldName = nameof(MassDataReadDto.CustomerName), Caption = "CustomerName",                 FilterType = ColumnFilterType.Text },
    new() { FieldName = nameof(MassDataReadDto.Amount),       Caption = "Amount",       DisplayFormat = "c2", FilterType = ColumnFilterType.Text },
    new() { FieldName = nameof(MassDataReadDto.Category),     Caption = "Category",     ReadOnly = true, FilterType = ColumnFilterType.Text },
    new() { FieldName = nameof(MassDataReadDto.StatusFlag),   Caption = "Status",       ReadOnly = true, FilterType = ColumnFilterType.Bool },
    new() { FieldName = nameof(MassDataReadDto.AddedWhen),    Caption = "Added",        ReadOnly = true, FilterType = ColumnFilterType.Date },
    new() { FieldName = nameof(MassDataReadDto.ChangedWhen),  Caption = "Changed",      ReadOnly = true, FilterType = ColumnFilterType.Date }
};

    private readonly List<PageSizeOption> pageSizeOptions = new()
    {
        new() { Value = 100,    Text = "100" },
        new() { Value = 1000,   Text = "1.000" },
        new() { Value = 10000,  Text = "10.000" },
        new() { Value = 100000, Text = "100.000" },
        new() { Value = null,   Text = "Alle" }
    };

    private readonly List<ProcedureOption> procedureOptions = new()
    {
        new() { Value = 0, Text = "PRMassdata_UpsertByCustomerName" }
    };

    protected override async Task OnInitializedAsync()
    {
        await InitializeBandLayoutAsync();
        await LoadPage(0);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await ApplyGridLayoutAfterRenderAsync();
    }

    private async Task LoadPage(int page)
    {
        isLoading = true;
        errorMessage = null;
        try
        {
            var total = await Api.GetCountAsync();
            var effectivePageSize = pageSize ?? (total == 0 ? 1 : total);
            pageCount = Math.Max(1, (int)Math.Ceiling(total / (double)effectivePageSize));
            pageIndex = Math.Clamp(page, 0, pageCount - 1);
            var skip = pageSize.HasValue ? pageIndex * pageSize.Value : 0;
            items = await Api.GetAllAsync(skip, pageSize);
        }
        catch (Exception ex)
        {
            errorMessage = $"MassData konnten nicht geladen werden: {ex.Message}";
        }
        finally
        {
            isLoading = false;
            hasLoaded = true;
            StateHasChanged();
        }
    }

    private async Task OnPageChanged(int index) => await LoadPage(index);

    private async Task OnPageSizeChanged(int? size)
    {
        pageSize = size;
        await LoadPage(0);
    }

    protected override void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
    {
        if (validationMessageStore == null || editContext == null) return;
        if (e.FieldIdentifier.FieldName == nameof(MassDataEditModel.UpdateProcedure))
        {
            validationMessageStore.Clear();
            editContext.NotifyValidationStateChanged();
            return;
        }
        if (e.FieldIdentifier.FieldName == nameof(MassDataEditModel.CustomerName))
        {
            validationMessageStore.Clear(new FieldIdentifier(editContext.Model, nameof(MassDataEditModel.CustomerName)));
            editContext.NotifyValidationStateChanged();
        }
    }

    private void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e)
    {
        if (e.IsNew)
        {
            e.EditModel = new MassDataEditModel { IsNew = true, UpdateProcedure = procedureOptions[0].Value };
            SetPopupHeaderText(true);
            return;
        }
        var item = (MassDataReadDto)e.DataItem;
        e.EditModel = new MassDataEditModel
        {
            Id = item.Id,
            CustomerName = item.CustomerName,
            AmountText = item.Amount.ToString("0.00"),
            Category = item.Category,
            StatusFlag = item.StatusFlag,
            UpdateProcedure = procedureOptions[0].Value,
            IsNew = false,
            OriginalCustomerName = item.CustomerName
        };
        SetPopupHeaderText(false);
    }

    private async Task OnEditModelSaving(GridEditModelSavingEventArgs e)
    {
        errorMessage = null;
        infoMessage = null;
        validationMessageStore?.Clear();
        editContext?.NotifyValidationStateChanged();
        var editModel = (MassDataEditModel)e.EditModel;
        if (!decimal.TryParse(editModel.AmountText, out var amount))
        {
            AddValidationError(editModel, nameof(MassDataEditModel.AmountText), "Amount ist ungültig.");
            e.Cancel = true;
            return;
        }
        if (editModel.IsNew)
        {
            var existing = await Api.GetByCustomerNameAsync(editModel.CustomerName);
            if (existing != null)
            {
                AddValidationError(editModel, nameof(MassDataEditModel.CustomerName), "Kunde existiert bereits.");
                e.Cancel = true;
                return;
            }
        }
        var dto = new MassDataWriteDto
        {
            CustomerName = editModel.CustomerName,
            Amount = amount,
            Category = editModel.Category,
            StatusFlag = editModel.StatusFlag
        };

        var result = await Api.UpsertAsync(dto);
        if (!result.Success)
        {
            errorMessage = result.Error ?? "Speichern fehlgeschlagen.";
            e.Cancel = true;
            return;
        }
        infoMessage = editModel.IsNew ? "MassData angelegt." : "MassData aktualisiert.";
        focusedRowKey = result.Value?.Id;
        await LoadPage(pageIndex);
    }

    private void AddValidationError(MassDataEditModel editModel, string fieldName, string message)
    {
        if (editContext == null || validationMessageStore == null) return;
        validationMessageStore.Add(new FieldIdentifier(editModel, fieldName), message);
        editContext.NotifyValidationStateChanged();
    }

    private Task OnDataItemDeleting(GridDataItemDeletingEventArgs e)
    {
        errorMessage = null;
        infoMessage = "Löschen ist aktuell noch nicht verfügbar.";
        e.Cancel = true;
        return Task.CompletedTask;
    }

    private sealed class MassDataEditModel
    {
        public int Id { get; set; }
        public string CustomerName { get; set; } = string.Empty;
        public string AmountText { get; set; } = string.Empty;
        public string Category { get; set; } = string.Empty;
        public bool StatusFlag { get; set; }
        public int UpdateProcedure { get; set; }
        public bool IsNew { get; set; }
        public string OriginalCustomerName { get; set; } = string.Empty;
    }

    private sealed class ProcedureOption
    {
        public int Value { get; set; }
        public string Text { get; set; } = string.Empty;
    }

    private sealed class PageSizeOption
    {
        public int? Value { get; set; }
        public string Text { get; set; } = string.Empty;
    }
}