#if DEBUG
#define CREATE_PREVIEW_HTML
#endif
using iText.Html2pdf;
using KarleyLibrary.Erweiterungen;
using MbeSoap;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core.Basis.Erweiterungen;
using WK5.Core.Models;

namespace WK5.Core.Drucken.Warenbegleitscheine
{
    /// <summary>
    /// Stellt eine Vorlage zur Generierung eines Warenbegleitscheins als PDF zur Verfügung.
    /// </summary>
    public sealed class PrintWarenbegleitschein : PrintBase
    {
        private readonly Bestellung _bestellung;
        private readonly BestellungAbruf? _abruf;
        private readonly PrintWarenbegleitscheinRegelsatz _regeln = new PrintWarenbegleitscheinRegelsatz();
        private RecipientType _anschrift;
        private readonly Auftrag _auftrag;

        private PrintWarenbegleitschein(Bestellung bestellung, BestellungAbruf? abruf, RecipientType anschrift, Auftrag auftrag)
        {
            _bestellung = bestellung;
            _abruf = abruf;
            _layoutFile = "Warenbegleitschein.html";
            _template = String.Empty;
            _anschrift = anschrift;
            _auftrag = auftrag;
        }

        /// <summary>
        /// Erstellt einen neuen <see cref="PrintWarenbegleitschein"/> für den angebenen Auftrag.
        /// </summary>
        /// <param name="auftrag"></param>
        /// <returns></returns>
        public static async Task<PrintWarenbegleitschein> CreateAsync(Bestellung bestellung, BestellungAbruf? abruf, FbController2 fbController)
        {
            RecipientType? anschrift = null;

            Auftrag? auftrag = await Auftrag.GetAuftragAsync(bestellung.BEST_N_AB_NR, fbController);

            if (auftrag is not null)
            {
                anschrift = await auftrag.ToRecipientTypeAsync(fbController);
            }
            else
            {
                throw new ArgumentNullException(nameof(auftrag));
            }


            if (anschrift is null)
            {
                throw new ArgumentNullException(nameof(anschrift));
            }

            var myClass = new PrintWarenbegleitschein(bestellung, abruf, anschrift, auftrag);
            await myClass.InitializeAsync();
            return myClass;
        }
        protected override async Task InitializeAsync()
        {
            string layoutPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LAYOUT_PATH, _layoutFile);
            _template = await File.ReadAllTextAsync(layoutPath);
            SetRegeln();
            _template = await SetTemplateVariables();

        }

        protected override Task InitializeAsync(FbController2 fbController)
        {
            throw new NotImplementedException();
        }

        public override string Print(string speicherpfad)
        {
            string filename = $"WBS_BE{ _bestellung.Bestellnummer}_AU{_bestellung.BEST_N_AB_NR}.pdf";

#if CREATE_PREVIEW_HTML
            File.WriteAllText(Path.Combine(speicherpfad, $"WBS_BE{ _bestellung.Bestellnummer}_AU{_bestellung.BEST_N_AB_NR}.html"), _template);
#endif
            byte[] byteArray = Encoding.UTF8.GetBytes(_template);
            MemoryStream stream = new MemoryStream(byteArray);
            ConverterProperties converterProperties = new ConverterProperties()
                .SetBaseUri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LAYOUT_PATH));

            string fullPath = Path.Combine(speicherpfad, filename);
            if (File.Exists(fullPath))
            {
                File.Delete(fullPath);
            }

            HtmlConverter.ConvertToPdf(stream, new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None), converterProperties);

            return fullPath;
        }
        protected override void SetRegeln()
        {
            _regeln.ShowAdresszeile2 = !String.IsNullOrWhiteSpace(_anschrift.Name);
            _regeln.ShowAdresszeile3 = !String.IsNullOrWhiteSpace(_anschrift.Address2);
            _regeln.ShowAdresszeile4 = false;
            _regeln.ShowAdresszeileLand = !_anschrift.Country.Equals("DE");
            _regeln.ShowBestellnummer = !string.IsNullOrWhiteSpace(_auftrag.Bestellnummer);
            _regeln.ShowBestelltDurch = !string.IsNullOrWhiteSpace(_auftrag.BestelltDurch);

        }

        protected override async Task<string> SetTemplateVariables()
        {
            StringBuilder posBuilder = new StringBuilder();
            int posZähler = 1;
            if (_abruf is not null)
            {
                foreach (var pos in _abruf.Positionen)
                {
                    var originalPos = _bestellung.Positionen.First(x => x.BEPO_N_POSID == pos.PosId);
                    posBuilder.AppendLine("<tr>");
                    posBuilder.AppendLine("\t<td class=\"nowrap text-center\">");
                    posBuilder.AppendLine($"\t\t{posZähler++}");
                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("\t<td class=\"\">");
                    posBuilder.AppendLine($"\t\t<span class=\"font-weight-bold\">{pos.Artikelnummer}</span><br />");
                    posBuilder.AppendLine($"\t\t{originalPos.GetBezeichnung()}");
                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                    if (pos.Menge > 0)
                    {
                        posBuilder.AppendLine($"\t\t{pos.Menge:0.00} {originalPos.BEPO_A_MASSEINHEIT}");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t");
                    }

                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("</tr>");
                }
            }
            else
            {
                foreach (var pos in _bestellung.Positionen.OrderBy(x => x.BEPO_N_POS))
                {
                    posBuilder.AppendLine("<tr>");
                    posBuilder.AppendLine("\t<td class=\"nowrap text-center\">");
                    posBuilder.AppendLine($"\t\t{posZähler++}");
                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("\t<td class=\"\">");
                    posBuilder.AppendLine($"\t\t<span class=\"font-weight-bold\">{pos.BEPO_A_ARTIKELNR}</span><br />");
                    posBuilder.AppendLine($"\t\t{pos.GetBezeichnung()}");
                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                    if (pos.BEPO_N_MENGE > 0)
                    {
                        posBuilder.AppendLine($"\t\t{pos.BEPO_N_MENGE:0.00} {pos.BEPO_A_MASSEINHEIT}");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t");
                    }

                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("</tr>");
                }

            }



            using FbController2 fbController = new FbController2();
            Land? land = await Land.GetLandAsync(_anschrift.Country, fbController);

            _template = _template
                .Replace("{{ DISPLAY_CSS }}", GenerateDisplayCss())
                .Replace("{{ IMPRESSUM }}", GlobalConfig.Configuration.FirmenDaten.ImpressumHtmlDruckformulare())
                .Replace("{{ ABS_FIRMA }}", GlobalConfig.Configuration.FirmenDaten.Firmenname)
                .Replace("{{ ABS_STRASSE }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Strasse)
                .Replace("{{ ABS_LAND }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Land)
                .Replace("{{ ABS_PLZ }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Postleitzahl)
                .Replace("{{ ABS_ORT }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Ort)
                .Replace("{{ ADDRESSZEILE1 }}", _anschrift.CompanyName)
                .Replace("{{ ADDRESSZEILE2 }}", _anschrift.Name)
                .Replace("{{ ADDRESSZEILE3 }}", _anschrift.Address2)
                .Replace("{{ ADDRESSZEILE4 }}", string.Empty)
                .Replace("{{ EMP_STRASSE }}", _anschrift.Address)
                .Replace("{{ EMP_LAND }}", land?.LAND_A_NAME ?? _anschrift.Country)
                .Replace("{{ EMP_PLZ }}", _anschrift.ZipCode)
                .Replace("{{ EMP_ORT }}", _anschrift.City)
                .Replace("{{ DATUM }}", _bestellung.Belegdatum.ToShortDateString())
                .Replace("{{ AUFTRAGSNUMMER }}", _bestellung.BEST_N_AB_NR.ToString())
                .Replace("{{ KUNDENNUMMER }}", _bestellung.BEST_A_LIEFERKUNDE?.ToString() ?? String.Empty)
                .Replace("{{ KOPFTEXT }}", StringErweiterung.RtfToString(_bestellung.BEST_B_KOPFTEXT).Trim())
                .Replace("{{ FUSSTEXT }}", StringErweiterung.RtfToString(_bestellung.BEST_B_FUSSTEXT).Trim())
                .Replace("{{ POSITIONEN }}", posBuilder.ToString())
                .Replace("{{ BESTELLNUMMER }}", _auftrag.Bestellnummer)
                .Replace("{{ BESTELLTDURCH }}", _auftrag.BestelltDurch)
                ;

            return await Task.FromResult(_template);
        }

        protected override string GenerateDisplayCss()
        {
            StringBuilder cssBuilder = new StringBuilder();
            cssBuilder.AppendLine("<style>");
            if (!_regeln.ShowAdresszeile2)
            {
                cssBuilder.AppendLine("\t.display-addresszeile2 {");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowAdresszeile3)
            {
                cssBuilder.AppendLine("\t.display-addresszeile3 {");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowAdresszeile4)
            {
                cssBuilder.AppendLine("\t.display-addresszeile4 {");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowAdresszeileLand)
            {
                cssBuilder.AppendLine("\t.display-empfaenger-land {");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestellnummer)
            {
                cssBuilder.AppendLine("\t.display-bestellnummer {");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestelltDurch)
            {
                cssBuilder.AppendLine("\t.display-bestellt-durch {");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }
            cssBuilder.AppendLine("</style>");
            return cssBuilder.ToString();
        }


    }
}
