#if DEBUG
#define HappyShit
#define LIVE_ECO
//#define NobelHobel    
#define kleinHomeOffice
#endif

using Dapper;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using WK5.Core.Models;

namespace WK5.Core
{
    public static class GlobalConfig
    {
        // Datenbankwerte
        public const string W4ConnectionString = "initial catalog=w4;password=masterkey;user id=SYSDBA;data source=srv01";
        public const string W4LocalDebugConnectionString = "initial catalog=w4;password=masterkey;user id=SYSDBA;data source=localhost;";
        public const string NobelHobelMySQLConnectionString = "Database=karley_nobelhobel;Password=gRsu66_0;Port=3306;Server=nobel-hobel.de;User Id=nobeldbusr2018;SslMode=none;Convert Zero Datetime=True";
        public const string HappyShitMySQLConnectionString = @"Database=happyshit_db;Password=Jjy2r7&7;Port=3306;Server=happy-shit.de;User Id=happyshit_usr;SslMode=none;Convert Zero Datetime=True";
        public const string KarleyMySQLConnectionString = "Database=karley_shopdb3;Password=3BS4oKtcN$V$P7-y4Haa;Port=3306;Server=karley.de;User Id=ShopDB3User;SslMode=none;Convert Zero Datetime=True";
        public const string MachMichConnectionString = "Database=karley_shitdb;Password=$G0sx5x2;Port=3306;Server=mach-mich.de;User Id=ShitDBUser;SslMode=none;Convert Zero Datetime=True";
        public const string AufgabenConnectionString = "initial catalog=aufgaben;password=masterkey;user id=SYSDBA;data source=srv01";
        public const string ZeiterfassungConnectionString = "initial catalog=zeiterfassung;password=masterkey;user id=SYSDBA;data source=srv01";
        public const string LocalBackupKarleyMySQLConnectionString = "Database=KarleyBackupDB;Password=!DbUsrKarleyBack2019*;Port=3306;Server=192.168.0.247;User Id=backupDBUsr;SslMode=none;Convert Zero Datetime=True";
        public const string LocalBackupMachMichMySQLConnectionString = "Database=MachMichBackupDB;Password=!DbUsrKarleyBack2019*; Port=3306;Server=192.168.0.247;User Id=backupDBUsr;SslMode=none;Convert Zero Datetime=True";

#if DEBUG
        public const string KarleyApiDatabase = "Database=api_karley_v2;Password=$zKM$n=I7DLJ?%o*rAPPGu>6~+Gqy6:Lc(,nrnWE;Port=3306;Server=karley.de;User Id=karleyApi2;SslMode=none;Convert Zero Datetime=True";
#else
        public const string KarleyApiDatabase = "Database=api_karley_v2;Password=$zKM$n=I7DLJ?%o*rAPPGu>6~+Gqy6:Lc(,nrnWE;Port=3306;Server=karley.de;User Id=karleyApi2;SslMode=none;Convert Zero Datetime=True";
#endif

#if RELEASE
        public static string WWWRoot = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"));
#elif DEBUG
        public static string WWWRoot = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../", "wwwroot"));
#endif

        // ecoDMS
#if (DEBUG && LIVE_ECO) || RELEASE
        public const string ECODMS_BASIS_URL = "http://srv01:8180/api/";
#else
        public const string ECODMS_BASIS_URL = "http://localhost:8180/api/";
#endif
        public const string ECODMS_DEFAULT_USER = "ecodms:ecodms";

        public const string NICHT_ARCHIVIERTE_RECHNUNGEN_XML_FILE = @"\\srv01\daten\w4\tmp\NichtArchivierteDocs.xml";

        /// <summary>
        /// Stellt den Connection String für Mach-Mich oder Happy Shit zur Verfügung. Abhängig ob DEBUG oder RELEASE
        /// </summary>
#if !HappyShit
        public const string MachMichMysql = MachMichConnectionString;
#else
        public const string MachMichMysql = HappyShitMySQLConnectionString;
#endif

#if !NobelHobel
        public const string KarleyMySql = KarleyMySQLConnectionString;
#else
        public const string KarleyMySql = NobelHobelMySQLConnectionString;
#endif

        //Lokale PFade - bisher keine Debug Pfade
        public const string W4TmpFolder = @"\\srv01\Daten\w4\tmp";
        public const string W4TmpFolderSrv01 = @"\\srv01\Daten\W4\tmp";
        public const string LogFile = @"\\srv01\daten\w4\ArtikelUpdate_error.log";
        public const string AuftragsFreigabeLogFile = @"\\srv01\daten\w4\Auftragsfreigabe\Freigabe.log";
        public const string AuftragsFreigabeEmailLogFile = @"\\srv01\daten\\w4\FreigabeEmails.xml";




        //FTP
#if DEBUG
        public const string Karley_FTP_USER = "nobeladmin2018";
        public const string Karley_FTP_SERVER = "nobel-hobel.de";
        public const string Karley_FTP_PW = "^=Bpa>7B7&Ngyfj4";
        public const string Karley_FTP_SYNC_FOLDER = "FTP://www.nobel-hobel.de/httpdocs/sync/";
#else
        public const string Karley_FTP_USER = "karleyftpaccount";
        public const string Karley_FTP_SERVER = "karley.de";
        public const string Karley_FTP_PW = "Up_BFd6JkYvCtJ3L";
        public const string Karley_FTP_SYNC_FOLDER = "FTP://www.karley.de/httpdocs/sync/";
#endif

        //Email
        public const string EmailInfoEU = "info@karley.eu"; //Was an den Vertrieb geht
        public const string EmailInfoDe = "info@karley.de"; //vermutlich eher nur als Sender für interne Mails zu nutzen, aber .eu ist zu bevorzugen 
        public const string EmailLogsEU = "logs_de@karley.eu"; //geht nach Tobit in den Logs ordner
        public const string EmailShopverwalter = "shopverwaltung@karley.eu"; //


        //Allgemeine Konstanten
        [Obsolete("Die Konstante sollte nicht länger verwendet werden. Stattdessen sollte der Mwstsatz aus der Datenbank ausgelesen werden. Dadurch müssen die Programme nicht neu kompiliert werden")]
        public const double MwSt = 1.19;
        public const string TaskRunnerPassword = "S@oN=&w}2-P^";

        /* 
         * WK5 Config
         * Ordnet Variablen den entsprechenden Config Schlüssel zu
         */
        public const string ANZEIGELIMIT_CONFIG_NAME = "ANZEIGELIMIT";
        public const string SCANINPUT_PFAD_CONFIG_NAME = "SCANINPUT_PFAD";
        public const string STATS_SELEKTIONSERLOES_LAST_UPDATE_CONFIG_NAME = "STATS_SELEKTIONSERLOES_LAST_UPDATE";
        public const string LAGERREGAL_DEBUG_MODE_CONFIG_NAME = "LAGERREGAL_DEBUG_MODE";
        public const string WK5_VERSAND_PRINTER_CONFIG_NAME = "WK5_VERSAND_PRINTER";
        public const string WK5_ARCHIVPFAD_CONFIG_NAME = "WK5_ARCHIVPFAD";
        public const string GEWICHTSBERECHNER_VERSANDPREISLISTE_PFAD_CONFIG_NAME = "GEWICHTSBERECHNER_VERSANDPREISLISTE_PFAD";
        public const string SMTP_EXTERN_HOST_CONFIG_NAME = "SMTP_EXTERN_HOST";
        public const string SMTP_EXTERN_PASSWORD_CONFIG_NAME = "SMTP_EXTERN_PASSWORD";
        public const string SMTP_EXTERN_PORT_CONFIG_NAME = "SMTP_EXTERN_PORT";
        public const string SMTP_EXTERN_USER_CONFIG_NAME = "SMTP_EXTERN_USER";
        public const string SMTP_INTERN_HOST_CONFIG_NAME = "SMTP_INTERN_HOST";
        public const string SMTP_INTERN_PASSWORD_CONFIG_NAME = "SMTP_INTERN_PASSWORD";
        public const string SMTP_INTERN_PORT_CONFIG_NAME = "SMTP_INTERN_PORT";
        public const string SMTP_INTERN_USER_CONFIG_NAME = "SMTP_INTERN_USER";
        public const string VERSAND_MAILER_POLLS = "VERSAND_MAILER_POLLS";
        public const string VERSAND_MAILER_POLL_TIMEOUT = "VERSAND_MAILER_POLL_TIMEOUT";
        public const string WK5_LIVESHOP_DISABLED_CONFIG_NAME = "WK5_LIVESHOP_DISABLED";
        public const string WK5_ALWAYS_SEND_XRECHNUNG = "WK5_ALWAYS_SEND_XRECHNUNG";
        public const string ZAHLLIMIT_PRO_TAG_CONFIG_NAME = "ZAHLLIMIT_PRO_TAG";
        public const string GLAEUBIGER_IDENTIFIKATIONSNUMMER_CONFIG_NAME = "GLAEUBIGER_IDENTIFIKATIONSNUMMER";
        public const string ENABLE_B2C_CONFIG_NAME = "ENABLE_B2C";
        public const string AGB_PATH_CONFIG_NAME = "AGB_PATH";
        public const string AUFTRAG_STORNIEREN_BUCHHALTUNG_MAIL_CONFIG_NAME = "AUFTRAG_STORNIEREN_BUCHHALTUNG_MAIL";
        public const string AUFTRAG_STORNIEREN_DIRECT_PAYMENT_URL_CONFIG_NAME = "AUFTRAG_STORNIEREN_DIRECT_PAYMENT_URL";
        public const string DATEV_EXPORT_LAST_DATE_CONFIG_NAME = "DATEV_EXPORT_LAST_DATE";


        public const string PRINTER_LAGER_DOCUMENTS_CONFIG_NAME = "PRINTER_LAGER_DOCUMENTS";
        public const string PRINTER_DOCUMENTS_CONFIG_NAME = "PRINTER_DOCUMENTS";
        public const string PRINTER_ETIKETTEN_ARTIKEL_CONFIG_NAME = "PRINTER_ETIKETTEN_ARTIKEL";

        public const string NOTIFICATION_CHECK_INTERVAL_CONFIG_NAME = "NOTIFICATION_CHECK_INTERVAL";

#region Texte und Identifier
        // Text Identifier
        /// <summary>
        /// Ruft den Identifier zum abrufen der Texte für die Stornierung eines Auftrages ab.
        /// <para>Der Identifier kann an <see cref="TemplateText.GetTemplateTexteAsync(string, FbController2)"/> übergeben werden.</para>
        /// </summary>
        public const string IDENTIFIER_AUFTRAG_STORNIEREN = "STORNIERT_";
        /// <summary>
        /// Ruft den Identifier zum abrufen der Texte für die Rechnungsdruckformulare ab.
        /// </summary>
        public const string IDENTIFIER_RECHNUNGEN = "RECHNUNGEN_";

        // Text Identifier Keys
        public const string IDENTIFIER_KEY_STORNIERT_BUCHHALTUNG = "STORNIERT_BUCHHALTUNG";
        public const string IDENTIFIER_KEY_STORNIERT_BUCHHALTUNG_BANKDATEN = "STORNIERT_BUCHHALTUNG_BANKDATEN";
        public const string IDENTIFIER_KEY_STORNIERT_BUCHHALTUNG_BETREFF = "STORNIERT_BUCHHALTUNG_BETREFF";
        public const string IDENTIFIER_KEY_STORNIERT_KUNDE_BETREFF = "STORNIERT_KUNDE_BETREFF";
        public const string IDENTIFIER_KEY_STORNIERT_KUNDE_VORKASSE_BANKDATEN = "STORNIERT_KUNDE_VORKASSE_BANKDATEN";
        public const string IDENTIFIER_KEY_STORNIERT_KUNDE_VORKASSE_DIRECT_PAYMENT = "STORNIERT_KUNDE_VORKASSE_DIRECT_PAYMENT";
        public const string IDENTIFIER_KEY_STORNIERT_KUNDE_VORKASSE_KEINE_BANKDATEN = "STORNIERT_KUNDE_VORKASSE_KEINE_BANKDATEN";
        public const string IDENTIFIER_KEY_STORNIERT_LIEFERANT = "STORNIERT_LIEFERANT";
        public const string IDENTIFIER_KEY_STORNIERT_LIEFERANT_MIT_AUFTRAGSBESTAEGIGUNG = "STORNIERT_LIEFERANT_MIT_AUFTRAGSBESTAEGIGUNG";
        public const string IDENTIFIER_KEY_STORNIERT_LIEFERANT_BETREFF = "STORNIERT_LIEFERANT_BETREFF";

        public const string IDENTIFIER_KEY_RECHNUNGEN_DE = "RECHNUNGEN_DE";
        public const string IDENTIFIER_KEY_RECHNUNGEN_EU_MIT_MWST = "RECHNUNGEN_EU_MIT_MWST";
        public const string IDENTIFIER_KEY_RECHNUNGEN_EU_OHNE_MWST = "RECHNUNGEN_EU_OHNE_MWST";
        public const string IDENTIFIER_KEY_RECHNUNGEN_DRITTLAND = "RECHNUNGEN_DRITTLAND";
        public const string IDENTIFIER_KEY_RECHNUNGEN_EU_MIT_MWST_EN = "RECHNUNGEN_EU_MIT_MWST_EN";
        public const string IDENTIFIER_KEY_RECHNUNGEN_EU_OHNE_MWST_EN = "RECHNUNGEN_EU_OHNE_MWST_EN";
        public const string IDENTIFIER_KEY_RECHNUNGEN_DRITTLAND_EN = "RECHNUNGEN_DRITTLAND_EN";
#endregion

        public static AppConfiguration Configuration;
        static GlobalConfig()
        {
            //Wichtig - will man für z.B. Homeoffice weitere Einstellungen, dann hier rein - werden von oben nach unten überschrieben
            var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            var builder = new ConfigurationBuilder()
                .AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appSettings.json"), false, true)
                .AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"appSettings.{environmentName}.json"), true, true)
                .AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"appSettings.klein.json"), true, true)
                .Build();

            Configuration = new AppConfiguration(builder);
        }

        //
        // Die GetConfig Funktionen sollten nicht mehr verwendet werden.
        // Neue Einstellungen ausschließlich in appsettings!!!!
        //
        //


        /// <summary>
        /// Ruft die Value für einen Konfigurationsschlüssel aus der Datenbank ab. Am besten nicht mehr nutzen
        /// </summary>
        /// <param name="CONF_A_KEY"></param>
        /// <returns></returns>
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden. Verwenden Sie stattdessen GetConfigAsync")]
        public static object? GetConfig(string CONF_A_KEY)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@CONF_A_KEY", CONF_A_KEY);

            var data = fbController.SelectRow("SELECT FIRST 1 CONF_A_VALUE FROM WK5_CONFIG WHERE CONF_A_KEY = @CONF_A_KEY");
            return data?["CONF_A_VALUE"];
        }

        [Obsolete("Bitte verwenden Sie stattdessen GetConfigAsync(string, FbController2)")]
        public static async Task<string> GetConfigAsync(string CONF_A_KEY)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@CONF_A_KEY", CONF_A_KEY);

            DataRow? row = await fbController.SelectRowAsync("SELECT FIRST 1 CONF_A_VALUE FROM WK5_CONFIG WHERE CONF_A_KEY = @CONF_A_KEY");
            if (row is not null)
            {
                return row.Field<string>("CONF_A_VALUE") ?? String.Empty;
            }
            else
            {
                return String.Empty;
            }
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static async Task<string> GetConfigAsync(string CONF_A_KEY, FbController2 fbController)
        {
            fbController.AddParameter("@CONF_A_KEY", CONF_A_KEY);

            DataRow? row = await fbController.SelectRowAsync("SELECT FIRST 1 CONF_A_VALUE FROM WK5_CONFIG WHERE CONF_A_KEY = @CONF_A_KEY");
            if (row is not null)
            {
                return row.Field<string>("CONF_A_VALUE") ?? String.Empty;
            }
            else
            {
                return String.Empty;
            }
        }

        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static async Task<DateTime> GetDatevExportLastDateAsync()
        {
            string value = await GetConfigAsync(DATEV_EXPORT_LAST_DATE_CONFIG_NAME);

            DateTime.TryParse(value, out DateTime lastDate);

            return lastDate;
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static string GetDocumentPrinter()
        {
            if (GetConfig(PRINTER_DOCUMENTS_CONFIG_NAME) is not string pfad)
            {
                throw new ArgumentNullException(nameof(pfad));
            }

            return pfad;
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static string GetDocumentPrinterLager()
        {
            if (GetConfig(PRINTER_LAGER_DOCUMENTS_CONFIG_NAME) is not string pfad)
            {
                throw new ArgumentNullException(nameof(pfad));
            }

            return pfad;
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static string GetArtikeletikettenPrinter()
        {
            if (GetConfig(PRINTER_ETIKETTEN_ARTIKEL_CONFIG_NAME) is not string pfad)
            {
                throw new ArgumentNullException(nameof(pfad));
            }

            return pfad;
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static decimal GetZahllimitProTag()
        {
            object? res = GetConfig(ZAHLLIMIT_PRO_TAG_CONFIG_NAME);
            if (res is null)
            {
                return 20000;
            }
            else if (decimal.TryParse(res.ToString(), out decimal limit))
            {
                return limit;
            }
            else
            {
                return 20000;
            }
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static async Task<string> GetAgbPathAsync()
        {
            string agbPfad = await GetConfigAsync(AGB_PATH_CONFIG_NAME);

            if (!File.Exists(agbPfad))
            {
                throw new FileNotFoundException(agbPfad);
            }

            return agbPfad;
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static async Task<bool> UpdateConfig(string key, object value)
        {
            if (key is null)
            {
                throw new ArgumentNullException($"{nameof(key)} darf nicht null sein.");
            }

            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@KEY", key.ToUpper());
            fbController.AddParameter("@VALUE", value);
            try
            {
                await fbController.QueryAsync($"UPDATE OR INSERT INTO WK5_CONFIG (CONF_A_KEY, CONF_A_VALUE) VALUES (@KEY, @VALUE)");
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static int GetPageLimit()
        {
            object? res = GetConfig(ANZEIGELIMIT_CONFIG_NAME);
            if (res is null)
            {
                return 30;
            }
            else if (int.TryParse(res.ToString(), out int limit))
            {
                return limit;
            }
            else
            {
                return 30;
            }
        }
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static async Task<int> GetConfigNumber(string key, int fallbackValue)
        {
            object? res = await GetConfigAsync(key);
            if (res is null)
            {
                return fallbackValue;
            }
            else if (int.TryParse(res.ToString(), out int limit))
            {
                return limit;
            }
            else
            {
                return fallbackValue;
            }
        }

        /// <summary>
        /// Ruft das Datum des Letzten Updates des Selektionserlös aus der Config ab.
        /// </summary>
        /// <returns></returns>
        [Obsolete("Diese Methode sollte nicht mehr verwendet werden.")]
        public static DateTime GetStatsSelektionsmerkmalErloesLastUpdate()
        {
            object? res = GetConfig(STATS_SELEKTIONSERLOES_LAST_UPDATE_CONFIG_NAME);

            if (res == null)
            {
                return new DateTime();
            }
            else if (DateTime.TryParse(res.ToString(), out DateTime last_update))
            {
                return last_update;
            }
            else
            {
                return new DateTime();
            }
        }

        public static List<string> LänderDeutscheEmails => new List<string>() { "DE", "CH", "AT", "BE", "LU" }; // Diese Länder von Lieferanten erhalten deutsche E-Mails
        /// <summary>
        /// Ruft alle Efta Länder ab. Diese werden ohne Mehrwerststeuer beliefert.
        /// </summary>
        public static List<string> EftaLänder => new List<string>() { "LI", "IS", "NO", "CH" };

        public static List<string> DachLächer = new List<string> { "DE", "AT", "CH" };

        /// <summary>
        /// Ruft eine Liste mit Endungen von Freemail-Providern ab.
        /// </summary>
        public static List<string> Freemails { get; } = new List<string>()
        {
          "aol.com", "aol.de", "freenet.de", "gmail.com", "gmx.at", "gmx.com",
          "gmx.de", "gmx.net", "googlemail.com", "hotmail.com", "hotmail.de",
          "icloud.com", "live.de", "online.de", "outlook.com", "outlook.de",
          "t-online.com", "t-online.de", "web.de", "yahoo.co", "yahoo.com", "yahoo.de",
          "yandex.com", "yandex.ru", "ymail.com", "yopmail.com","gmx.eu"
        };
        /// <summary>
        /// Ruft eine Liste mit Artikeln ab, die in einem Beleg zugewiesen sein können, allerdings nicht als eigenständiger Artikel in der W4 existieren.
        /// </summary>
        public static List<string> ZusatzPositionenNichtInW4 => new List<string>()
        {
            "NACHNAME", "MINDER", "DISCOUNT", "TEXT", "T1"
        };

        public static List<string> AutomatischBuchen => new List<string>()
        {
            "NACHNAME", "MINDER", "DISCOUNT", "T1", "VERSAND"
        };
    }
}
