using GestionIntegral.Api.Dtos.Reportes.ViewModels;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using System.Globalization;
using System.Linq;

namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
{
    public class ListadoDistCanMensualDocument : IDocument
    {
        public ListadoDistCanMensualViewModel Model { get; }
        private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");

        public ListadoDistCanMensualDocument(ListadoDistCanMensualViewModel model)
        {
            Model = model;
        }

        public DocumentMetadata GetMetadata() => DocumentMetadata.Default;

        public void Compose(IDocumentContainer container)
        {
            container.Page(page =>
            {
                page.Margin(1.5f, Unit.Centimetre);
                page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
                
                page.Header().Element(ComposeHeader);
                page.Content().Element(ComposeContent);
                page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
            });
        }

        void ComposeHeader(IContainer container)
        {
            container.Column(column =>
            {
                column.Item().AlignCenter().Text("Listado de Distribución Mensual").SemiBold().FontSize(14);
                column.Item().AlignCenter().Text(Model.TipoDestinatario).FontSize(12);

                column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
                {
                    row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
                    row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
                });
            });
        }
        
        void ComposeContent(IContainer container)
        {
            container.PaddingTop(1, Unit.Centimetre).Column(column =>
            {
                column.Spacing(10);
                
                // Agrupamos los datos por Canilla
                var gruposPorCanilla = Model.Detalles.GroupBy(d => d.Canilla);

                // Creamos una tabla principal que contendrá todo
                column.Item().Table(table =>
                {
                    table.ColumnsDefinition(columns =>
                    {
                        columns.RelativeColumn(2.5f); // Canilla / Publicación
                        columns.RelativeColumn();     // Llevados
                        columns.RelativeColumn();     // Devueltos
                        columns.RelativeColumn(1.2f); // Importe
                    });

                    // Encabezado principal de la tabla
                    table.Header(header =>
                    {
                        header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).Text("Canilla / Publicación").SemiBold();
                        header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Llevados").SemiBold();
                        header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Devueltos").SemiBold();
                        header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Importe").SemiBold();
                    });

                    // Iteramos sobre cada grupo de canilla
                    foreach (var grupo in gruposPorCanilla)
                    {
                        // Fila del nombre del Canilla
                        table.Cell().ColumnSpan(4).PaddingTop(8).Text(grupo.Key).SemiBold();
                        
                        // Filas de detalle para ese canilla
                        foreach (var detalle in grupo)
                        {
                            table.Cell().PaddingLeft(15).Padding(2).Text(detalle.Publicacion);
                            table.Cell().Padding(2).AlignRight().Text(detalle.TotalCantSalida?.ToString("N0") ?? "0");
                            table.Cell().Padding(2).AlignRight().Text(detalle.TotalCantEntrada?.ToString("N0") ?? "0");
                            table.Cell().Padding(2).AlignRight().Text(detalle.TotalRendir?.ToString("C", CultureAr) ?? "$ 0.00");
                        }
                        
                        // Fila de total por canilla
                        var totalRendirCanilla = grupo.Sum(d => d.TotalRendir ?? 0);
                        table.Cell().ColumnSpan(3).BorderTop(1.5f).BorderColor(Colors.Black).AlignRight().Padding(2).Text("A Rendir").SemiBold();
                        table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).AlignRight().Padding(2).Text(t => t.Span(totalRendirCanilla.ToString("C", CultureAr)).SemiBold());
                    }

                    // --- Fila de TOTALES GENERALES ---
                    var totalGeneralLlevados = Model.Detalles.Sum(d => d.TotalCantSalida ?? 0);
                    var totalGeneralDevueltos = Model.Detalles.Sum(d => d.TotalCantEntrada ?? 0);
                    var totalGeneralRendir = Model.Detalles.Sum(d => d.TotalRendir ?? 0);

                    table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).Text("TOTALES").ExtraBold();
                    table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralLlevados.ToString("N0")).ExtraBold());
                    table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralDevueltos.ToString("N0")).ExtraBold());
                    table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralRendir.ToString("C", CultureAr)).ExtraBold());
                });
            });
        }
    }
}