
using System.Data;

using CSharpFunctionalExtensions;

using iText.IO.Font;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;

namespace Monitoring.Features.Reports.FileBuilders;

public class PdfFileBuilder : IFileBuilder
{
	const int RegularFontSize = 10;
	const int HeaderFontSize = 12;

	public ValueTask<Result<byte[]>> Create(DataTable table, CancellationToken cancellationToken)
	{
		try
		{
			using MemoryStream memoryStream = new();
			using PdfWriter writer = new(memoryStream);
			using PdfDocument pdf = new(writer);

			Document document = new(pdf);

			var boldFontPath = Path.Combine("Fonts", "Roboto", "static", "Roboto-Bold.ttf");
			var boldFont = PdfFontFactory.CreateFont(boldFontPath, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED, true);

			var regularFontPath = Path.Combine("Fonts", "Roboto", "static", "Roboto-Regular.ttf");
			var regularFont = PdfFontFactory.CreateFont(regularFontPath, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED, true);

			var tableWriter = new Table(UnitValue.CreatePercentArray(table.Columns.Count))
				.UseAllAvailableWidth();

			// Добавление заголовков столбцов в таблицу
			foreach (DataColumn column in table.Columns)
			{
				_ = tableWriter.AddHeaderCell(new Cell().Add(new Paragraph(column.ColumnName))
					.SetFont(boldFont)
					.SetFontSize(HeaderFontSize));
			}

			// Добавление строк данных в таблицу
			foreach (DataRow row in table.Rows)
			{
				foreach (var cellData in row.ItemArray)
				{
					if (cellData is null)
					{
						throw new Exception($"Cell data is null in row {row.Table.Rows.IndexOf(row)} and column {row.ItemArray.ToList().IndexOf(cellData)}");
					}

					var type = cellData.GetType();

					if (type == typeof(DBNull))
					{
						continue;
					}

					if (cellData is not CellContainer cellContainer)
					{
						throw new Exception("Cell data is not CellContainer");
					}

					_ = tableWriter.AddCell(
						new Cell(1, cellContainer.ColumnGlues)
						.Add(
							new Paragraph(cellContainer.Text)
								.SetTextAlignment(TextAlignment.CENTER)
								.SetFont(regularFont)
								.SetFontSize(RegularFontSize)
						)
					);
				}
			}

			// Добавление таблицы в документ
			_ = document.Add(tableWriter);

			document.Close();

			return ValueTask.FromResult(Result.Success(memoryStream.ToArray()));
		}
		catch (Exception ex)
		{
			return ValueTask.FromResult(Result.Failure<byte[]>(ex.Message));
		}
	}
}