using System.Text;
using IWS5.Server.Enums;
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf.Graphics;

namespace IWS5.Server.Utils.Converter.PdfConverter;

public class HtmlFileToPdfConverter : IFileConverter
{
    private static readonly HashSet<string> Extensions = new(StringComparer.OrdinalIgnoreCase)
    {
        nameof(ConvertibleFileTypes.html).ToLowerInvariant()
    };

    public bool CanConvert(string sourceFileExtension, string targetFileExtension) => Extensions.Contains(sourceFileExtension) && 
        string.Equals(targetFileExtension, nameof(ConvertibleFileTypes.pdf), StringComparison.OrdinalIgnoreCase);

    public async Task<byte[]> ConvertAsync(byte[] inputFile)
    {
        try
        {
            // Convert byte array to HTML string
            string htmlContent = Encoding.UTF8.GetString(inputFile);
            
            // Validate HTML content
            if (string.IsNullOrWhiteSpace(htmlContent))
            {
                throw new ArgumentException("HTML content cannot be null or empty.");
            }

            // Initialize HTML to PDF converter with Blink rendering engine
            var htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink)
            {
                ConverterSettings =
                {
                    // Configure converter settings
                    EnableJavaScript = true,
                    EnableHyperLink = false,
                    Margin = new PdfMargins
                    {
                        Top = 0,
                        Bottom = 0,
                        Left = 0,
                        Right = 0
                    }
                }
            };

            // Convert HTML to PDF
            using var pdfDocument = htmlConverter.Convert(htmlContent, "about:blank");
            
            if (pdfDocument == null)
            {
                throw new InvalidOperationException("Failed to convert HTML to PDF: resulting document is null.");
            }
            
            using var pdfStream = new MemoryStream();
            pdfDocument.Save(pdfStream);
            pdfDocument.Close(true);

            var result = pdfStream.ToArray();
            
            if (result.Length == 0)
            {
                throw new InvalidOperationException("PDF conversion resulted in empty document.");
            }

            return await Task.FromResult(result);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"Error converting HTML to PDF: {ex.Message}", ex);
        }
    }
}