using Serilog;
using Serilog.Sinks.Firebird;
using MbeSoap;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WK5.Core.Basis.Erweiterungen;
using WK5.Core.Drucken.Angebote;
using WK5.Core.Drucken.Aufträge;
using WK5.Core.Drucken.Lieferscheine;
using WK5.Core.Drucken.Rechnungen;
using WK5.Core.Email;
using WK5.Core.Models.Tools.Lagerregal;
using WK5.Core.Services;
using Serilog.Core;

namespace WK5.Core.Models.Versand
{
    /// <summary>
    /// Funktionen für den E-Mail Versand mit dem Lagerregal
    /// </summary>
    public class VersandMailer
    {
        /// <summary>
        /// Gibt an, wie groß ein Anhang mindestens sein muss, damit wir die E-Mail verschicken.
        /// <para>
        /// Zahl ist in bytes angegeben.
        /// </para>
        /// </summary>
        public const int MinAnhangLength = 5000;
        private readonly Beleg beleg;
        private readonly int personalNummer;
        private readonly EmailController emailController = new EmailController
        {
            Html = true, // Immer HTML!!!!
        };
        private readonly List<string> trackingNummern;
        private readonly VersandOption versandOptionen;
        public string VersandEmailAdresse { get; set; } = "";
        public string RechnungsEmailAdresse { get; set; } = "";

        public string MailBody { get; set; } = "";

        public EmailAnhang Anhang { get; set; }

        
        // Hier werden die verscheidenen Templates für die E-Mail Generierung eiingelesen.
        public static readonly string RechnungsTemplate = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"EmailTemplates/Versand/RechnungsEmail.html"));
        public static readonly string VersandTemplate = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"EmailTemplates/Versand/VersandmitteilungEmail.html"));
        public static readonly string AbholungsTemplate = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"EmailTemplates/Versand/AbholungsEmail.html"));
        public static readonly string MbeZollvoranmeldungTemplate = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"EmailTemplates/MbeZollvoranmeldungEmail.html"));
        public Logger Log { get; set; } = new LoggerConfiguration()
#if DEBUG
            .WriteTo.Firebird(GlobalConfig.W4LocalDebugConnectionString, prefix: () => "VersandMailer - ")
#else
            .WriteTo.Firebird(GlobalConfig.W4ConnectionString, prefix: () => "VersandMailer - ")
#endif
            .CreateLogger();


        private VersandMailer(Beleg beleg, List<string> trackingNummern, VersandOption versandOptionen, int personalNummer, string versandEmailAdresse, string rechnungsEmailAdresse)
        {
            this.trackingNummern = trackingNummern;
            this.versandOptionen = versandOptionen;
            VersandEmailAdresse = versandEmailAdresse;
            RechnungsEmailAdresse = String.IsNullOrWhiteSpace(rechnungsEmailAdresse) ? VersandEmailAdresse : rechnungsEmailAdresse;
            this.beleg = beleg;
            this.personalNummer = personalNummer;
        }

        public static async Task<VersandMailer> CreateAsync(Beleg beleg, List<string> trackingNummern, VersandOption versandOptionen, int personalNummer, FbController2 fbController)
        {
            string versandEmailAdresse = await beleg.GetVersandEmailAdresseAsync(fbController);
            string rechnungsEmailAdresse = await beleg.GetRechnungsEmailAdresseAsync(fbController);
            var myClass = new VersandMailer(beleg, trackingNummern, versandOptionen, personalNummer, versandEmailAdresse, rechnungsEmailAdresse);
            return myClass;
        }



        /// <summary>
        /// Verschickt alle E-Mails, die mit dem Beleg zu tun haben.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task<List<EmailVersandResponse>> EmailSendenAsync()
        {
            List<EmailVersandResponse> responses = new List<EmailVersandResponse>();
            using FbController2 fbController = new FbController2();
            // Wenn ein Paketdienst aufgewählt wurde, aber keine Trackingnummern geneiert wurden, dann sollen auch keine Mails rausgesendet werden.
            if (versandOptionen.Versandart != CourierArt.MANUELL && versandOptionen.Versandart != CourierArt.ABHOLUNG && versandOptionen.Versandart != CourierArt.BRIEF && trackingNummern.Count == 0)
            {
                return responses;
            }

            Kunde kunde = await Kunde.GetKundeAsync(beleg.Kundennummer) ?? throw new ArgumentNullException(nameof(kunde));
            // Bei Rechnungsdruck soll der Kunde keine Mail von uns erhalten. 
            if (kunde.KUND_WK5_L_REDRUCK)
            {
                responses.Add(new EmailVersandResponse
                {
                    Message = "Kunde wünscht Rechnung per Post. Bitte manuell per Post versenden.",
                    Status = EmailVersandState.REDRUCK,
                    Success = true
                });

                if (beleg.Belegtyp is "RE")
                {
                    await emailController.SendenAsync
                    (
                        GlobalConfig.EmailInfoEU,
                        "Künde wünscht Rechnung per Post",
                        @$"Der Kunde <a href=""/Kunden/{kunde.KUND_A_NR}"">{kunde.KUND_A_NAME1}</a> wünscht die Rechnung {beleg.Belegnummer} per Post."
                    );
                }



                return responses;
            }

            string betreff = beleg.Belegtyp switch
            {
                "AN" => $"Ihr Angebot {beleg.Belegnummer}",
                "AU" => $"Ihr Auftrag {beleg.Belegnummer}",
                "LS" => $"Ihr Lieferschein {beleg.Belegnummer}",
                "RE" => $"Ihre Rechnung {beleg.Belegnummer}",
                _ => $"Ihr Auftrag {beleg.Belegnummer}",
            };

#if EMAIL_DEBUG
            betreff += $" <TARGET: {RechnungsEmailAdresse}>";
#endif

            List<EmailTemplate> mails = new List<EmailTemplate>();

            string dateiname = await beleg.GetBelegDateinameAsync(fbController);
            // Druck der Belege
            if (beleg is Angebot angebot)
            {
                PrintAngebot printAngebot = await PrintAngebot.CreateAsync(angebot, new PrintAngebotRegelsatz { ShowHeader = true, ShowFooter = true }, fbController);

                Anhang = new EmailAnhang(printAngebot.Print(GlobalConfig.Configuration.OutputPfad), dateiname);

            }
            else if (beleg is Auftrag auftrag)
            {
                PrintAuftrag printAuftrag = await PrintAuftrag.CreateAsync(auftrag, new PrintAuftragRegelsatz { ShowHeader = true, ShowFooter = true }, fbController);
                Anhang = new EmailAnhang(printAuftrag.Print(GlobalConfig.Configuration.OutputPfad), dateiname);
            }
            else if (beleg is Lieferschein lieferschein)
            {
                if (lieferschein.NeutralerVersender && lieferschein.NeutralerLieferschein.Length > 0)
                {
                    await File.WriteAllBytesAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, dateiname), lieferschein.NeutralerLieferschein);
                    Anhang = new EmailAnhang(Path.Combine(GlobalConfig.Configuration.OutputPfad, dateiname), dateiname);
                }
                else
                {
                    PrintLieferschein printLieferschein = await PrintLieferschein.CreateAsync
                   (
                       lieferschein,
                       new PrintLieferscheinRegelsatz { ShowHeader = true, ShowFooter = true }
                   );

                    Anhang = new EmailAnhang(printLieferschein.Print(GlobalConfig.Configuration.OutputPfad), dateiname);
                }

            }
            else if (beleg is PackLieferschein packLieferschein)
            {
                if (packLieferschein.NeutralerVersender && packLieferschein.NeutralerLieferschein.Length > 0)
                {
                    await File.WriteAllBytesAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, dateiname), packLieferschein.NeutralerLieferschein);
                    Anhang = new EmailAnhang(Path.Combine(GlobalConfig.Configuration.OutputPfad, dateiname), dateiname);
                }
                else
                {
                    Lieferschein normalerLieferschein = await Lieferschein.GetLieferscheinAsync(packLieferschein.Belegnummer, fbController) ?? throw new ArgumentNullException(nameof(normalerLieferschein));
                    PrintLieferschein printLieferschein = await PrintLieferschein.CreateAsync
                    (
                        normalerLieferschein,
                        new PrintLieferscheinRegelsatz { ShowHeader = true, ShowFooter = true }
                    );

                    Anhang = new EmailAnhang(printLieferschein.Print(GlobalConfig.Configuration.OutputPfad), dateiname);
                }
            }
            else if (beleg is PackAuftrag packAuftrag)
            {
                // PackAufträge brauchen nicht als Anhang zu sein          
            }
            else if (beleg is Rechnung rechnung)
            {
                PrintRechnung printRechnung = await PrintRechnung.CreateAsync(rechnung, new PrintRechnungRegelsatz { ShowHeader = true, ShowFooter = true }, fbController);

                Anhang = new EmailAnhang(printRechnung.Print(GlobalConfig.Configuration.OutputPfad), dateiname);
            }
            else
            {
                throw new InvalidOperationException();
            }


            List<EmailAnhang> dokumente = new List<EmailAnhang>();

            if (Anhang.Name is not null && Anhang.Pfad is not null)
            {
                dokumente.Add(Anhang);
            }

            if (beleg is Rechnung)
            {
                string xRechnungResult = await GlobalConfig.GetConfigAsync(GlobalConfig.WK5_ALWAYS_SEND_XRECHNUNG, fbController);

                bool sendXRechnung = String.IsNullOrWhiteSpace(xRechnungResult) ? false : xRechnungResult.Equals("Y", StringComparison.OrdinalIgnoreCase);

                if (sendXRechnung && kunde.KUND_WK5_L_XRECHNUNG && !String.IsNullOrWhiteSpace(kunde.KUND_WK5_A_LEITWEG_ID))
                {
                    XRechnungService xRechnungService = new XRechnungService();
                    s2industries.ZUGFeRD.InvoiceDescriptor xRechnung = await xRechnungService.ToXRechnung(beleg);

                    try
                    {
                        string datei = Path.Combine(GlobalConfig.Configuration.OutputPfad, $"{beleg.Belegtyp}-{beleg.Belegnummer}-xrechnung.xml");

                        string xml = xRechnungService.ToPDF(xRechnung, s2industries.ZUGFeRD.ZUGFeRDVersion.Version21, s2industries.ZUGFeRD.Profile.XRechnung, XRechnungVersion.Version211);

                        File.WriteAllText(datei, xml);

                        EmailAnhang anhang = new EmailAnhang()
                        {
                            Name = Path.GetFileName(datei),
                            Pfad = datei
                        };

                        dokumente.Add(anhang);
                    }
                    catch (Exception ex)
                    {
                        Log.Error($"Fehler beim anhängen der XRechnung. Fehler: {{ex}}", ex);
                    }
                }
            }



            // Bei Rechnungen prüfen wir, ob der Kunde nur die Rechnung erhalten darf
            if (((beleg is Rechnung && !kunde.NurRechnungAlsPdf) || beleg is not Rechnung) && !beleg.NeutralerVersender)
            {
                await foreach (ArtikelDokument dokument in ArtikelDokument.GetArtikelDokumenteAsync(beleg).Where(x => x.ARDI_L_IN_VERSAND == true))
                {
                    if (dokument.Exists() && dokument.ARDI_L_IN_VERSAND)
                    {
                        EmailAnhang anhang = dokument.ToEmailAnhang();
                        dokumente.Add(anhang);
                    }
                }


                List<KeyValuePair<string, string>> warengruppenDokumente = new List<KeyValuePair<string, string>>()
                {
                    new KeyValuePair<string, string>( "2172", @"\\srv01\Daten\attachements\KARLEY-PREISLISTE-ETIKETTEN.pdf" ), //EtikettenMaterial                    
                };

                List<KeyValuePair<string, string>> unterwarengruppenDokumente = new List<KeyValuePair<string, string>>()
                {
                    new KeyValuePair<string, string>( "2543", @"\\srv01\Daten\attachements\KARLEY-PREISLISTE-BONROLLEN.pdf" ), //Bonrollen                    
                };


                // Karley Flyer bei Erstkunden anhängen
                bool istErstkunde = await Kunde.IstErstkundeAsync(beleg.Kundennummer);

                if (istErstkunde)
                {
                    dokumente.Add(new EmailAnhang
                    {
                        Pfad = @"\\srv01\daten\Werbung\Karley-Flyer\Mailing_Systemhaus.pdf",
                        Name = "Mailing_Systemhaus.pdf"
                    });
                }


                foreach (Belegposition pos in beleg.GetEndPositionen())
                {
                    IEnumerable<string> wgDoks = warengruppenDokumente.Where(x => x.Key == pos.ARTI_A_WARENGRUPPE).Select(x => x.Value);
                    IEnumerable<string> uwgDoks = unterwarengruppenDokumente.Where(x => x.Key == pos.ARTI_A_UNTERWARENG).Select(x => x.Value);

                    foreach (string dok in wgDoks)
                    {
                        if (!dokumente.Where(x => x.Pfad.Equals(dok, StringComparison.OrdinalIgnoreCase)).Any())
                        {
                            if (!File.Exists(dok))
                            {
                                await EmailController.FehlerMailSendenAsync("Datei nicht gefunden", $"Die Datei {dok} konnte nicht gefunden werden und wurde daher auch nicht an die Rechnnungsmails angehangen");
                                continue;
                            }

                            dokumente.Add(new EmailAnhang
                            {
                                Pfad = dok,
                                Name = Path.GetFileName(dok)
                            });
                        }
                    }

                    foreach (string dok in uwgDoks)
                    {
                        if (!dokumente.Where(x => x.Pfad.Equals(dok, StringComparison.OrdinalIgnoreCase)).Any())
                        {
                            if (!File.Exists(dok))
                            {
                                await EmailController.FehlerMailSendenAsync("Datei nicht gefunden", $"Die Datei {dok} konnte nicht gefunden werden und wurde daher auch nicht an die Rechnnungsmails angehangen");
                                continue;
                            }

                            dokumente.Add(new EmailAnhang
                            {
                                Pfad = dok,
                                Name = Path.GetFileName(dok)
                            });
                        }
                    }
                }

            }

            if (String.IsNullOrWhiteSpace(RechnungsEmailAdresse) || VersandEmailAdresse == RechnungsEmailAdresse) // Kombinierter Versand
            {
                if (beleg.IstAbholung)
                {
                    MailBody = await FormatEmailAsync(AbholungsTemplate, Anhang.Name, fbController, true);
                }
                else
                {
                    MailBody = await FormatEmailAsync(VersandTemplate, Anhang.Name, fbController, true);
                }

                MailBody.Replace("{%RECHNUNG%}", await FormatEmailAsync(RechnungsTemplate, Anhang.Name, fbController, true));

                mails.Add(new EmailTemplate
                {
                    Betreff = beleg.IstAbholung ? $"Ihre Bestellung ist bereit zur Abholung & {betreff}" : $"{betreff} & Ihre Versandmitteilung",
                    Anhänge = dokumente,
                    Body = MailBody,
                    Empfänger = VersandEmailAdresse
                });
            }
            else // Mails werden getrennt verschickt
            {
                MailBody = await FormatEmailAsync(RechnungsTemplate, Anhang.Name, fbController);
                mails.Add(new EmailTemplate
                {
                    Anhänge = dokumente,
                    Betreff = betreff,
                    Empfänger = RechnungsEmailAdresse,
                    Body = MailBody
                });

                if (beleg.IstAbholung)
                {
                    MailBody = await FormatEmailAsync(AbholungsTemplate, Anhang.Name, fbController);
                }
                else
                {
                    MailBody = await FormatEmailAsync(VersandTemplate, Anhang.Name, fbController);
                }

                mails.Add(new EmailTemplate
                {
                    Anhänge = new List<EmailAnhang>(),
                    Betreff = beleg.IstAbholung ? "Ihre Bestellung ist bereit zur Abholung" : $"Ihre Versandmitteilung",
                    Empfänger = VersandEmailAdresse,
                    Body = MailBody
                });

            }

            // Prüfen ob wir eine Zollvoranmeldung senden müssen
            var länder = await Land.GetLänderAsync(fbController).ToListAsync();
            if (länder.Any(x => !x.WK5_LAND_L_ISTEULAND && x.LAND_A_ID == beleg.Land) && versandOptionen.Versender == Courier.UPS)
            {
                mails.Add(new EmailTemplate
                {
                    Betreff = $"Zollvoranmeldung RE-{beleg.Belegnummer}",
                    Empfänger = "mbe0159@mbe.de",
                    Anhänge = new List<EmailAnhang>() { Anhang },
                    Body = await FormatEmailAsync(MbeZollvoranmeldungTemplate, Anhang.Name, fbController)
                });
            }

            if (beleg.BestelltDurch.Equals("ebay", StringComparison.OrdinalIgnoreCase) == true)
            {
                mails.Add(new EmailTemplate
                {
                    Betreff = "Versandnummer bei Ebay Auftrag eintragen!",
                    Body = $"<p>Der Auftrag {beleg.Belegtyp}-{beleg.Belegnummer} war ein Ebay Verkauf!</p><br/><p>Bitte im Ebay Konto die Versandnummer {trackingNummern?.FirstOrDefault()} hinterlegen.",
                    Empfänger = GlobalConfig.Configuration.FirmenDaten.Email
                });
            }

            if ((beleg is Lieferschein || beleg is PackLieferschein) && beleg.WK5_BELE_L_SAMMELRECHNUNG)
            {
                mails.Add(new EmailTemplate
                {
                    Betreff = "Sammelrechnung erstellen",
                    Body = $"Der Beleg: {beleg.Belegtyp}-{beleg.Belegnummer} wurde versendet aber <strong>NICHT</strong> zur Rechnung fortgeführt.<br/>Der Beleg hat ein Sammelrechnungsmerkmal eingetragen und sollte somit zu der entsprechenden Sammelrechnung hinzugefügt werden.",
                    Empfänger = GlobalConfig.Configuration.FirmenDaten.Email
                });
            }

            foreach (var mail in mails)
            {
                var resultPrüfung = PrüfeMail(mail);

                if (resultPrüfung != null)
                {
                    responses.Add(resultPrüfung);
                    // Fehler beim Versand von E-Mails müssen auch an den Vertrieb gehen, damit der weiß, dass ein Kunde eventuell keine Rechnung erhalten hat.

                    string dateien = String.Join("<br/><br/>", mail.Anhänge.Select(x => $"Dateiname: {x.Name}<br/>Dateipfad: {x.Pfad}"));

                    await EmailController.FehlerMailSendenAsync(
                        betreff: "WK5_Blazor_VersandMailer - Fehler beim Mailversand",
                        body: $"Die Mail konnte nicht an \"{mail.Empfänger}\" gesendet werden.<br /><br />Fehler: {resultPrüfung.Message}<br /><br/>{dateien}<br/><br />Mail:<br />{mail.Body}",
                        empfänger: "software@karley.eu;info@karley.eu",
                        anhänge: mail.HatAnhang ? mail.Anhänge.Where(x => x.IsValid()).ToList() : null
                    );
                    continue;
                }

                EmailResponse response = await emailController.SendenAsync(
                    empfängerEmail: mail.Empfänger,
                    betreff: mail.Betreff,
                    body: mail.Body,
                    anhänge: mail.HatAnhang ? mail.Anhänge : null
                );

                var tmpResponse = new EmailVersandResponse()
                {
                    Success = response.Success,
                    Message = response.Message,
                    Status = response.Success ? EmailVersandState.OK : EmailVersandState.EMAIL_ERROR
                };

                if (response.Success && beleg.NeutralerVersender)
                {
                    tmpResponse.Status = EmailVersandState.NEUTRAL;
                }

                responses.Add(tmpResponse);

                // Wenn eine E-Mail nicht versendet wurde, dann soll er die anderen auch nicht versenden
                if (!response.Success)
                {
                    // Fehler beim Versand von E-Mails müssen auch an den Vertrieb gehen, damit der weiß, dass ein Kunde eventuell keine Rechnung erhalten hat.
                    string dateien = String.Join("<br/><br/>", mail.Anhänge.Select(x => $"Dateiname: {x.Name}<br/>Dateipfad: {x.Pfad}"));

                    await EmailController.FehlerMailSendenAsync(
                        betreff: "WK5_Blazor_VersandMailer - Fehler beim Mailversand",
                        body: $"Die Mail konnte nicht an \"{mail.Empfänger}\" gesendet werden.<br /><br />Fehler: {response.Message}<br /><br/>{dateien}<br/><br />Mail:<br />{mail.Body}",
                        empfänger: "software@karley.eu;info@karley.eu",
                        anhänge: mail.HatAnhang ? mail.Anhänge.Where(x => x.IsValid()).ToList() : null
                    );
                }

            }

            return responses;
        }

        /// <summary>
        /// Prüft ob alle erforderlichen Daten für den Versand einer E-Mail vorhanden sind.
        /// </summary>
        /// <param name="mail"></param>
        /// <returns>Liefert null zurück, wenn alles OK ist.</returns>
        private EmailVersandResponse? PrüfeMail(EmailTemplate mail)
        {
            if (String.IsNullOrWhiteSpace(mail.Empfänger))
            {
                return new EmailVersandResponse
                {
                    Status = EmailVersandState.EMPFAENGER_NOT_FOUND,
                    Message = "Es konnte keine Empfänger E-Mail Adresse gefunden werden",
                    Success = false,
                    Value = mail
                };
            }

            foreach (var anhang in mail.Anhänge)
            {
                if (String.IsNullOrWhiteSpace(anhang.Pfad) || !File.Exists(anhang.Pfad) || new FileInfo(anhang.Pfad).Length < MinAnhangLength)
                {
                    return new EmailVersandResponse()
                    {
                        Status = EmailVersandState.ATTACHEMENT_NOT_FOUND,
                        Message = $"Der Anhang {anhang.Name} konnte nicht gefunden werden",
                        Success = false,
                        Value = mail
                    };
                }
            }

            return null;
        }
        /// <summary>
        /// Formatiert das E-Mail Template und befüllt alle Platzhalter mit Inhalt.
        /// </summary>
        /// <param name="template"></param>
        /// <param name="anhangName"></param>
        /// <param name="fbController"></param>
        /// <param name="isComboEmail"></param>
        /// <returns></returns>
        private async Task<string> FormatEmailAsync(string template, string anhangName, FbController2 fbController, bool isComboEmail = false)
        {
            Ansprechpartner? partner = await Ansprechpartner.GetAnsprechpartnerByNameAsync(beleg.Kundennummer, beleg.Ansprechpartner);
            Lieferanschrift? lieferanschrift = await Lieferanschrift.GetLieferanschriftAsync(beleg.Kundennummer, beleg.LieferanschriftId);

            string anrede = partner is null || String.IsNullOrEmpty(partner.PART_A_BRIEFANREDE) || String.IsNullOrEmpty(partner.PART_A_NAME) ? "Sehr geehrte Damen und Herren" : $"{partner.PART_A_BRIEFANREDE} {partner.PART_A_NAME}";

            RecipientType empfänger = await beleg.ToRecipientTypeAsync(fbController);

            StringBuilder sbPakete = new StringBuilder();
            if (trackingNummern.Count > 1)
            {
                sbPakete.AppendLine("Paketnummern:<br />");
            }
            else if (trackingNummern.Count == 1)
            {
                sbPakete.Append("Paketnummer: ");
            }

            foreach (var trackingnummer in trackingNummern)
            {
                if (versandOptionen.Versender == Courier.UPS)
                {
                    sbPakete.Append($"<a href='https://www.ups.com/track?loc=de_DE&tracknum={trackingnummer}&requester=ST'>{trackingnummer}</a><br />");
                }
                else
                {
                    sbPakete.Append($"{trackingnummer}<br />");
                }
            }

            string trustedShops = "";
            if (!String.IsNullOrWhiteSpace(beleg.Bestellnummer) && beleg.Bestellnummer.StartsWith("KL-"))
            {
                trustedShops = "https://www.trustedshops.de/bewertung/bewerten_XD2DE526ECC7EF26641091C1740E0CF81.html&buyerEmail=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(empfänger.Email)) + "&shopOrderID=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(beleg.Bestellnummer));
            }

            string belenrPrefix = beleg.Belegtyp switch
            {
                "AN" => $"Ihre Angebots-Nummer:",
                "AU" => $"Ihre Auftrags-Nummer:",
                "LS" => $"Ihre Lieferschein-Nummer:",
                "RE" => $"Ihre Rechnungs-Nummer:",
                _ => $"Ihre Auftrags-Nummer:",
            };

            string bestellnr = "";
            if (!String.IsNullOrWhiteSpace(beleg.Bestellnummer) && beleg.Bestellnummer.StartsWith("KL-"))
            {
                bestellnr = $"{beleg.Bestellnummer}";
            }
            else
            {
                if (beleg.AuftragsnummerVerknüpfung > 0)
                {
                    bestellnr = $"AU-{beleg.AuftragsnummerVerknüpfung}";
                }
            }

            string refnr = "";
            if (!String.IsNullOrWhiteSpace(beleg.Bestellnummer) && !beleg.Bestellnummer.ToLower().Contains("email") && !beleg.Bestellnummer.StartsWith("KL-") && !beleg.Bestellnummer.ToLower().Contains("telefon"))
            {
                refnr = $"Ihre Referenznummer: {beleg.Bestellnummer}";
            }

            // Ab hier wird das Template ersetzt
            Dictionary<string, string> replaces = new Dictionary<string, string>
            {
                {"{%BESTELLNR_PREFIX%}",bestellnr.Length > 0 ? "Ihre BestellNr.:" : "" },
                {"{%REFNR%}", refnr },
                {"{%ANREDE%}", anrede },
                {"{%VERSENDER%}",versandOptionen.Versender != Courier.MANUAL && versandOptionen.Versender != Courier.OHNETRACKINGNUMMER ? $"wurde heute an {versandOptionen.Versender} übergeben." : "wurde heute versendet." },
                {"{%BESTELLNR%}",bestellnr},
                {"{%BELENR%}",beleg.Belegnummer.ToString()},
                {"{%BELETYP%}",beleg.Belegtyp },
                {"{%BELENR_PREFIX%}",belenrPrefix },
                {"{%LF_PARTNER_NAME%}",empfänger.Name},
                {"{%LF_COMPANY_NAME%}",empfänger.CompanyName},
                {"{%LF_STRASSE2%}",empfänger.Address2?.Length > 0 ? $"<span>{empfänger.Address2}</span><br />" : "" },
                {"{%LF_STRASSE3%}",empfänger.Address3?.Length > 0 ? $"<span>{empfänger.Address3}</span><br />" : ""},
                {"{%LF_STRASSE%}",empfänger.Address},
                {"{%LF_LAND%}",empfänger.Country },
                {"{%LF_PLZ%}",empfänger.ZipCode },
                {"{%LF_ORT%}",empfänger.City },
                {"{%VERFOLGUNGS_DATUM%}",DateTime.Now.Hour <= 15 ? "16 Uhr" : "16 Uhr morgen" },
                {"{%PAKET_NUMMERN%}", sbPakete.ToString() },
                {"{%TRUSTED_SHOPS_LINK%}", trustedShops.Length > 0 ? $"<a href='{trustedShops}'>Trusted Shops</a> oder" : ""},
                {"{%RE_DOKUMENT%}",anhangName},
                {"{%IMPRESSUM%}", GlobalConfig.Configuration.FirmenDaten.ImpressumHTML() },
                {"{%GOOGLE_LINK%}",@"https://g.page/karley-de?gm" }
            };



            foreach (KeyValuePair<string, string> kvp in replaces)
            {
                if (String.IsNullOrWhiteSpace(kvp.Value))
                {
                    template = template.Replace(kvp.Key, String.Empty);
                }
                else
                {
                    template = template.Replace(kvp.Key, kvp.Value);
                }
            }


            if (isComboEmail)
            {
                Regex regex = new Regex("(\\{%START_REMOVE_COMBO_EMAIL%\\})(.*?)(\\{%STOP_REMOVE_COMBO_EMAIL%\\})", RegexOptions.Singleline);
                template = regex.Replace(template, String.Empty);
                template = template.Replace("{%START_REMOVE_SINGLE_MAIL%}", String.Empty);
                template = template.Replace("{%STOP_REMOVE_SINGLE_MAIL%}", String.Empty);
            }
            else
            {
                Regex regex = new Regex("(\\{%START_REMOVE_SINGLE_MAIL%\\})(.*?)(\\{%STOP_REMOVE_SINGLE_MAIL%\\})", RegexOptions.Singleline);
                template = regex.Replace(template, String.Empty);
                template = template.Replace("{%START_REMOVE_COMBO_EMAIL%}", String.Empty);
                template = template.Replace("{%STOP_REMOVE_COMBO_EMAIL%}", String.Empty);
            }

            return template;
        }
    }
}
