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

namespace WK5.Core.Drucken.Bestellungen
{
    /// <summary>
    /// Stellt eine Vorlage zur Generierung eines PDFs aus einer Bestellung dar.
    /// </summary>
    public sealed class PrintBestellung : PrintBase
    {

        private readonly Bestellung _bestellung;
        private readonly string _displayName;
        private readonly PrintBestellungRegelsatz _regeln;
        private BestellungView _view;

        private PrintBestellung(Bestellung bestellung, string displayName)
        {
            _layoutFile = "Bestellung.html";
            _regeln = new PrintBestellungRegelsatz();
            _bestellung = bestellung;
            _displayName = displayName;
            _view = new BestellungView();
        }

        public override string Print(string speicherpfad)
        {
            string filename = $"BE_{_bestellung.Bestellnummer}.pdf";
#if CREATE_PREVIEW_HTML
            File.WriteAllText(Path.Combine(speicherpfad, $"PREVIEW_BE_{_bestellung.Bestellnummer}.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;
        }

        /// <summary>
        /// Initialisiert die <see cref="PrintBestellung"/>, sodass die Methode <see cref="Print(string)"/> aufgerufen werden kann.
        /// </summary>
        /// <returns></returns>
        protected override async Task InitializeAsync(FbController2 fbController)
        {
            fbController.AddParameter("@BEST_N_NR", _bestellung.Bestellnummer);
            var row = await fbController.SelectRowAsync("SELECT * FROM WK5_VIEW_BESTELLUNG WHERE BEST_N_NR = @BEST_N_NR");

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

            _view = ObjectErweiterung.DataRowZuObjekt(new BestellungView(), row);
            var tmp = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LAYOUT_PATH, _layoutFile);
            _template = await File.ReadAllTextAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LAYOUT_PATH, _layoutFile));
            SetRegeln();


            _template = await SetTemplateVariables();
        }

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


        /// <summary>
        /// Erstellt eine neue <see cref="PrintBestellung"/> für die angegebene Bestellung.
        /// </summary>
        /// <param name="bestellung"></param>
        /// <param name="displayName">Der Name des Mitarbeiters, der unter dem PDF stehen soll.
        /// <para>z.B. Marvin Klein</para></param>
        /// <returns></returns>
        public static async Task<PrintBestellung> CreateAsync(FbController2 fbController, Bestellung bestellung, string displayName)
        {
            var myClass = new PrintBestellung(bestellung, displayName);
            await myClass.InitializeAsync(fbController);
            return myClass;
        }

        protected override void SetRegeln()
        {
            _regeln.ShowEmail = !String.IsNullOrWhiteSpace(_view.LIEF_A_EMAIL) || !String.IsNullOrWhiteSpace(_view.LIEP_A_EMAIL);
            _regeln.ShowFax = !String.IsNullOrWhiteSpace(_view.LIEF_A_FAX) || !String.IsNullOrWhiteSpace(_view.LIEP_A_TELEFAX);
            _regeln.ShowRabatt = _view.BEST_N_RABATT > 0;
            _regeln.ShowKundennummer = !String.IsNullOrWhiteSpace(_view.BEST_A_LIEFERKUNDE);
            _regeln.ShowAnlieferstelle = !String.IsNullOrWhiteSpace(_view.BEST_A_LIEFERKUNDE) || _view.BEST_A_LIEFERKUNDELA > 0;
            _regeln.ShowFrachtkosten = _view.BEST_N_FRACHT > 0;
            _regeln.ShowVerpackung = _view.BEST_N_VERPACKUNG > 0;
            _regeln.ShowVersicherung = _view.BEST_N_VERSICHERUNG > 0;
            _regeln.ShowAngebotsnummer = !String.IsNullOrWhiteSpace(_view.BEST_A_ANGEBOTNR);
            _regeln.ShowAdresszeile2 = !String.IsNullOrWhiteSpace(_view.LIEF_A_PARTNER);
            _regeln.ShowAdresszeile3 = false;
            _regeln.ShowAdresszeile4 = false;
            _regeln.ShowAdresszeileLand = _view.LIEF_A_LAND is not null && !_view.LIEF_A_LAND.Equals("DE", StringComparison.OrdinalIgnoreCase);
        }

        protected override async Task<string> SetTemplateVariables()
        {

            StringBuilder posBuilder = new StringBuilder();
            int zähler = 0;
            foreach (var pos in _bestellung.Positionen.OrderBy(x => x.BEPO_N_POS))
            {
                bool positionIstText = pos.BEPO_A_ARTIKELNR.Equals("TEXT");

                if (!positionIstText)
                {
                    zähler++;
                }

                decimal rabatt1 = 0;
                decimal rabatt2 = 0;
                decimal preisMitRabatt = pos.BEPO_N_MENGE * pos.BEPO_N_PREIS;
                if (pos.BEPO_N_RABATTPROZ > 0)
                {
                    rabatt1 = preisMitRabatt - preisMitRabatt * (100 - pos.BEPO_N_RABATTPROZ) / 100;
                    preisMitRabatt -= rabatt1;
                }

                if (pos.BEPO_N_RABATTPROZ2 > 0)
                {
                    rabatt2 = preisMitRabatt - preisMitRabatt * (100 - pos.BEPO_N_RABATTPROZ2) / 100;
                    preisMitRabatt -= rabatt2;
                }


                posBuilder.AppendLine("<tr>");
                // Pos
                posBuilder.AppendLine($"\t<td class=\"nowrap text-center\">");
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t{zähler}");
                }
                posBuilder.AppendLine("\t</td>");

                // Artikelnummer + Bezeichnung
                posBuilder.AppendLine("\t<td>");
                if (!positionIstText)
                {
                    if (!String.IsNullOrWhiteSpace(pos.BEPO_A_BESTELLNUMMER))
                    {
                        posBuilder.AppendLine($"\t\t{pos.BEPO_A_BESTELLNUMMER}");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t{pos.BEPO_A_ARTIKELNR}");
                    }
                }
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t<span class=\"font-weight-bold d-block\">Unsere Artikelnummer: {pos.BEPO_A_ARTIKELNR}</span>");
                    posBuilder.AppendLine($"\t\t<p>{pos.GetBezeichnung()}</p>");
                }
                posBuilder.AppendLine($"\t\t<p>{pos.BEPO_A_NOTIZ?.Trim().Replace("\r\n", "<br />")}</p>");
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t<span class=\"font-weight-bold d-block\">Spätester Liefertermin: {pos.BEPO_D_LIEFERDAT.ToShortDateString()}</span>");
                }
                posBuilder.AppendLine("\t</td>");

                // Menge
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t{pos.BEPO_N_MENGE} {pos.BEPO_A_MASSEINHEIT}");
                }
                posBuilder.AppendLine("\t</td>");

                // VK-Preis
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t{pos.BEPO_N_PREIS:0.00}");
                }
                posBuilder.AppendLine("\t</td>");

                // Rabatt
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!positionIstText)
                {
                    if (rabatt1 > 0 && rabatt2 > 0)
                    {
                        posBuilder.AppendLine($"\t\t{pos.BEPO_N_RABATTPROZ:0.00}<br />");
                        posBuilder.AppendLine($"\t\t+ {pos.BEPO_N_RABATTPROZ2:0.00}");
                    }
                    else if (rabatt1 > 0)
                    {
                        posBuilder.AppendLine($"\t\t{pos.BEPO_N_RABATTPROZ:0.00}");
                    }
                    else if (rabatt2 > 0)
                    {
                        posBuilder.AppendLine($"\t\t{pos.BEPO_N_RABATTPROZ2:0.00}");
                    }
                }
                posBuilder.AppendLine("\t</td>");

                // Preis mit Rabatt
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t{pos.PreisMitRabatt:0.00}");
                }
                posBuilder.AppendLine("\t</td>");

                // Gesamt
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!positionIstText)
                {
                    posBuilder.AppendLine($"\t\t{pos.PreisMitRabatt * pos.BEPO_N_MENGE:0.00}");
                }
                posBuilder.AppendLine("\t</td>");

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


            using FbController2 fbController = new FbController2();
            Land? land = await Land.GetLandAsync(_view.LIEF_A_LAND, fbController);

            string abrufbestellungText = String.Empty;

            if (_bestellung.IstAbrufbestellung)
            {
                abrufbestellungText = $"<span class=\"d-block font-weight-bold h4\">XXX ACHTUNG ABRUFAUFTRAG, bitte nur gemäß Abruf ausliefern, nicht gesamt XXX</span>";
            }


            _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("{{ BESTELLNUMMER }}", _bestellung.Bestellnummer.ToString())
                .Replace("{{ DATUM }}", _bestellung.Belegdatum.ToShortDateString())
                .Replace("{{ ANGEBOT_NR }}", _view.BEST_A_ANGEBOTNR ?? String.Empty)
                .Replace("{{ LIEFERANT_NR }}", _bestellung.LieferantenId.ToString())
                .Replace("{{ KUNDENNUMMER }}", _view.BEST_A_LIEFERKUNDE)
                .Replace("{{ ZAHLUNGSBEDINGUNG }}", _view.GetZahlungsbedingung())
                .Replace("{{ LIEFERBEDINGUNG }}", _view.LIBD_A_TEXT1)
                .Replace("{{ ADDRESSZEILE1 }}", _view.LIEF_A_NAME1)
                .Replace("{{ ADDRESSZEILE2 }}", _view.LIEF_A_PARTNER ?? String.Empty)
                .Replace("{{ ADDRESSZEILE3 }}", string.Empty)
                .Replace("{{ ADDRESSZEILE4 }}", string.Empty)
                .Replace("{{ EMP_LAND }}", land?.LAND_A_NAME ?? _view.LIEF_A_LAND ?? String.Empty)
                .Replace("{{ EMP_PLZ }}", _view.LIEF_A_PLZ)
                .Replace("{{ EMP_ORT }}", _view.LIEF_A_ORT)
                .Replace("{{ EMP_STRASSE }}", _view.LIEF_A_STR ?? String.Empty)
                .Replace("{{ EMAIL }}", _view.GetEmail())
                .Replace("{{ FAX }}", _view.GetFax())
                .Replace("{{ RABATT }}", (-_view.BEST_N_RABATT).ToString("0.00"))
                .Replace("{{ ANLIEFERSTELLE }}", _view.GetAnlieferadresse())
                .Replace("{{ POSITIONEN }}", posBuilder.ToString())
                .Replace("{{ SUMME_EINZELPREISE }}", (_view.BEST_N_NETTO - _view.BEST_N_RABATT).ToString("0.00"))
                .Replace("{{ FRACHTKOSTEN }}", _view.BEST_N_FRACHT.ToString("0.00"))
                .Replace("{{ VERPACKUNG }}", _view.BEST_N_VERPACKUNG.ToString("0.00"))
                .Replace("{{ VERSICHERUNG }}", _view.BEST_N_VERSICHERUNG.ToString("0.00"))
                .Replace("{{ GESAMT_NETTO }}", (_view.BEST_N_NETTO - _view.BEST_N_RABATT + _view.BEST_N_FRACHT + _view.BEST_N_VERPACKUNG + _view.BEST_N_VERSICHERUNG).ToString("0.00"))
                .Replace("{{ BELEGKOPF }}", StringErweiterung.RtfToString(_view.BEST_B_KOPFTEXT).Trim().Replace("\r\n", "<br />"))
                .Replace("{{ BELEGFUSS }}", StringErweiterung.RtfToString(_view.BEST_B_FUSSTEXT).Trim().Replace("\r\n", "<br />"))
                .Replace("{{ WAEHRUNG }}", _view.BEST_A_WAEHRUNG)
                .Replace("{{ MITARBEITER }}", _displayName)
                .Replace("{{ ABRUFBESTELLUNG }}", abrufbestellungText)
                ;


            return await Task.FromResult(_template);
        }
        /// <summary>
        /// Generiert die Style Section, die alle Klassen ausblendet, die durch <see cref="SetRegeln"/> festgelegt worden sind.
        /// </summary>
        /// <param name="regeln"></param>
        /// <returns></returns>
        protected override string GenerateDisplayCss()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<style>");
            if (!_regeln.ShowAnlieferstelle)
            {
                sb.AppendLine("\t.display-anlieferstelle {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowRabatt)
            {
                sb.AppendLine("\t.display-rabatt {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowKundennummer)
            {
                sb.AppendLine("\t.display-kundennummer {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowEmail)
            {
                sb.AppendLine("\t.display-email {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowFrachtkosten)
            {
                sb.AppendLine("\t.display-frachtkosten {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowVerpackung)
            {
                sb.AppendLine("\t.display-verpackung {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowVersicherung)
            {
                sb.AppendLine("\t.display-versicherung {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowFax)
            {
                sb.AppendLine("\t.display-fax {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

            if (!_regeln.ShowAngebotsnummer)
            {
                sb.AppendLine("\t.display-angebotsnummer {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }


            if (!_regeln.ShowAdresszeile2)
            {
                sb.AppendLine("\t.display-addresszeile2 {");
                sb.AppendLine("\t\tdisplay: none;");
                sb.AppendLine("\t}");
            }

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

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

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



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

            return sb.ToString();
        }


    }
}
