using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using static iTextSharp.text.pdf.AcroFields;
using Document = iTextSharp.text.Document;
using Rectangle = iTextSharp.text.Rectangle;

namespace POCPatientAccessReprot
{
    public class FormEventMessage
    {
        public const string CreateReport = "Our records indicated that Informational Report #{0}, was created on {1}";
        public const string SentReport = "Our records indicate that Informational Report #{0}, was sent on {1} to the following contact(s)";
        public const string ViewReport = "Records show that Informational Report #{0} was accessed and viewed by recipient(s).";
        public const string SignedReport = "Records show that Informational Report #{0} was signed and uploaded on {1} ";
        public const string SentTextMessage = @"Sent Text Message: {0} has sent you an important informational packet to review. Please click on the following link to view these documents. {1} Note: If you provided the facility with your email, a copy of this report may also be in your inbox.";
        public const string SentEmailMessage = @"Sent Email Message: {0} has attached an informational packet for your review. Though the report is not specific to any individual, it contains important information about Skilled Nursing Facilities and common issues applicable to individuals in or around these facilities. We request you take the time necessary to read the report as it may affect you or someone you care about. {1} Thank you for your support.";
    }
    public enum AccessReportType
    {
        IsoReport = 1,
        FullReportRemote = 2,
        FullReportInPerson = 3
    }

    public class TOCAccessItems
    {
        public List<TOCItems> TOCItemsList { get; set; }
    }
    public class TOCItems
    {
        public bool IsAccess { get; set; }
        public object Item { get; set; }
    }
    public class AccessReport
    {
        public AccessReportType AccessReportType { get; set; }
        public List<TOCAccessItems> TOCAccessItems { get; set; }
    }

    internal class Program
    {
        public const string DEST = "results/example.pdf";

        static void Main(string[] args)
        {
            List<AccessReport> TOCContactsSentTo = new()
            {
                new AccessReport
                {
                    AccessReportType = AccessReportType.IsoReport,
                    TOCAccessItems = new List<TOCAccessItems>
                    {
                        new TOCAccessItems
                        {
                            TOCItemsList = new List<TOCItems>
                            {
                                new TOCItems
                                {
                                    Item = string.Format(FormEventMessage.SentReport, "123455", DateTime.UtcNow.ToString("F"))
                                },
                                new TOCItems
                                {
                                    Item = new List<string>
                                    {
                                        "Logan Tester",
                                        "Responsible Party",
                                        "510-421-4447",
                                        "ben.pyper@emailcom"
                                    }
                                },
                                new TOCItems
                                {
                                    Item = string.Format(FormEventMessage.SentTextMessage, "Facility Test", new Uri("https://www.google.com/maps"))
                                },
                                new TOCItems
                                {
                                    Item = string.Format(FormEventMessage.SentEmailMessage, "Facility Test", new Uri("https://www.google.com/maps"))
                                },
                                new TOCItems
                                {
                                    Item = string.Format(FormEventMessage.ViewReport, "123455")
                                },
                                new TOCItems
                                {
                                    Item = string.Format("Viewing logs are as follows:")
                                },
                                new TOCItems
                                {
                                    IsAccess = true,
                                    Item = new List<string>
                                    {
                                        "Logan Tester",
                                        "Iphone, IP, Safari",
                                        "11/9/23 - 10:03 am (PST)",
                                        "Report 123454",
                                        "Logan Tester",
                                        "Iphone, IP, Safari",
                                        "",
                                        "Report 123454"
                                    }
                                },
                            }
                        }
                    }
                }
            };
            CreateTableOfContent(TOCContactsSentTo);
        }

        static void CreateTableOfContent(List<AccessReport> TOCContents)
        {
            using MemoryStream ms = new();
            Font font = new(Font.FontFamily.TIMES_ROMAN, 11);
            using Document document = new(PageSize.LETTER, 50f, 50f, 15f, 15f);
            var writer = PdfWriter.GetInstance(document, ms);
            writer.PageEvent = new HeaderEventHandler();

            document.Open();

            foreach (var contents in TOCContents)
            {
                string headLine = "";

                switch (contents.AccessReportType)
                {
                    case AccessReportType.IsoReport:
                        headLine = "ISO REPORT CONFIRMATION";
                        break;
                    case AccessReportType.FullReportInPerson:
                        headLine = "INFORMED MEDICAL - FULL REPORT CONFIRMATION - (For IN PERSON Reports)";
                        break;
                    case AccessReportType.FullReportRemote:
                        headLine = "INFORMED MEDICAL - FULL REPORT CONFIRMATION - REMOTE";
                        break;
                }

                Paragraph pageTitle = new(headLine, new Font(Font.FontFamily.TIMES_ROMAN, 11))
                {
                    Alignment = Element.ALIGN_CENTER,
                    SpacingAfter = 8
                };

                document.Add(pageTitle);

                foreach (var data in contents.TOCAccessItems)
                {
                    foreach (var tocItems in data.TOCItemsList)
                    {
                        if (tocItems.Item is string singleItem)
                        {
                            Paragraph pageDescription1 = new(singleItem, new Font(Font.FontFamily.TIMES_ROMAN, 11))
                            {
                                Alignment = Element.ALIGN_LEFT,
                                SpacingBefore = 5,
                                SpacingAfter = 5,
                            };

                            pageDescription1.SetLeading(1, 1);

                            document.Add(pageDescription1);
                        }
                        if (tocItems.Item is List<string> itemList)
                        {
                            PdfPTable table = CreatePdfTable(itemList, tocItems.IsAccess);
                            document.Add(table);
                        }
                    }
                }

                document.Close();

                string filePath = $"{Directory.GetCurrentDirectory()}/result.pdf";

                File.WriteAllBytes(filePath, ms.ToArray());
            }
        }
        public class TableHeaderAccessReport
        {
            public string HeaderItem { get; set; }
        }
        private static PdfPTable CreatePdfTable(List<string> summaryReports, bool useViewHeader)
        {
            List<TableHeaderAccessReport> SentHeader = new()
            {
                new TableHeaderAccessReport
                {
                    HeaderItem = "Name",
                },
                new TableHeaderAccessReport
                {
                    HeaderItem = "Relation",
                },
                new TableHeaderAccessReport
                {
                    HeaderItem = "Mobile",
                },
                new TableHeaderAccessReport
                {
                    HeaderItem = "Email",
                }
             };

            List<TableHeaderAccessReport> ViewHeader = new()
            {
                new TableHeaderAccessReport
                {
                    HeaderItem = "Viewed by",
                },
                new TableHeaderAccessReport
                {
                    HeaderItem = "Accessed From",
                },
                new TableHeaderAccessReport
                {
                    HeaderItem = "Date & Time",
                },
                new TableHeaderAccessReport
                {
                    HeaderItem = "Info Viewed",
                }
            };

            var headerView = useViewHeader ? ViewHeader : SentHeader;

            PdfPTable table = new(4) { WidthPercentage = 100, PaddingTop = 50 };
            float[] columns = new[] { 40f, 40f, 40f, 40f };
            table.SetWidths(columns);
            table.SpacingBefore = 10;

            foreach (var header in headerView)
            {
                PdfPCell headerCell = new();
                Paragraph headerparagraph = new(header.HeaderItem, new Font(Font.FontFamily.TIMES_ROMAN, 11, 0))
                {
                    Alignment = Element.ALIGN_LEFT
                };
                headerCell.AddElement(headerparagraph);

                headerCell.PaddingBottom = 10;

                table.AddCell(headerCell);
            }

            for (int x = 0; x <= summaryReports.Count() - 1; x++)
            {
                PdfPCell cell = new();

                Paragraph paragraph = new(summaryReports[x], new Font(Font.FontFamily.TIMES_ROMAN, 11, 0))
                {
                    Alignment = Element.ALIGN_LEFT
                };

                cell.AddElement(paragraph);
                cell.PaddingBottom = 10;
                table.AddCell(cell);

            }

            return table;
        }

        public class HeaderEventHandler : PdfPageEventHelper
        {
            public override void OnStartPage(PdfWriter writer, Document document)
            {
                base.OnEndPage(writer, document);

                document.SetMargins(50f, 50f, 45f, 15f);
            }
        }
    }
}