/*
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC.
 */

using Syncfusion.XlsIO;
using Syncfusion.Maui.DataGrid.Exporting;

using DXLib.Email;
using DXLib.Utils;

namespace iStatVball3;

/*
 * Exports a stats analysis report to Excel (.xls) format and sends it as an email attachment. ONLY exports grids, not
 * graphs or charts.
 */
public class ExcelExporter : Exporter
{
    /* Constants */
    private const string FilePrefix = "istatvball3";
    private const string FileExt = "xls";
    private const string FileType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    /* Fields */
    private Grid grid;

    /* Methods */

    // Creates Excel document then sends via email
    public async Task<DXEmail.Result> Export( ExportConfig config )
    {
        ExcelEngine engine = new();
        DataGridExcelExportingController controller = new();

        // Register for callbacks
        controller.CellExporting += OnCellExporting;

        int count = config.Cards.Count;

        // Create Excel workbook
        IWorkbook workbook = engine.Excel.Workbooks.Create( count );

        bool hasGrid = false;
        
        // Export each report
        for ( int i = 0; i < count; i++ )
        {
            ReportCard card = config.Cards[i];

            // Grids only
            if ( card.Type == AnalyzeKeys.GridKey )
            {
                hasGrid = true;
                
                if ( card is GridCard gridCard )
                {
                    grid = gridCard.Grid;

                    // Separate tab for each grid
                    IWorksheet worksheet = workbook.Worksheets[i];
                    worksheet.Name = card.Title;

                    // Configuration
                    DataGridExcelExportingOption options = new()
                    {
                        CanExportStackedHeaders = true,
                        CanExportHeader = true,

                        ExportMode = ExportMode.Text,
                        CanExportAllPages = true,
                        CanExportUnboundRows = true,
                        CanExportRowHeight = true,
                        CanExportColumnWidth = true,

                        CanAllowOutlining = false,
                        CanAllowSortingAndFiltering = true,

                        CanApplyGridStyle = false
                    };

                    // Export
                    controller.ExportToExcel( grid, grid.View!, options, worksheet );
                }
            }
        }

        // May not have any grids
        if ( hasGrid )
        {
            MemoryStream stream = new();

            // Write to file
            workbook.SaveAs( stream );
            workbook.Close();

            engine.Dispose();

            // Convert to raw data
            byte[] excel = stream.ToArray();

            // Configure email
            DXEmailConfig emailConfig = new()
            {
                // Local/remote
                IsLocal = config.IsLocal,

                // From:
                FromAddress = config.FromAddress,
                FromName = config.FromName,

                // To:
                ToAddresses = config.ToAddresses,
                ToNames = config.ToNames,

                // Local use only
                Subject = config.Subject,
                Body = DXString.Get( "export.body", config.Title ),

                // Template
                TemplateId = "d-0920a5e640724679b1cd3aab86f278b5",
                TemplateData = config,

                // Attachment
                FileRaw = excel,
                FileName = CreateFilename( config ),
                FileData = DXUtils.ToBase64( excel ),
                FileType = FileType
            };
            
            // Async email send
            DXEmail.Result result = await DXEmail.Send( emailConfig );

            return result;
        }

        return DXEmail.Result.Error;
    }

    // Generates canonical filename for export file
    private static string CreateFilename( ExportConfig config )
    {
        string dateStr = DXUtils.FilenameFromDate( config.Date );

        // 'istatvball3_hitting_team_241025.pdf'
        string fullName = $"{FilePrefix}_{config.Title}_{config.Team}_{dateStr}.{FileExt}";
        string filename = DXUtils.ToFilename( fullName );

        return filename;
    }

    /* Event Callbacks */

    // Required workaround for unbound row formatting
    private void OnCellExporting( object sender, DataGridCellExcelExportingEventArgs args )
    {
        // Totals row
        if ( args.CellType == ExportCellType.FixedBottomUnboundCell )
        {
            string key = args.ColumnName;
            JsonColumn column = grid.Json.GetColumn( key );

            if ( column != null )
            {
                string type = column.Type;
                string value = args.CellValue.ToString();

                if ( value != null )
                {
                    // Must manually set format for totals cells
                    switch ( type )
                    {
                        // '1,000'
                        case AnalyzeKeys.IntKey:
                        {
                            args.CellValue = float.Parse( value ).ToString( "N0" );
                            break;
                        }
                        // '5.0', '0.300', '35.0%'
                        case AnalyzeKeys.FloatKey:
                        case AnalyzeKeys.FixedKey:
                        case AnalyzeKeys.PercentKey:
                        {
                            string format = Grid.GetNumericFormat( column.Type );

                            args.CellValue = float.Parse( value ).ToString( format );
                            break;
                        }
                    }
                }
            }
        }
    }
}

//
