using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using SportsDivision.Application.DTOs.ReportDtos;

namespace SportsDivision.Web.Reports;

public class ScoresByEventDocument : IDocument
{
    private readonly IEnumerable<ScoresByEventReportDto> _data;
    private readonly string _tournamentName;

    private static readonly string HeaderColor = "#003366";
    private static readonly Color AltRowColor = Color.FromHex("#F5F5F5");
    private static readonly string ReportTitle = "Scores by Event Report";

    public ScoresByEventDocument(IEnumerable<ScoresByEventReportDto> data, string tournamentName)
    {
        _data = data;
        _tournamentName = tournamentName;
    }

    public DocumentMetadata GetMetadata() => DocumentMetadata.Default;

    public void Compose(IDocumentContainer container)
    {
        container.Page(page =>
        {
            page.Size(PageSizes.A4);
            page.Margin(30);

            page.Header().Element(ComposeHeader);
            page.Content().Element(ComposeContent);
            page.Footer().Element(ComposeFooter);
        });
    }

    private void ComposeHeader(IContainer container)
    {
        container.Column(column =>
        {
            column.Item().AlignCenter().Text("Dominica Sports Division")
                .FontSize(18).Bold().FontColor(HeaderColor);

            column.Item().AlignCenter().Text(_tournamentName)
                .FontSize(14).SemiBold();

            column.Item().AlignCenter().Text(ReportTitle)
                .FontSize(12);

            column.Item().PaddingVertical(5).LineHorizontal(1).LineColor(HeaderColor);
        });
    }

    private void ComposeContent(IContainer container)
    {
        container.PaddingVertical(10).Column(column =>
        {
            foreach (var eventDto in _data)
            {
                // Event heading
                column.Item().PaddingTop(10).Background("#E8EEF4").Padding(8).Text(text =>
                {
                    text.Span(eventDto.EventName).FontSize(12).Bold().FontColor(HeaderColor);
                    text.Span($"  ({eventDto.EventLevelName})").FontSize(10).FontColor("#666666");
                    text.Span($"  -  {eventDto.Category}").FontSize(10).FontColor("#666666");
                });

                // Scores table
                column.Item().PaddingTop(5).PaddingBottom(5).Table(table =>
                {
                    table.ColumnsDefinition(columns =>
                    {
                        columns.ConstantColumn(55);  // Placement
                        columns.RelativeColumn(3);   // Student Name
                        columns.RelativeColumn(2);   // School
                        columns.ConstantColumn(80);  // Raw Performance
                        columns.ConstantColumn(70);  // Calc Points
                        columns.ConstantColumn(70);  // Placement Points
                    });

                    table.Header(header =>
                    {
                        header.Cell().Background(HeaderColor).Padding(5).AlignCenter()
                            .Text("Place").FontColor(Colors.White).FontSize(9).Bold();
                        header.Cell().Background(HeaderColor).Padding(5)
                            .Text("Student").FontColor(Colors.White).FontSize(9).Bold();
                        header.Cell().Background(HeaderColor).Padding(5)
                            .Text("School").FontColor(Colors.White).FontSize(9).Bold();
                        header.Cell().Background(HeaderColor).Padding(5).AlignRight()
                            .Text("Performance").FontColor(Colors.White).FontSize(9).Bold();
                        header.Cell().Background(HeaderColor).Padding(5).AlignRight()
                            .Text("Calc Pts").FontColor(Colors.White).FontSize(9).Bold();
                        header.Cell().Background(HeaderColor).Padding(5).AlignRight()
                            .Text("Place Pts").FontColor(Colors.White).FontSize(9).Bold();
                    });

                    var rowIndex = 0;
                    foreach (var score in eventDto.Scores)
                    {
                        var bgColor = rowIndex % 2 == 0 ? Colors.White : AltRowColor;

                        table.Cell().Background(bgColor).Padding(5).AlignCenter()
                            .Text(score.Placement?.ToString() ?? "-").FontSize(9);
                        table.Cell().Background(bgColor).Padding(5)
                            .Text(score.StudentName).FontSize(9);
                        table.Cell().Background(bgColor).Padding(5)
                            .Text(score.SchoolName).FontSize(9);
                        table.Cell().Background(bgColor).Padding(5).AlignRight()
                            .Text(score.RawPerformance.ToString("F2")).FontSize(9);
                        table.Cell().Background(bgColor).Padding(5).AlignRight()
                            .Text(score.CalculatedPoints.ToString()).FontSize(9);
                        table.Cell().Background(bgColor).Padding(5).AlignRight()
                            .Text(score.PlacementPoints.ToString()).FontSize(9);

                        rowIndex++;
                    }
                });

                column.Item().PaddingVertical(3).LineHorizontal(0.5f).LineColor("#CCCCCC");
            }
        });
    }

    private void ComposeFooter(IContainer container)
    {
        container.Row(row =>
        {
            row.RelativeItem().AlignLeft().Text(text =>
            {
                text.Span("Generated: ").FontSize(8);
                text.Span(DateTime.Now.ToString("yyyy-MM-dd HH:mm")).FontSize(8);
            });

            row.RelativeItem().AlignRight().Text(text =>
            {
                text.Span("Page ").FontSize(8);
                text.CurrentPageNumber().FontSize(8);
                text.Span(" of ").FontSize(8);
                text.TotalPages().FontSize(8);
            });
        });
    }
}
