@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.JSInterop
@using System.IO
@using Radzen.Documents.Spreadsheet
@inject IJSRuntime JSRuntime

<RadzenStack Gap="1rem">
    <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="1rem">
        <RadzenButton ButtonStyle="ButtonStyle.Base" Icon="upload_file" class="rz-fileupload-choose">
            <InputFile OnChange=@OnImportAsync accept=".xlsx" />
            <span class="rz-button-text">Import XLSX</span>
        </RadzenButton>
        <RadzenButton Icon="download" Text="Download XLSX" ButtonStyle="ButtonStyle.Primary"
            Click=@DownloadXlsx />
    </RadzenStack>

    <RadzenAlert AlertStyle="AlertStyle.Info" Variant="Variant.Flat" AllowClose="false">
        @status
    </RadzenAlert>

    @if (rows.Count > 0)
    {
        <RadzenTable>
            <RadzenTableHeader>
                <RadzenTableHeaderRow>
                    @foreach (var headerCell in rows[0])
                    {
                        <RadzenTableHeaderCell>@headerCell</RadzenTableHeaderCell>
                    }
                </RadzenTableHeaderRow>
            </RadzenTableHeader>
            <RadzenTableBody>
                @for (var r = 1; r < Math.Min(rows.Count, 25); r++)
                {
                    var row = rows[r];
                    <RadzenTableRow>
                        @foreach (var cell in row)
                        {
                            <RadzenTableCell>@cell</RadzenTableCell>
                        }
                    </RadzenTableRow>
                }
            </RadzenTableBody>
        </RadzenTable>
        @if (rows.Count > 25)
        {
            <RadzenText TextStyle="TextStyle.Caption">
                Showing first 25 rows of @rows.Count.
            </RadzenText>
        }
    }
</RadzenStack>

@code {
    Workbook workbook = BuildSampleWorkbook();
    List<List<string>> rows = new();
    string status = "Showing the pre-built sample workbook. Click Import XLSX to load your own file, or Download XLSX to save the current workbook.";

    protected override void OnInitialized()
    {
        Render(workbook);
    }

    static Workbook BuildSampleWorkbook()
    {
        var wb = new Workbook();
        var sheet = wb.AddSheet("Sales", 11, 5);
        sheet.BeginUpdate();

        var headerFormat = new Format { Bold = true, BackgroundColor = "#305496", Color = "#ffffff", TextAlign = TextAlign.Center };
        var currencyFormat = new Format { NumberFormat = "$#,##0.00" };

        sheet.Columns[0] = 110; sheet.Columns[1] = 130;
        for (var c = 2; c < 5; c++) sheet.Columns[c] = 110;

        string[] headers = { "Region", "Product", "Q1", "Q2", "Total" };
        for (var c = 0; c < headers.Length; c++)
        {
            sheet.Cells[0, c].Value = headers[c];
            sheet.Cells[0, c].Format = headerFormat;
        }

        var data = new (string Region, string Product, double Q1, double Q2)[]
        {
            ("EMEA", "Laptop Pro", 45200, 52100),
            ("EMEA", "Ultra Monitor", 18500, 21300),
            ("EMEA", "Ergo Keyboard", 8200, 7600),
            ("AMER", "Wireless Mouse", 5400, 6100),
            ("AMER", "Noise Headset", 12300, 14500),
            ("AMER", "USB Dock", 22100, 25400),
            ("APAC", "Office Chair", 15800, 17200),
            ("APAC", "Standing Desk", 28500, 31200),
            ("APAC", "Webcam Pro", 9800, 10750),
            ("APAC", "Cable Organizer", 3200, 3450),
        };
        for (var i = 0; i < data.Length; i++)
        {
            var r = i + 1;
            sheet.Cells[r, 0].Value = data[i].Region;
            sheet.Cells[r, 1].Value = data[i].Product;
            sheet.Cells[r, 2].Value = data[i].Q1; sheet.Cells[r, 2].Format = currencyFormat;
            sheet.Cells[r, 3].Value = data[i].Q2; sheet.Cells[r, 3].Format = currencyFormat;
            sheet.Cells[r, 4].Formula = $"=C{r + 1}+D{r + 1}";
            sheet.Cells[r, 4].Format = new Format { Bold = true, NumberFormat = "$#,##0.00" };
        }
        sheet.Rows.Frozen = 1;
        sheet.EndUpdate();
        return wb;
    }

    void Render(Workbook wb)
    {
        rows.Clear();
        var sheet = wb.Sheets[0];
        for (var r = 0; r < sheet.RowCount; r++)
        {
            var row = new List<string>();
            var hasContent = false;
            for (var c = 0; c < sheet.ColumnCount; c++)
            {
                var cell = sheet.Cells[r, c];
                var text = cell.GetValueAsString() ?? "";
                if (!string.IsNullOrEmpty(text)) hasContent = true;
                row.Add(text);
            }
            if (hasContent) rows.Add(row);
        }
    }

    async Task OnImportAsync(InputFileChangeEventArgs args)
    {
        var file = args.File;
        if (file is null) return;

        using var ms = new MemoryStream();
        await file.OpenReadStream(maxAllowedSize: 10 * 1024 * 1024).CopyToAsync(ms);
        ms.Position = 0;

        workbook = Workbook.LoadFromStream(ms);
        Render(workbook);
        status = $"Imported {file.Name}: {rows.Count} populated rows across {workbook.Sheets.Count} sheet(s).";
    }

    async Task DownloadXlsx()
    {
        using var ms = new MemoryStream();
        workbook.SaveToStream(ms);
        ms.Position = 0;
        using var streamRef = new DotNetStreamReference(ms);
        await JSRuntime.InvokeVoidAsync("Radzen.downloadFile", "sales.xlsx", streamRef);
    }
}
