    #define CREATE_PREVIEW_HTML
using iText.Html2pdf;
using KarleyLibrary.Erweiterungen;
using PDFtoPrinter;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core.Email;
using WK5.Core.Models;

namespace WK5.Core.Drucken.Lieferscheine
{
    public class PrintLieferschein : PrintBase
    {
        private readonly Lieferschein _lieferschein;
        private readonly PrintLieferscheinRegelsatz _regeln;


        public bool IsEnglisch { get; }
        private PrintLieferschein(Lieferschein lieferschein, PrintLieferscheinRegelsatz regeln)
        {
            _lieferschein = lieferschein;
            IsEnglisch = !GlobalConfig.DachLächer.Contains(_lieferschein.Land);
            _regeln = regeln;
            _layoutFile = IsEnglisch ? "LieferscheinEnglisch.html" : "Lieferschein.html";
            _template = String.Empty;
        }
        public static async Task<PrintLieferschein> CreateAsync(Lieferschein lieferschein, PrintLieferscheinRegelsatz regeln)
        {
            var myClass = new PrintLieferschein(lieferschein, regeln);
            await myClass.InitializeAsync();
            return myClass;
        }
        public override string Print(string speicherpfad)
        {
            string filename = $"LS_{_lieferschein.Belegnummer}.pdf";

#if CREATE_PREVIEW_HTML
            File.WriteAllText(Path.Combine(speicherpfad, $"LS_{ _lieferschein.Belegnummer}.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 string GenerateDisplayCss()
        {
            StringBuilder cssBuilder = new StringBuilder();
            cssBuilder.AppendLine("<style>");



            if (!_regeln.ShowFooter)
            {
                cssBuilder.AppendLine("\t#footer {");
                //cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t\tvisibility: hidden;");
                cssBuilder.AppendLine("\t\topacity: 0;");
                cssBuilder.AppendLine("\t\tcolor: rgba(0,0,0,0);");
                cssBuilder.AppendLine("\t\ttransform: scale(0);");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowHeader)
            {
                cssBuilder.AppendLine("\t.karley-header {");
                //cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t\tvisibility: hidden;");
                cssBuilder.AppendLine("\t\topacity: 0;");
                cssBuilder.AppendLine("\t\tcolor: rgba(0,0,0,0);");
                cssBuilder.AppendLine("\t\ttransform: scale(0);");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestelltDurch)
            {
                cssBuilder.AppendLine("\t.display-bestellt-durch{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestelltAm)
            {
                cssBuilder.AppendLine("\t.display-bestellt-am{");
                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.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.ShowAngebotsnummer)
            {
                cssBuilder.AppendLine("\t.display-angebotsnummer{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

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






            cssBuilder.AppendLine("</style>");

            return cssBuilder.ToString();
        }

        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();
        }

        protected override void SetRegeln()
        {
            _regeln.ShowBestelltDurch = !String.IsNullOrWhiteSpace(_lieferschein.BestelltDurch);
            _regeln.ShowBestelltAm = _lieferschein.BestelltAm != default;
            _regeln.ShowBestellnummer = !String.IsNullOrWhiteSpace(_lieferschein.Bestellnummer);
            _regeln.ShowAdresszeileLand = _lieferschein.Land != "DE";
            _regeln.ShowAdresszeile2 = !String.IsNullOrWhiteSpace(_lieferschein.Name2);
            _regeln.ShowAdresszeile3 = !String.IsNullOrWhiteSpace(_lieferschein.Name3);
            _regeln.ShowAdresszeile4 = !String.IsNullOrWhiteSpace(_lieferschein.Ansprechpartner);
            _regeln.ShowAngebotsnummer = _lieferschein.AngebotsnummerVerknüpfung > 0;
            _regeln.ShowAuftragsnummer = _lieferschein.AuftragsnummerVerknüpfung > 0;
        }

        protected override async Task<string> SetTemplateVariables()
        {
            Ansprechpartner? partner = null;
            if (!String.IsNullOrWhiteSpace(_lieferschein.Ansprechpartner))
            {
                partner = await Ansprechpartner.GetAnsprechpartnerByNameAsync(_lieferschein.Kundennummer, _lieferschein.Anrede);
            }
            Lieferanschrift? lieferanschrift = null;

            if (_lieferschein.LieferanschriftId > 0)
            {
                lieferanschrift = await Lieferanschrift.GetLieferanschriftAsync(_lieferschein.Kundennummer, _lieferschein.LieferanschriftId) ?? throw new ArgumentNullException(nameof(lieferanschrift));
                _regeln.ShowAdresszeile2 = !String.IsNullOrWhiteSpace(lieferanschrift.KULA_A_NAME2);
                _regeln.ShowAdresszeile3 = !String.IsNullOrWhiteSpace(lieferanschrift.KULA_A_NAME3);
                _regeln.ShowAdresszeile4 = false;
                _regeln.ShowAdresszeileLand = lieferanschrift.KULA_A_LAND != "DE";
            }
            StringBuilder posBuilder = new StringBuilder();

            int zähler = 1;
            foreach (var pos in _lieferschein.Positionen.Where(x => x.IstBundle || (!x.IstBundle && x.BundleId == 0)).OrderBy(x => x.PosNr))
            {
                if (pos.PosOhneDruck)
                {
                    continue;
                }

                bool istText = pos.Artikelnummer.Equals("TEXT", StringComparison.OrdinalIgnoreCase);


                posBuilder.AppendLine("<tr class=\"pos\">");
                posBuilder.AppendLine("\t<td class=\"nowrap\">");
                if (!istText)
                {
                    posBuilder.AppendLine($"\t\t{zähler}");
                    zähler++;
                }
                posBuilder.AppendLine("\t</td>");
                // Spalte Artikelnummer
                posBuilder.AppendLine("\t<td class=\"\">");
                if (!istText)
                {
                    posBuilder.AppendLine("\t\t<span class=\"font-weight-bold\">");
                    if (!String.IsNullOrWhiteSpace(pos.Kundensachnummer))
                    {
                        posBuilder.AppendLine($"\t\t\t{pos.Artikelnummer} ({pos.Kundensachnummer})");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t\t{pos.Artikelnummer}");
                    }
                    posBuilder.AppendLine("\t\t</span>");
                }

                if (pos.ARTI_L_MIETE && pos.BPOS_D_MIETE_START != default && pos.BPOS_D_MIETE_ENDE != default)
                {
                    if (IsEnglisch)
                    {
                        posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">Period: {pos.BPOS_D_MIETE_START.ToShortDateString()} - {pos.BPOS_D_MIETE_ENDE.ToShortDateString()}</span>");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">Zeitraum: {pos.BPOS_D_MIETE_START.ToShortDateString()} - {pos.BPOS_D_MIETE_ENDE.ToShortDateString()}</span>");
                    }
                }

                posBuilder.AppendLine($"\t\t<div class=\"position-bezeichnung\">");
                posBuilder.AppendLine($"\t\t\t{pos.GetBezeichnung()}");
                if (pos.IstBundle)
                {
                    if (IsEnglisch)
                    {
                        posBuilder.AppendLine($"\t\t\t<span class=\"d-block font-weight-bold bundle-heading\">Bundle consists of:</span>");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t\t<span class=\"d-block font-weight-bold bundle-heading\">Bundle bestehend aus:</span>");
                    }

                    foreach (var bundlePos in pos.BundleArtikel)
                    {
                        decimal basisBundleMenge = bundlePos.Menge / pos.Menge;
                        posBuilder.AppendLine($"\t\t\t<div class=\"bundle-pos\">");
                        posBuilder.AppendLine($"\t\t\t\t<span class=\"bundle-pos-quantity\">{basisBundleMenge} x {bundlePos.Artikelnummer}</span>");
                        posBuilder.AppendLine($"\t\t\t\t<span class=\"bundle-pos-description\">{bundlePos.Bezeichnung1}</span>");
                        if(bundlePos.Seriennummern.Any())
                        {
                            if(IsEnglisch)
                            {
                                posBuilder.AppendLine($"\t\t\t<span class=\"d-block font-weight-bold bundle-heading\">Serialnumbers:</span>");
                            }
                            else
                            {
                                posBuilder.AppendLine($"\t\t\t<span class=\"d-block font-weight-bold bundle-heading\">Seriennummern:</span>");
                            }

                            foreach (Seriennummer seriennummer in bundlePos.Seriennummern)
                            {
                                posBuilder.AppendLine($"\t\t\t\t<span class=\"bundle-pos-seriennummer\">{seriennummer.Nummer}{(!String.IsNullOrWhiteSpace(seriennummer.Kunde) ? $", {seriennummer.Kunde}" : String.Empty)}</span>");
                            }
                        }
                        posBuilder.AppendLine($"\t\t\t</div>");
                    }
                }
                posBuilder.AppendLine($"\t\t</div>");
                foreach (Seriennummer seriennummer in pos.Seriennummern)
                {
                    posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">SN: {seriennummer.Nummer}{(!String.IsNullOrWhiteSpace(seriennummer.Kunde) ? $", {seriennummer.Kunde}" : String.Empty)}</span>");
                }
                posBuilder.AppendLine("\t</td>");

                // Spalte Menge
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (pos.Menge > 0)
                {
                    posBuilder.AppendLine($"\t\t{pos.Menge:0.00} {pos.BPOS_A_MASSEINHEIT}");
                }
                else
                {
                    posBuilder.AppendLine($"\t\t");
                }
                posBuilder.AppendLine("\t</td>");
                posBuilder.AppendLine("</tr>");

                if (!String.IsNullOrWhiteSpace(pos.Langtext))
                {
                    posBuilder.AppendLine("<tr>");
                    posBuilder.AppendLine("\t<td></td>");
                    posBuilder.AppendLine("\t<td>");
                    posBuilder.AppendLine($"\t\t<div class=\"position-bezeichnung\">");
                    if (pos.LangtextDrucken)
                    {
                        posBuilder.AppendLine($"\t\t\t\t{pos.Langtext.HtmlToDruckHtml()}");
                    }
                    posBuilder.AppendLine($"\t\t</div>");
                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("\t<td></td>");
                    posBuilder.AppendLine("</tr>");
                }

            }

            Rechnungsanschrift? rechnungsanschrift = null;

            if (_lieferschein.LieferanschriftId > 0)
            {
                lieferanschrift = await Lieferanschrift.GetLieferanschriftAsync(_lieferschein.Kundennummer, _lieferschein.LieferanschriftId);
            }

            if (_lieferschein.RechnungsanschriftId > 0)
            {
                rechnungsanschrift = await Rechnungsanschrift.GetRechnungsanschriftAsync(_lieferschein.Kundennummer, _lieferschein.RechnungsanschriftId);
            }

            using FbController2 fbController = new FbController2();

            Land land = await Land.GetLandAsync(_lieferschein.Land, fbController) ?? throw new ArgumentNullException(nameof(land));





            _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 }}", lieferanschrift is not null ? lieferanschrift.KULA_A_NAME1 : _lieferschein.Name1)
                .Replace("{{ ADDRESSZEILE2 }}", lieferanschrift is not null ? lieferanschrift.KULA_A_NAME2 : _lieferschein.Name2)
                .Replace("{{ ADDRESSZEILE3 }}", lieferanschrift is not null ? lieferanschrift.KULA_A_NAME3 : _lieferschein.Name3)
                .Replace("{{ ADDRESSZEILE4 }}", lieferanschrift is not null ? String.Empty : partner is not null ? partner.GetName() : _lieferschein.Ansprechpartner)
                .Replace("{{ EMP_STRASSE }}", lieferanschrift is not null ? lieferanschrift.KULA_A_STRASSE : _lieferschein.Strasse)
                .Replace("{{ EMP_LAND }}", lieferanschrift is not null ? lieferanschrift.KULA_A_LAND : land.LAND_A_NAME)
                .Replace("{{ EMP_PLZ }}", lieferanschrift is not null ? lieferanschrift.KULA_A_PLZ : _lieferschein.Postleitzahl)
                .Replace("{{ EMP_ORT }}", lieferanschrift is not null ? lieferanschrift.KULA_A_ORT : _lieferschein.Ort)
                .Replace("{{ DATUM }}", _lieferschein.BELE_D_DATE.ToShortDateString())
                .Replace("{{ KUNDENNUMMER }}", _lieferschein.Kundennummer)
                .Replace("{{ BESTELLT_DURCH }}", _lieferschein.BestelltDurch)
                .Replace("{{ BESTELLT_AM }}", _lieferschein.BestelltAm.ToShortDateString())
                .Replace("{{ KOPFTEXT }}", _lieferschein.Kopftext)
                .Replace("{{ FUSSTEXT }}", _lieferschein.Fußtext)
                .Replace("{{ POSITIONEN }}", posBuilder.ToString())
                .Replace("{{ LIEFERSCHEINNUMMER }}", _lieferschein.Belegnummer.ToString())
                .Replace("{{ BESTELLNUMMER }}", _lieferschein.Bestellnummer)
                .Replace("{{ ANGEBOTSNUMMER }}", _lieferschein.AngebotsnummerVerknüpfung.ToString())
                .Replace("{{ AUFTRAGSNUMMER }}", _lieferschein.AuftragsnummerVerknüpfung.ToString())
                ;

            return await Task.FromResult(_template);
        }
    }
}
