using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using Indotalent.Features.Sales.SalesOrder.Cqrs;

namespace Indotalent.Features.Sales.SalesOrder;

public class SalesOrderPdfGenerator
{
    public static byte[] Generate(GetSalesOrderByIdResponse data)
    {
        QuestPDF.Settings.License = LicenseType.Community;

        var primaryBlue = "#0D47A1";
        var textSlate = "#64748b";

        return Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(1.5f, Unit.Centimetre);
                page.PageColor(Colors.White);
                page.DefaultTextStyle(x => x.FontSize(9).FontFamily(Fonts.Verdana));

                page.Header().Row(row =>
                {
                    row.RelativeItem().Column(col =>
                    {
                        col.Item().Text("SALES ORDER")
                            .FontSize(20).ExtraBold().FontColor(primaryBlue);
                        col.Item().Text($"{data.AutoNumber}").FontSize(11).SemiBold();
                    });

                    row.RelativeItem().AlignRight().Column(col =>
                    {
                        col.Item().Text(data.CompanyName).FontSize(11).ExtraBold();
                        col.Item().Text($"{data.CompanyStreet}").FontColor(textSlate);
                        col.Item().Text($"{data.CompanyCity}, {data.CompanyState} {data.CompanyZipCode}").FontColor(textSlate);
                        col.Item().Text($"Tel: {data.CompanyPhone} | Email: {data.CompanyEmail}").FontColor(textSlate);
                    });
                });

                page.Content().PaddingVertical(20).Column(col =>
                {
                    col.Item().Row(row =>
                    {
                        row.RelativeItem().Column(c =>
                        {
                            c.Item().BorderBottom(1).PaddingBottom(5).Text("FROM (COMPANY)").FontSize(8).Bold().FontColor(textSlate);
                            c.Item().PaddingTop(5).Text(data.CompanyName).Bold();
                            c.Item().Text(data.CompanyStreet);
                            c.Item().Text($"{data.CompanyCity}, {data.CompanyState} {data.CompanyZipCode}");
                            c.Item().Text($"Tel: {data.CompanyPhone}");
                            c.Item().Text($"Email: {data.CompanyEmail}");
                        });

                        row.ConstantItem(40);

                        row.RelativeItem().Column(c =>
                        {
                            c.Item().BorderBottom(1).PaddingBottom(5).Text("TO (CUSTOMER)").FontSize(8).Bold().FontColor(textSlate);
                            c.Item().PaddingTop(5).Text(data.CustomerName).Bold();
                            c.Item().Text(data.CustomerStreet);
                            c.Item().Text($"{data.CustomerCity}, {data.CustomerState} {data.CustomerZipCode}");
                            c.Item().Text($"Tel: {data.CustomerPhone}");
                            c.Item().Text($"Email: {data.CustomerEmail}");
                        });
                    });

                    col.Item().PaddingTop(20).Table(table =>
                    {
                        table.ColumnsDefinition(columns =>
                        {
                            columns.ConstantColumn(25);
                            columns.RelativeColumn(4);
                            columns.RelativeColumn(2);
                            columns.RelativeColumn(1.5f);
                            columns.RelativeColumn(2.5f);
                        });

                        table.Header(header =>
                        {
                            header.Cell().Element(HeaderStyle).Text("#");
                            header.Cell().Element(HeaderStyle).Text("Product Description");
                            header.Cell().Element(HeaderStyle).AlignRight().Text("Unit Price");
                            header.Cell().Element(HeaderStyle).AlignCenter().Text("Qty");
                            header.Cell().Element(HeaderStyle).AlignRight().Text($"Total ({data.CurrencySymbol})");

                            static IContainer HeaderStyle(IContainer container)
                            {
                                return container.DefaultTextStyle(x => x.SemiBold().FontColor(Colors.White))
                                                .PaddingVertical(5).PaddingHorizontal(5).Background("#0D47A1");
                            }
                        });

                        var index = 1;
                        foreach (var item in data.Items)
                        {
                            table.Cell().Element(CellStyle).Text($"{index++}");
                            table.Cell().Element(CellStyle).Column(c => {
                                c.Item().Text(item.ProductName).Bold();
                                if (!string.IsNullOrEmpty(item.Summary)) c.Item().Text(item.Summary).FontSize(8).FontColor(textSlate);
                            });
                            table.Cell().Element(CellStyle).AlignRight().Text(item.UnitPrice?.ToString("N2"));
                            table.Cell().Element(CellStyle).AlignCenter().Text(item.Quantity?.ToString());
                            table.Cell().Element(CellStyle).AlignRight().Text(item.Total?.ToString("N2"));

                            static IContainer CellStyle(IContainer container)
                            {
                                return container.BorderBottom(1).BorderColor("#E2E8F0").PaddingVertical(8).PaddingHorizontal(5);
                            }
                        }
                    });

                    col.Item().PaddingTop(10).Row(row =>
                    {
                        row.RelativeItem().Column(c => {
                            c.Item().Text("Notes:").FontSize(8).Bold();
                            c.Item().Text(string.IsNullOrEmpty(data.Description) ? "-" : data.Description).FontSize(8);
                            c.Item().PaddingTop(10).Text($"Date: {data.OrderDate?.ToString("dd MMM yyyy")}").FontSize(9);
                            c.Item().Text($"Status: {data.OrderStatus.ToString().ToUpper()}").FontSize(9).Bold().FontColor(primaryBlue);
                        });
                        row.ConstantItem(200).Column(c =>
                        {
                            c.Item().Row(r => {
                                r.RelativeItem().Text("Sub Total");
                                r.RelativeItem().AlignRight().Text(data.BeforeTaxAmount?.ToString("N2"));
                            });
                            c.Item().Row(r => {
                                r.RelativeItem().Text("Tax Amount");
                                r.RelativeItem().AlignRight().Text(data.TaxAmount?.ToString("N2"));
                            });
                            c.Item().PaddingTop(5).BorderTop(1).Row(r => {
                                r.RelativeItem().Text($"TOTAL ({data.CurrencySymbol})").Bold();
                                r.RelativeItem().AlignRight().Text(data.AfterTaxAmount?.ToString("N2")).ExtraBold().FontColor(primaryBlue);
                            });
                        });
                    });
                });

                page.Footer().AlignCenter().Text(x =>
                {
                    x.Span("Page ").FontSize(8);
                    x.CurrentPageNumber().FontSize(8);
                    x.Span(" of ").FontSize(8);
                    x.TotalPages().FontSize(8);
                });
            });
        }).GeneratePdf();
    }
}