
using Microsoft.Data.Sqlite;
using System.Collections;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows;
using System.Globalization;

namespace Aborea_Projekt
{
    internal class MainWindow_Controler
    {
        internal List<Tuple<string, double, double, string>> GetComboboxInhalt()
        {
            // Ruft eine LinkedList (verkettete Liste) von Rüstungsarten aus der Datenbank ab.
            LinkedList<Rüstungsart> rList = Datenbank.GetRüstungsarten();
            // Ruft eine LinkedList (verkettete Liste) von Gegenständen aus der Datenbank ab.
            LinkedList<Gegenstände> gList = Datenbank.GetGegenstände();

            // Erstellt eine Liste von Tuple-Objekten, um die Daten zu speichern.
            // Das Tuple speichert drei Werte: Name (string), Kosten (double), Gewicht (double).
            List<Tuple<string, double, double,string>> tList = new List<Tuple<string, double, double,string>>();

            // Arbeitet sich durch die Liste von Rüstungsarten (rList).
            if (rList.First == null) throw new Exception("Das sollte nicht Null sein");

            LinkedListNode< Rüstungsart > x = rList.First;// Start bei der ersten Rüstungsart.
            bool end = false; // Kontrollvariable für die Schleife.
            while (end == false)// Schleife läuft, bis alle Elemente durchgegangen sind.
            {
                // Holt das aktuelle Element aus der Liste.
                if (x.Value == null) throw new Exception("Das sollte nicht Null sein");
                Rüstungsart a = x.Value;
              
                // Erstelle den String basierend auf den Werten der Rüstungsart.
                string funktion = $"Manöver Bonus: {a.Manöver}, Mindes Stärke: {a.minStärke}, Rüstungs Bonus: {a.RüstungBonus}";

                // Fügt ein neues Tuple mit den Eigenschaften der Rüstungsart in die Liste ein.
                tList.Add(new Tuple<string, double, double, string>(a.Name, a.KostenTT, a.Gewicht,funktion));
                // Wenn nicht das letzte Element, gehe zum nächsten Element.
                if (x != rList.Last)
                {
                    if (x.Next == null) throw new Exception("Das sollte nicht Null sein");
                    x = x.Next;
                }
                else
                {
                    end = true;// Schleife beenden, wenn das letzte Element erreicht wurde.
                }
            }

            // Wiederholt denselben Prozess für die Liste von Gegenständen (gList)
            if (gList.First == null) throw new Exception("Das sollte nicht Null sein");
            LinkedListNode<Gegenstände> y = gList.First;
            end = false;// Kontrollvariable für die neue Schleife zurücksetzen.
            while (end == false)
            {
                Gegenstände a = y.Value;
                tList.Add(new Tuple<string, double, double,string>(a.Name, a.KostenTT, a.Gewicht,a.Funktion));
                if (y != gList.Last)
                {
                    if (y.Next == null) throw new Exception("Das sollte nicht Null sein");
                    y = y.Next;
                }
                else
                {
                    end = true;
                }
            }

            // Sortiert die Liste nach den Tupel-Werten. (Die Standard-Sortierung von Tuple verwendet lexikographische Reihenfolge.)
            tList.Sort();
            // Gibt die sortierte Liste zurück.
            return tList;
        }
        internal void InitMainWindow()
        {
            // Platzhalter-Methode für die Initialisierung des Hauptfensters.
            throw new NotImplementedException(); // Bedeutet, dass die Methode noch nicht implementiert ist.
        }

        public Tuple<double, double> AuswahlSpeichern( int MengeAuswahl, double artikelGewicht,double artikelKosten, double HändlerProzentsatz)
        {
            // Berechnung der Gesamtkosten
            double gesKosten = artikelKosten * MengeAuswahl;
            if (HändlerProzentsatz != 0)
            { 
                double Aufschlag = gesKosten * HändlerProzentsatz /100;
                gesKosten += Aufschlag;
            }
            
            // Berechnung des Gesamtgewichts
            double gesGewicht = artikelGewicht * MengeAuswahl;


            // Rückgabe eines Tuple-Objekts mit den berechneten Werten
            return Tuple.Create(Math.Round(gesKosten, 2), Math.Round(gesGewicht, 2));

        }

        internal string KomplettPreisBerechnen(ObservableCollection<KaufObjekt> liste, string MerchantProzentBox)
        {

            // Überprüfen, ob der Prozentsatz eine gültige ganze Zahl ist
            bool isProzentsatzValid = int.TryParse(MerchantProzentBox, out int händlerGesProzentsatz);

            // Wenn die Eingabe ungültig ist, Fehlermeldung anzeigen und Methode beenden
            if (!isProzentsatzValid)
            {
                MessageBox.Show("Bitte geben Sie einen gültigen Prozentsatz (ganze Zahl) ein.", "Ungültige Eingabe", MessageBoxButton.OK, MessageBoxImage.Warning);
                return $"0GF 0TT 0Kl 0Mu";
            }


            double komplettPreis = 0;
            foreach (var item in liste)
            {
                komplettPreis += item.gesPreis;
            }
            if (händlerGesProzentsatz != 0)
            {
                double Aufschlag = komplettPreis * händlerGesProzentsatz / 100;
                komplettPreis += Aufschlag;
            }

            // Umrechnung in GF, TT, Kl, Mu
            var ergebniss = PreisZuWehrung(komplettPreis);


            
            return $"{ergebniss.Item1}GF {ergebniss.Item2}TT {ergebniss.Item3}Kl {ergebniss.Item4}Mu";
        }


        internal void MinusMenge(KaufObjekt itemToMinusMenge)
        {
            if (itemToMinusMenge.Menge > 0)
            {
                // Berechne den Einzelpreis und das Einzelgewicht
                double einzelPreis = Math.Round(itemToMinusMenge.gesPreis / itemToMinusMenge.Menge,2);
                double einzelGewicht = Math.Round(itemToMinusMenge.Gewicht / itemToMinusMenge.Menge,2);

                // Menge verringern
                itemToMinusMenge.Menge--;

                // Aktualisiere Gesamtpreis und Gesamtgewicht
                itemToMinusMenge.gesPreis = Math.Round(einzelPreis * itemToMinusMenge.Menge,2);
                itemToMinusMenge.Gewicht = Math.Round(einzelGewicht * itemToMinusMenge.Menge,2);

                // Umrechnung in GF, TT, Kl, Mu
                var ergebniss = PreisZuWehrung(itemToMinusMenge.gesPreis);


                itemToMinusMenge.gesPreisString = $"{ergebniss.Item1}GF {ergebniss.Item2}TT {ergebniss.Item3}Kl {ergebniss.Item4}Mu";

                


            }
        }

        internal void PlusMenge(KaufObjekt itemToPlusMenge)
        {
            // Erhöhe die Menge
            itemToPlusMenge.Menge++;
           

            // Berechne den Einzelpreis und das Einzelgewicht basierend auf der vorherigen Menge
            double einzelPreis = Math.Round(itemToPlusMenge.gesPreis / (itemToPlusMenge.Menge - 1), 2);
            double einzelGewicht = Math.Round(itemToPlusMenge.Gewicht / (itemToPlusMenge.Menge - 1), 2);

            // Aktualisiere Gesamtpreis und Gesamtgewicht
            itemToPlusMenge.gesPreis = Math.Round(einzelPreis * itemToPlusMenge.Menge, 2);
            itemToPlusMenge.Gewicht = Math.Round(einzelGewicht * itemToPlusMenge.Menge, 2);

            // Umrechnung in GF, TT, Kl, Mu

            var ergebniss = PreisZuWehrung(itemToPlusMenge.gesPreis);


            itemToPlusMenge.gesPreisString = $"{ergebniss.Item1}GF {ergebniss.Item2}TT {ergebniss.Item3}Kl {ergebniss.Item4}Mu";

        }

        internal double KompletGewichtBerechnen(ObservableCollection<KaufObjekt> kaufListe)
        {
            double KomplettGewicht = 0;
            foreach (var Item in kaufListe)
            {
                KomplettGewicht += Item.Gewicht;
            }

            return Math.Round(KomplettGewicht, 2);
        }

        internal string AuswahlPreisString(double item1)
        {
            // Umrechnung in GF, TT, Kl, Mu
           var ergebniss = PreisZuWehrung(item1);
           

            return $"{ergebniss.Item1}GF {ergebniss.Item2}TT {ergebniss.Item3}Kl {ergebniss.Item4}Mu";
        }

        internal IEnumerable<string> GetObjektAuswahlCombo()
        {
            // Eine Liste der Tabellenüberschriften erstellen.
            return new List<string>
            {
                "Rüstungsarten",
                "Gegenstände"
            };
        }

        internal static void SpeichereRüstungsart(string Name, string MinStärke, string RüstungsBonus, string Manöver, string Kosten, string Gewicht)
        {

            try
            {
                // Werte aus den Textboxen auslesen
                string name = Name;
                int minStärke = int.TryParse(MinStärke, out int parsedMinStärke) ? parsedMinStärke : 0;
                int rüstungBonus = int.TryParse(RüstungsBonus, out int parsedRüstungBonus) ? parsedRüstungBonus : 0;
                int manöver = int.TryParse(Manöver, out int parsedManöver) ? parsedManöver : 0;
                double kostenTT = double.TryParse(Kosten, out double parsedKostenTT) ? parsedKostenTT : 0;
                double gewicht = double.TryParse(Gewicht, out double parsedGewicht) ? parsedGewicht : 0;

                // Erstelle eine neue Rüstungsart-Instanz
                Rüstungsart neueRüstung = new Rüstungsart(name, minStärke, rüstungBonus, manöver, kostenTT, gewicht);

                // Rüstungsart in die Datenbank speichern
                Datenbank.SpeichereRüstungsart(neueRüstung);

                // Erfolgsmeldung anzeigen
                MessageBox.Show("Rüstung gespeichert: " + neueRüstung.Name);


            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler beim Speichern der Rüstung: " + ex.Message);
            }
            
        }

        internal static void SpeichereGegenstand(string Name, string Gewicht, string Kosten, string Häufigkeit, string Funktion)
        {
           
            try
            {
                // Werte aus den TextBoxen auslesen
                string name = Name;
                double gewicht = double.TryParse(Gewicht, out double parsedGewicht) ? parsedGewicht : 0;
                double kostenTT = double.TryParse(Kosten, out double parsedKostenTT) ? parsedKostenTT : 0;
                string häufigkeit = Häufigkeit;
                string funktion = Funktion;

                // Erstelle ein neues Objekt der Klasse Gegenstände
                Gegenstände neuerGegenstand = new Gegenstände(name, gewicht, kostenTT, häufigkeit, funktion);

                // Speichere den Gegenstand über den Controller
                Datenbank.SpeichereGegenstand(neuerGegenstand);

                // Bestätigungsmeldung
                MessageBox.Show($"Gegenstand '{neuerGegenstand.Name}' gespeichert!");


            }
            catch (Exception ex)
            {
                // Fehlerbehandlung
                MessageBox.Show("Fehler: " + ex.Message);
            }
        }

        internal void AddSelection_Click(string QuantityTextBox, string MerchantPercentageTextBox, object selectedItem, ObservableCollection<KaufObjekt> kaufListe)
        {


            // Überprüfen, ob die Eingaben gültige ganze Zahlen sind
            bool isMengeValid = int.TryParse(QuantityTextBox, out int MengeAuswahl);
            bool isProzentsatzValid = int.TryParse(MerchantPercentageTextBox, out int HändlerProzentsatz);

            // Falls eine der Eingaben ungültig ist, nichts tun
            if (!isMengeValid || !isProzentsatzValid)
            {
                // Optional: Eine Fehlermeldung anzeigen, falls gewünscht
                MessageBox.Show("Bitte geben Sie gültige ganze Zahlen für Menge und Händlerprozentsatz ein.", "Ungültige Eingabe", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // Ausgewähltes Objekt aus der ComboBox abrufen
            var AusgewähltesObjekt = selectedItem as Tuple<string, double, double, string>;
            if (AusgewähltesObjekt == null)
            {
                MessageBox.Show("Bitte wählen Sie ein gültiges Objekt aus.", "Fehler", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // Ausgewähltes Objekt aus der ComboBox abrufen

            string artikelName = AusgewähltesObjekt.Item1;
            double artikelKosten = AusgewähltesObjekt.Item2;
            double artikelGewicht = AusgewähltesObjekt.Item3;
            string artikelFunktion = AusgewähltesObjekt.Item4;

            // Berechnungen durchführen
            var ergebnisse = AuswahlSpeichern(MengeAuswahl, artikelGewicht, artikelKosten, HändlerProzentsatz);
            string gesPreisString = AuswahlPreisString(ergebnisse.Item1);

            double gesamtKosten = ergebnisse.Item1;
            double gesamtGewicht = ergebnisse.Item2;



            // Neues Item zur KaufListe hinzufügen
            kaufListe.Add(new KaufObjekt
            {
                Name = artikelName,
                Menge = MengeAuswahl,
                Gewicht = gesamtGewicht,
                gesPreis = gesamtKosten,
                gesPreisString = gesPreisString,
                HändlerProzentsatz = HändlerProzentsatz,
                Funktion = artikelFunktion

            });
        }

        internal void KeyUp(string textInthalt, ComboBox combo)
        {
            // Das Eingabefeld aus der ComboBox-Template extrahieren
            var textBox = textInthalt;

            if (textBox == null)
            {
                Console.WriteLine("TextBox ist null!");
                return;
            }

            string filterText = textBox.ToLower() ?? string.Empty;

            var allItems = GetComboboxInhalt();
            if (allItems == null)
            {
                Console.WriteLine("Die Liste ist null!");
                return;
            }

            // Sicherstellen, dass jedes Element in einen string konvertiert wird, falls möglich
            var filteredItems = allItems
                .Where(item =>
                {
                    string stringItem = item.ToString(); // Objekt sicher zu einem String konvertieren
                    return stringItem != null && stringItem.ToLower().Contains(filterText);
                })
                .ToList();

            Console.WriteLine($"Filtertext: {filterText}");
            Console.WriteLine($"Gefilterte Items: {string.Join(", ", filteredItems)}");

            combo.ItemsSource = filteredItems;
            combo.IsDropDownOpen = true;
        }

        internal void ClearUserInputs(StackPanel stackPanel)
        {
            foreach (var control in stackPanel.Children)
            {
                if (control is TextBox textBox)
                {
                    // Leere den Inhalt der TextBox
                    textBox.Clear();
                }
            }
        }

        internal void GegenstandLöschen(string GegenstandName)
        {
           Datenbank.LöscheGegenstand(GegenstandName);
        }

        internal void RüstungLöschen(string RüstungName)
        {
           Datenbank.LöscheRüstung(RüstungName);
        }

        internal static Tuple<string, string, string, string> PreisZuWehrung(double Preis)
        {

            
            string TextPreis = Preis.ToString();
            int KommaPosition = TextPreis.IndexOf(",");

            string gf;
            if (KommaPosition >= 2)
            {
                gf = TextPreis.Substring(0, KommaPosition - 1);
            }
            else if(KommaPosition == -1)
            {
                gf = TextPreis.Substring(0, TextPreis.Length - 1);
            }
            else
            {
                gf = "0";
            }

            string tt;
            if (KommaPosition >= 1)
            {
                tt = TextPreis.Substring(KommaPosition-1, 1);
            }
            else 
            {
                tt = TextPreis.Substring(TextPreis.Length - 1,1);
            }

            string kl;
            if (KommaPosition == -1)
            {
                kl = "0";
            }
            else
            {
                kl = TextPreis.Substring(KommaPosition + 1, 1);
            }

            string mu;
            if (KommaPosition != -1 && TextPreis.Length - KommaPosition >= 3)
            {
                mu = TextPreis.Substring(KommaPosition + 2, 1);
            }
            else 
            {
                mu = "0";
            }

            return new Tuple<string, string, string, string>(gf, tt, kl, mu);
        }
    }
}