#if DEBUG
//#define TestBesonderenArtikel
//#define SKIP_DOWNLOAD
#endif
using ArtikelUpdateOpencart.Import.Models;
using CsvHelper;
using CsvHelper.Configuration;
using Serilog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Email;

namespace ArtikelUpdateOpencart.Import
{
    public class LieferantenImportWerdDk : LieferantenImportBase<WerdDkArtikel>
    {
        public const int LIEFERANTENNUMMER = 71325;
        public LieferantenImportWerdDk(string downloadUrl, ILogger logger) : base(LIEFERANTENNUMMER, downloadUrl, logger)
        {

        }
        public override async Task DownloadAsync()
        {
            string datei = Path.Combine(GlobalConfig.W4TmpFolderSrv01, "WerdDK.csv");

#if !SKIP_DOWNLOAD
            for (int i = 0; i < 20; i++)
            {
                try
                {
                    FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://karley.de/WERD.csv");
                    request.Method = WebRequestMethods.Ftp.DownloadFile;
                    request.Credentials = new NetworkCredential("werddkpreisliste", "xCArcNW(B9#d~FvMV)G>,]@{ih}j+^");
                    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
                    Stream responseStream = response.GetResponseStream();
                    StreamReader reader = new StreamReader(responseStream, Encoding.Default, true);
                    StreamWriter myFile = new StreamWriter(datei, false, Encoding.Default); //Properties.Settings.Default.AppPfad
                    myFile.Write(reader.ReadToEnd());
                    reader.Close();
                    response.Close();
                    myFile.Close();

                    i = 20;
                }
                catch (Exception)
                {

                    if (i == 19)
                    {
                        await EmailController.FehlerMailSendenAsync("WerdDK Download Fehler", "Fehler beim runterladen der Datei, Lieferantenupdate wurde abgebrochen.");
                        Environment.Exit(0);
                    }
                    else
                    {
                        await Task.Delay(60000); // 1 Minute warten
                    }
                }
            }
#endif
            using (TextReader reader = new StreamReader(datei))
            {
                CsvConfiguration configuration = new CsvConfiguration(CultureInfo.GetCultureInfo("de-DE"));
                configuration.BadDataFound = null;
                configuration.TrimOptions = TrimOptions.Trim;
                configuration.HasHeaderRecord = false;

                using (var csv = new CsvReader(reader, configuration))
                {
                    ArtikeldatenLieferant = csv.GetRecords<WerdDkArtikel>().ToList();
                }
            }

        }

        public override async Task RunAsync()
        {
            using FbController2 fbController = new FbController2();
            List<string> vorhanden_hersteller = await GetVorhandeneHerstellerAsync(fbController).ToListAsync();
            HerstellerErsetzen ersetzen = await HerstellerErsetzen.CreateAsync();
            int zähler = 0;
            foreach (var artikel in ArtikeldatenLieferant)
            {
                ++zähler;
                Console.Write("\r{0}/{1}\t", zähler, ArtikeldatenLieferant.Count);

#if TestBesonderenArtikel
                if (!artikel.Artikelnummer.Equals("XXX", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
#endif

                // Wir wollen nur Artikel die den Status In Stock haben
                if (artikel.Status != "In Stock")
                {
                    continue;
                }

                // Überprüft ob der Hersteller in der W4 existiert
                if (!vorhanden_hersteller.Contains(ersetzen.GetHerstellerErsetzt(artikel.Hersteller)))
                {
                    continue;
                }

                // Überprüft ob der Artikel in IgnoreLieferantenArtikel.txt steht
                if (ersetzen.IsArtikelIgnored(artikel.Artikelnummer, LIEFERANTENNUMMER))
                {
                    continue;
                }

                /*
                 07.12.2020 Scholz: WerdDK ist immer günstig, ungewöhnlich für unseren Bereich. Darum wenn deren Preis unter unserem MinEK liegt, dann preis = MinEK-10 
                 */
                string? artikelnummer = await GetArtikelnummerAsync(artikel, fbController);
                string descAdd = "";
                if (artikelnummer != null)
                {
                    decimal minpreis = await GetMinEinkaufspreisAsync(artikelnummer, fbController);
                    if (minpreis > 0.0m)
                    {
                        if (artikel.Preis < (minpreis - 10.0m))
                        {
                            descAdd = "(Original Preis: " + artikel.Preis.ToString() + " EUR)";
                            artikel.Preis = minpreis - 10.0m;
                        }
                    }
                }

                GlobalLieferantenArtikel lieferantenArtikel = new GlobalLieferantenArtikel()
                {
                    LieferantenId = LIEFERANTENNUMMER,
                    Bestellnummer = artikel.Artikelnummer,
                    NettoEinkaufspreis = artikel.Preis,
                    Hersteller = artikel.Hersteller,
                    Herstellernummer = artikel.Artikelnummer,
                    Kurzbezeichnung = $"{artikel.ArtikelBeschreibung} {descAdd}",
                    Lagerbestand = artikel.Menge,
                    Versandkosten = 0m,
                    Mindestbestellmenge = 1,
                    EAN = artikel.EAN,
                };


                await LieferantenUpdateGlobalAsync(lieferantenArtikel, ersetzen, fbController, _logger);
            }
            await DeleteInaktiveLieferantenartikelAsync(LIEFERANTENNUMMER, fbController);
        }

        private async Task<string?> GetArtikelnummerAsync(WerdDkArtikel artikel, FbController2 fbController)
        {
            string sql = "SELECT FIRST 1 ARTI_A_NR FROM ARTIKEL WHERE (UPPER(ARTI_A_HERST_NR) = @HERSTELLERNUMMER AND UPPER(ARTI_A_HERSTELLER) LIKE @HERSTELLERNAME AND ARTI_A_HERST_NR != '' AND ARTI_A_HERST_NR is not null AND ARTI_A_HERSTELLER != '' AND ARTI_A_HERSTELLER is not null AND UPPER(ARTI_A_HERSTELLER) != @KARLEY AND UPPER(ARTI_A_HERSTELLER) != @DIVERS ) OR (ARTI_A_EAN = @EAN AND ARTI_A_EAN != '' AND ARTI_A_EAN is not null)";
            
            fbController.AddParameter("@HerstellerName", $"{artikel.Hersteller.ToUpper()}%");
            fbController.AddParameter("@HERSTELLERNUMMER", artikel.Artikelnummer.ToUpper().Length > 30 ? artikel.Artikelnummer.ToUpper().Remove(29) : artikel.Artikelnummer.ToUpper());
            fbController.AddParameter("@DIVERS", "DIVERS");
            fbController.AddParameter("@KARLEY", "KARLEY");
            fbController.AddParameter("@EAN", artikel.EAN);

            string? artikelnummer = await fbController.FetchObjectAsync(sql) as string;

            return artikelnummer;
        }

        private async Task<decimal> GetMinEinkaufspreisAsync(string artikelnummer, FbController2 fbController)
        {
            fbController.AddParameter("@ARLI_A_ARTIKELNR", artikelnummer);
            fbController.AddParameter("@ARLI_N_LIEFNR", LIEFERANTENNUMMER);
            decimal preis = Convert.ToDecimal(await fbController.FetchObjectAsync("SELECT CASE WHEN MIN(ARLI_N_PREIS) IS NULL THEN 0 ELSE MIN(ARLI_N_PREIS) END as minimum FROM LIEFERANTENARTIKEL WHERE ARLI_A_ARTIKELNR = @ARLI_A_ARTIKELNR AND ARLI_N_LIEFNR != @ARLI_N_LIEFNR"));
            return preis;
        }
    }
}
