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

namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
{
    public class DistribucionSuscripcionesDocument : IDocument
    {
        public DistribucionSuscripcionesViewModel Model { get; }

        public DistribucionSuscripcionesDocument(DistribucionSuscripcionesViewModel model)
        {
            Model = model;
        }

        public DocumentMetadata GetMetadata() => DocumentMetadata.Default;

        public void Compose(IDocumentContainer container)
        {
            container.Page(page =>
            {
                page.Margin(1, Unit.Centimetre);
                page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
                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().Row(row =>
                {
                    row.RelativeItem().Column(col =>
                    {
                        col.Item().Text("Reporte de Distribución de Suscripciones").SemiBold().FontSize(14);
                        col.Item().Text($"Período: {Model.FechaDesde} al {Model.FechaHasta}").FontSize(11);
                    });
                    row.ConstantItem(150).AlignRight().Text($"Generado: {Model.FechaGeneracion}");
                });
                column.Item().PaddingTop(5).BorderBottom(1).BorderColor(Colors.Grey.Lighten2);
            });
        }

        void ComposeContent(IContainer container)
        {
            container.PaddingTop(10).Column(column =>
            {
                column.Spacing(20); // Espacio entre elementos principales (sección de altas y sección de bajas)

                // --- Sección 1: Altas y Activas ---
                column.Item().Column(colAltas =>
                {
                    colAltas.Item().Text("Altas y Suscripciones Activas en el Período").Bold().FontSize(14).Underline();
                    colAltas.Item().PaddingBottom(10).Text("Listado de suscriptores que deben recibir entregas en el período seleccionado.");

                    if (!Model.DatosAgrupadosAltas.Any())
                    {
                        colAltas.Item().PaddingTop(10).Text("No se encontraron suscripciones activas para este período.").Italic();
                    }
                    else
                    {
                        foreach (var empresa in Model.DatosAgrupadosAltas)
                        {
                            colAltas.Item().Element(c => ComposeTablaEmpresa(c, empresa, esBaja: false));
                        }
                    }
                });
                
                // --- Sección 2: Bajas ---
                if (Model.DatosAgrupadosBajas.Any())
                {
                    column.Item().PageBreak(); // Salto de página para separar las secciones
                    column.Item().Column(colBajas =>
                    {
                        colBajas.Item().Text("Bajas de Suscripciones en el Período").Bold().FontSize(14).Underline().FontColor(Colors.Red.Medium);
                        colBajas.Item().PaddingBottom(10).Text("Listado de suscriptores cuya suscripción finalizó. NO se les debe entregar a partir de su 'Fecha de Baja'.");

                        foreach (var empresa in Model.DatosAgrupadosBajas)
                        {
                            colBajas.Item().Element(c => ComposeTablaEmpresa(c, empresa, esBaja: true));
                        }
                    });
                }
            });
        }

        void ComposeTablaEmpresa(IContainer container, GrupoEmpresa empresa, bool esBaja)
        {
            container.Column(column =>
            {
                // Cabecera de la EMPRESA (ej. EL DIA)
                column.Item().Background(Colors.Grey.Lighten2).Padding(5).Text(empresa.NombreEmpresa).Bold().FontSize(12);
                
                // Contenedor para las tablas de las publicaciones de esta empresa
                column.Item().PaddingTop(5).Column(colPub =>
                {
                    colPub.Spacing(10); // Espacio entre cada tabla de publicación
                    foreach (var publicacion in empresa.Publicaciones)
                    {
                        colPub.Item().Element(c => ComposeTablaPublicacion(c, publicacion, esBaja));
                    }
                });
            });
        }

        void ComposeTablaPublicacion(IContainer container, GrupoPublicacion publicacion, bool esBaja)
        {
            // Se envuelve la tabla en una columna para poder ponerle un título simple arriba.
            container.Column(column =>
            {
                column.Item().PaddingLeft(2).PaddingBottom(2).Text(publicacion.NombrePublicacion).SemiBold().FontSize(10);
                column.Item().Table(table =>
                {
                    table.ColumnsDefinition(columns =>
                    {
                        columns.RelativeColumn(2.5f); // Nombre
                        columns.RelativeColumn(3);   // Dirección
                        columns.RelativeColumn(1.5f); // Teléfono
                        columns.ConstantColumn(65);  // Fecha Inicio / Baja
                        columns.RelativeColumn(1.5f); // Días
                        columns.RelativeColumn(2.5f); // Observaciones
                    });

                    table.Header(header =>
                    {
                        header.Cell().BorderBottom(1).Padding(2).Text("Suscriptor").SemiBold();
                        header.Cell().BorderBottom(1).Padding(2).Text("Dirección").SemiBold();
                        header.Cell().BorderBottom(1).Padding(2).Text("Teléfono").SemiBold();
                        header.Cell().BorderBottom(1).Padding(2).Text(esBaja ? "Fecha de Baja" : "Fecha Inicio").SemiBold();
                        header.Cell().BorderBottom(1).Padding(2).Text("Días Entrega").SemiBold();
                        header.Cell().BorderBottom(1).Padding(2).Text("Observaciones").SemiBold();
                    });

                    foreach (var item in publicacion.Suscripciones)
                    {
                        table.Cell().Padding(2).Text(item.NombreSuscriptor);
                        table.Cell().Padding(2).Text(item.Direccion);
                        table.Cell().Padding(2).Text(item.Telefono ?? "-");
                        var fecha = esBaja ? item.FechaFin : item.FechaInicio;
                        table.Cell().Padding(2).Text(fecha?.ToString("dd/MM/yyyy") ?? "-");                        
                        table.Cell().Padding(2).Text(item.DiasEntrega);
                        table.Cell().Padding(2).Text(item.Observaciones ?? "-");
                    }
                });
            });
        }
    }
}