using MySql.Data.MySqlClient;
using Serilog;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Email;
using WK5.Core.Models;

namespace KarleyUpdate
{
    internal static class LangeNichtUpgedatet
    {
        public static async Task RunAsync(ILogger logger)
        {
            using FbController2 fbController = new FbController2();
            DataTable alteArtikel = new DataTable(); // Alles unsortiert
            DataTable alteArtikelBearbeitet = new DataTable(); // Alles sortiert

            alteArtikelBearbeitet.Columns.Add("ARTIKELNUMMER");
            alteArtikelBearbeitet.Columns.Add("BESCHREIBUNG");
            alteArtikelBearbeitet.Columns.Add("LIEFERANTEN_NUMMER");
            alteArtikelBearbeitet.Columns.Add("LETZTES_DATUM");

            string[] blockierteArtikel = { "T1", "DIVERS" };
            string[] blockierteLieferanten = { "70246" };
            DateTime olderThan = DateTime.Now.AddYears(-1);
            bool alteLieferantenAnzeigen = false;

            List<string> allelieferantenIDS = new List<string>(); // Speichert alle gefundenen Lieferanten IDS zwischen

            string SQL = @"SELECT
                    A.ARTI_A_NR AS ARTIKELNUMMER, 
                    A.ARTI_A_BEZ1 AS BESCHREIBUNG_1, 
                    A.ARTI_A_BEZ2 AS BESCHREIBUNG_2, 
                    A.ARTI_A_BEZ3 AS BESCHREIBUNG_3, 
                    A.ARTI_A_BEZ4 AS BESCHREIBUNG_4, 
                    A.ARTI_A_BEZ5 AS BESCHREIBUNG_5, 
                    LIST(LF.LIEF_N_NR) AS LIEFERANTEN_NUMMERN,
                    MAX(LFA.ARLI_D_LETZAEND) AS LETZTES_DATUM
                    FROM ARTIKEL A
                    LEFT JOIN LIEFERANTENARTIKEL LFA ON A.ARTI_A_NR = LFA.ARLI_A_ARTIKELNR
                    LEFT JOIN LIEFERANTEN LF ON LF.LIEF_N_NR = LFA.ARLI_N_LIEFNR
                    WHERE A.ARTI_L_INAKTIV = 'N' AND COALESCE(LFA.ARLI_A_BESTELLNR,'') != '' AND WK5_ARTI_L_ANFRAGEARTIKEL = 'N' ";

            // Blockierte Artikel
            if (blockierteArtikel != null && blockierteArtikel.Length > 0)
            {
                SQL += " AND A.ARTI_A_NR NOT IN('" + String.Join("','", blockierteArtikel.ToArray()) + "')";
            }
            // Blockierte Lieferanten
            if (blockierteLieferanten != null && blockierteLieferanten.Length > 0)
            {
                SQL += " AND LF.LIEF_N_NR NOT IN (" + String.Join(",", blockierteLieferanten.ToArray()) + ")";
            }

            SQL += @" AND A.ARTI_L_LAGERFUEHR = 'Y'
                    AND(SELECT AW.ARWE_N_BESTAND FROM ARTIKELWERTE AS AW WHERE AW.ARWE_A_NR = A.ARTI_A_NR) = 0
                    AND(SELECT AW.ARWE_N_BESTAND FROM ARTIKELWERTE AS AW WHERE AW.ARWE_A_NR = A.ARTI_A_NR) = 0
                    AND A.ARTI_A_NR NOT LIKE 'SO-%'";
            if (alteLieferantenAnzeigen)
            {
                SQL += " AND LFA.ARLI_D_LETZAEND < @OLDERTHAN";
            }

            SQL += " GROUP BY ARTIKELNUMMER,BESCHREIBUNG_1, BESCHREIBUNG_2, BESCHREIBUNG_3, BESCHREIBUNG_4, BESCHREIBUNG_5";

            if (!alteLieferantenAnzeigen)
            {
                SQL += " HAVING MAX(LFA.ARLI_D_LETZAEND) < @OLDERTHAN";
            }

            SQL += " ORDER BY A.ARTI_A_NR ASC";

            fbController.AddParameter("@OLDERTHAN", olderThan);
            alteArtikel = await fbController.SelectDataAsync(SQL);

            // Hole alle unterschiedlichen Lieferanten Nummern
            foreach (DataRow row in alteArtikel.Rows)
            {
                string[] lieferantenIDS = row["LIEFERANTEN_NUMMERN"].ToString().Split(',');
                foreach (string lieferantID in lieferantenIDS)
                {
                    if (!allelieferantenIDS.Contains(lieferantID))
                    {
                        allelieferantenIDS.Add(lieferantID);
                    }
                }
            }
            allelieferantenIDS.Sort();

            // Hole Rows
            foreach (string LIEFERANTEN_NUMMER in allelieferantenIDS)
            {
                // Suche Rows nach mit Lieferantennummer
                var sucheRows =
                    from DataRow sucheRow in alteArtikel.Rows
                    where sucheRow["LIEFERANTEN_NUMMERN"].ToString().Contains(LIEFERANTEN_NUMMER)
                    select sucheRow;

                // Rows einfügen
                foreach (DataRow row in sucheRows)
                {

                    string beschreibung = "";
                    // Muss vorher auf NULL geprüft werden, da ansonsten die Beschreibung falsch zusammengestellt wird
                    beschreibung += row.Field<string>("BESCHREIBUNG_1") ?? string.Empty;
                    beschreibung += row.Field<string>("BESCHREIBUNG_2") ?? string.Empty;
                    beschreibung += row.Field<string>("BESCHREIBUNG_3") ?? string.Empty;
                    beschreibung += row.Field<string>("BESCHREIBUNG_4") ?? string.Empty;
                    beschreibung += row.Field<string>("BESCHREIBUNG_5") ?? string.Empty;

                    alteArtikelBearbeitet.Rows.Add(row["ARTIKELNUMMER"].ToString(), beschreibung, LIEFERANTEN_NUMMER, row["LETZTES_DATUM"].ToString());
                }
            }

            foreach (string LIEFERANTEN_NUMMER in allelieferantenIDS)
            {

                SQL = @"SELECT LF.LIEF_A_NAME1, LF.LIEF_A_NAME2, LF.LIEF_A_EMAIL FROM LIEFERANTEN LF WHERE LF.LIEF_N_NR = @LIEFERANTEN_NUMMER";
                Lieferant lieferant = await Lieferant.GetLieferantAsync(Convert.ToInt32(LIEFERANTEN_NUMMER));
                string LIEFERANTEN_NAME = lieferant.LIEF_A_LIEFNAME1 + lieferant.LIEF_A_LIEFNAME2;
                string LIEFERANTEN_EMAIL = lieferant.LIEF_A_EMAIL;
                string LIEFERANTEN_ARTIKELNUMMER = "";
                string LIEFERANTEN_ALTER_EK = "";
                string LIEFERANTEN_PREIS_WAEHRUNG = "";
                string LIEFERANTEN_EK_WAEHRUNG = "";


                string mailText = "Lieber Mitarbeiter," + Environment.NewLine + Environment.NewLine;
                mailText += @"folgend eine Liste von Produkten, bei denen nicht automatisch die Preise upgedatet werden. 
Bitte überprüfe diese Artikel (Unsere Artikelnummer ist in Klammern), ob wir Preislisten von den Lieferanten haben oder Zugänge um die Preise bzw. das Preisdatum zu aktualisieren" + Environment.NewLine;
                mailText += "-> Siehe Arbeitsanweisung http://wikis.local/wiki/doku.php?id=w4:artikel:artikelimport:meldungen:au0003" + Environment.NewLine + Environment.NewLine;
                mailText += "Unten stehende Mail könnt Ihr auch direkt an den Lieferanten senden (Copy & Paste, ohne diesen Text!) und nach Preislisten oder Preisaktualisierung zu fragen." + Environment.NewLine + Environment.NewLine;
                mailText += "Info: Artikel die bei Views im Shop -1 stehen haben, sind nicht im Online-Shop vorhanden." + Environment.NewLine;
                mailText += "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + Environment.NewLine;
                mailText += "Mailadresse: " + LIEFERANTEN_EMAIL + Environment.NewLine + Environment.NewLine;
                mailText += "Sehr geehrte Damen und Herren der Firma " + LIEFERANTEN_NAME + "," + Environment.NewLine + Environment.NewLine;
                mailText += @"Wir haben in der Vergangenheit folgende Artikel bei Ihnen bezogen und haben für diese keine aktuellen Preise oder Verfügbarkeit. Da wir unsere Listen
aktuell halten möchten, würde ich Sie bitten mir entweder eine Preisliste zu senden, oder aber mir aktuelle Preise und Verfügbarkeit für folgende Produkte mitzuteilen." + Environment.NewLine + Environment.NewLine;

                var sucheRows =
                    from DataRow sucheRow in alteArtikelBearbeitet.Rows
                    where sucheRow["LIEFERANTEN_NUMMER"].Equals(LIEFERANTEN_NUMMER)
                    select sucheRow;

                foreach (DataRow row in sucheRows)
                {


                    SQL = "SELECT LFA.ARLI_A_BESTELLNR, LFA.ARLI_N_PREIS, LFA.ARLI_A_WAEHRUNG, LFA.ARLI_N_WAEHRUNGSPREIS FROM LIEFERANTENARTIKEL LFA LEFT JOIN ARTIKEL ARTI ON LFA.ARLI_A_ARTIKELNR = ARTI.ARTI_A_NR WHERE LFA.ARLI_A_ARTIKELNR = @ARTIKELNUMMER AND ARTI.ARTI_L_INAKTIV = 'N'";


                    fbController.AddParameter("@ARTIKELNUMMER", row["ARTIKELNUMMER"]);
                    DataRow? row2 = await fbController.SelectRowAsync(SQL);

                    if (row2 is not null)
                    {
                        LIEFERANTEN_ARTIKELNUMMER = row2["ARLI_A_BESTELLNR"].ToString();
                        LIEFERANTEN_ALTER_EK = row2["ARLI_N_PREIS"].ToString();
                        LIEFERANTEN_EK_WAEHRUNG = row2["ARLI_A_WAEHRUNG"].ToString();
                        LIEFERANTEN_PREIS_WAEHRUNG = row2["ARLI_N_WAEHRUNGSPREIS"].ToString();
                    }


                    int CURRENT_VIEWS = 0;
                    Dictionary<DateTime, int> VIEWS_LAST_MONTHS = new Dictionary<DateTime, int>();


                    using MySqlController2 mySqlController = new MySqlController2();
                    // Hole die Views des Produkts aktuellen Monats von Online
                    try
                    {
                        mySqlController.AddParameter("@ARTIKELNUMMER", row["ARTIKELNUMMER"].ToString().ToUpper());
                        object? tmp = await mySqlController.FetchObjectAsync("SELECT `viewed` FROM `product` WHERE UPPER(`model`) = @ARTIKELNUMMER");

                        if (tmp is not null)
                        {
                            CURRENT_VIEWS = (int)tmp;
                        }
                        else
                        {
                            CURRENT_VIEWS = -1; // Artikel ist nicht im Shop
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        await EmailController.FehlerMailSendenAsync("Langenicht geupdated Fehler #1", "Fehler #1 beim Hole die Views des Produkts aktuellen Monats von Online, Lieferantenupdate wurde abgebrochen.");
                        Environment.Exit(0);
                    }




                    try
                    {
                        mySqlController.AddParameter("@ARTIKELNUMMER", row["ARTIKELNUMMER"].ToString().ToUpper());
                        DataTable data = await mySqlController.SelectDataAsync("SELECT * FROM `product_view_history` WHERE `product_id` = (SELECT `product_id` FROM `product` WHERE UPPER(`model`) = @ARTIKELNUMMER) ORDER BY `date` DESC LIMIT 3");

                        foreach (DataRow viewRow in data.Rows)
                        {
                            VIEWS_LAST_MONTHS.Add(Convert.ToDateTime(viewRow["date"]), Convert.ToInt32(viewRow["views"]));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        await EmailController.FehlerMailSendenAsync("Langenicht geupdated Fehler #2", "Fehler #2 beim Hole die Views des Produkts aktuellen Monats von Online, Lieferantenupdate wurde abgebrochen.");
                        Environment.Exit(0);
                    }


                    // Hole die Views des Produkts für die letzten 3 Monate von Online
                    mailText += "--------------------------------" + Environment.NewLine;
                    mailText += "Artikelnummer: " + LIEFERANTEN_ARTIKELNUMMER + " (Unsere Artikelnummer: " + row["ARTIKELNUMMER"].ToString() + ")" + Environment.NewLine;
                    mailText += "Bezeichnung : " + row["BESCHREIBUNG"].ToString().Replace('@', ' ') + Environment.NewLine; // In der Bezeichnung dürfen keine @ Zeichen vorkommen, da die Mail ansonsten korrupt wird.
                    mailText += "Alter EK: " + LIEFERANTEN_PREIS_WAEHRUNG + " " + LIEFERANTEN_EK_WAEHRUNG + Environment.NewLine;
                    mailText += "Views im Shop (Dieser Monat): " + CURRENT_VIEWS.ToString() + Environment.NewLine;



                    foreach (KeyValuePair<DateTime, int> entry in VIEWS_LAST_MONTHS)
                    {
                        mailText += "Views im Shop (" + entry.Key.Month + "/" + entry.Key.Year + "): " + entry.Value + Environment.NewLine;
                    }


                }
                mailText += Environment.NewLine + Environment.NewLine + @"Falls Sie uns für diese Artikel eine Online Schnittstelle z.B. per FTP anbieten können bei der wir täglich die verfügbaren Mengen und unsere Preise abholen können, zur Verfügung stellen können, so würden wir uns über Zugangsdaten freuen um so die Zusammenarbeit vereinfachen zu können.";
                mailText += Environment.NewLine + Environment.NewLine;
                mailText += "Mit freundlichen Grüßen," + Environment.NewLine + "(% Benutzer Name %)" + Environment.NewLine + Environment.NewLine;
                mailText += "Karley Deutschland GmbH" + Environment.NewLine + "Herner Str. 15b - 45657 Recklinghausen" + Environment.NewLine + "Tel: +49(0)2361 979 231 - 0" + Environment.NewLine + "Fax: +49(0)2361 979 231 - 90";


                string betreff = "Preisaktualisierung für Lieferanten " + LIEFERANTEN_NAME;

                EmailController emailController = new EmailController();
                emailController.Html = false;
                await emailController.SendenAsync(GlobalConfig.EmailShopverwalter, betreff, mailText);
            }
        }
    }
}
