// Copyright © Selmo Technology GmbH. All Rights Reserved

using PuppeteerSharp.Media;
using PuppeteerSharp;
using Westwind.WebView.HtmlToPdf;

namespace SelmoStudio.Hmi.Server.SelmoHmi.Shared.FormatConverters
{
    internal class PdfConversion
    {
        /// <summary>
        /// Currently used Html to Pdf conversion. Please check the Readme.txt file in the
        /// SelmoStudio.Hmi.Server.SelmoHmi.FormatConverters folder
        /// </summary>
        internal static async Task<byte[]> ConvertAsync(string content)
        {
            await new BrowserFetcher().DownloadAsync();

            await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true
            });

            await using var page = await browser.NewPageAsync();

            await page.EmulateMediaTypeAsync(MediaType.Screen);

            await page.SetContentAsync(content);

            var pdfContent = await page.PdfStreamAsync(new PdfOptions
            {
                Format = PaperFormat.A4,
                Landscape = true,
                PrintBackground = true
            });

            return ReadStream(pdfContent);
        }

        /// <summary>
        /// Another implementation of the Html to Pdf conversion. Please check the Readme.txt file in the
        /// SelmoStudio.Hmi.Server.SelmoHmi.FormatConverters folder
        /// </summary>
        internal static async Task<byte[]?> Web2ViewConvertAsync(string content)
        {
            var host = new HtmlToPdfHost();

            var pdfPrintSettings = new WebViewPrintSettings()
            {
                ShouldPrintHeaderAndFooter = true,
                HeaderTitle = "Selmo HMI",

                ScaleFactor = 0.9F,
                ShouldPrintBackgrounds = false
            };

            var pdfPrintResult = await host.PrintToPdfStreamAsync(GetContentUri(content, out var filename), pdfPrintSettings);

            RemoveFile(filename);

            return pdfPrintResult.IsSuccess ? ReadStream(pdfPrintResult.ResultStream) : null;
        }

        private static string GetContentUri(string content, out string filename)
        {
            filename = $"{Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())}.html";

            File.WriteAllText(filename, content);

            return Path.GetFullPath(filename);
        }

        private static void RemoveFile(string filename)
        {
            File.Delete(filename);
        }

        private static byte[] ReadStream(Stream stream)
        {
            using (var memoryStream = new MemoryStream())
            {
                stream.CopyTo(memoryStream);

                return memoryStream.ToArray();
            }
        }
    }
}