using FuzzySharp;
using MahApps.Metro.Controls;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ZKuP
{
    /// <summary>
    /// Interaktionslogik für CreateVisitor.xaml
    /// </summary>
    public partial class ManageVisitor : MetroWindow, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        //private List<Visitor> myVar;
        //public List<Visitor> VisitorView
        //{
        //    get { return myVar; }
        //    set { myVar = value; OnPropertyChanged(); }
        //}

        DataTable visitors = new DataTable("Visitors");
        private Dictionary<string, List<string>> visitorSearchList = new Dictionary<string, List<string>>();

        private List<string> aspVar;
        public List<string> asp
        {
            get { return aspVar; }
            set { aspVar = value; OnPropertyChanged(); }
        }

        System.Windows.Threading.DispatcherTimer searchTimer = new System.Windows.Threading.DispatcherTimer();

        int index = 0;


        public ManageVisitor()
        {
            this.DataContext = this;

            InitializeComponent();

            //if (MainWindow.LoggedInRole == Roles.Admin)
            //{
            //    tbSearch.Visibility = Visibility.Visible;
            //    lblSearch.Visibility = Visibility.Visible;
            //}

            asp = SQL.ReadListString($"SELECT Name FROM {MainWindow.table}.ansprechpartner").Result;
            asp = asp.OrderBy(p => p).ToList();
            asp.Insert(0, "");
            cBAsp.ItemsSource = asp;
            //dg_cbASP.ItemsSource = asp;

            updateList();

            searchTimer.Interval = TimeSpan.FromSeconds(0.0005);
            searchTimer.Tick += SearchTimer_Tick;

            Dispatcher.Invoke(() => dgVisitors.Columns.FirstOrDefault(c => c.Header.ToString() == "Name").SortDirection = ListSortDirection.Ascending);
        }

        private void updateList()
        {
            if (MainWindow.LoggedInRole == Roles.Admin || MainWindow.LoggedInRole == Roles.M2_AM || MainWindow.LoggedInRole == Roles.Pförtner)
            {
                requestListAdmin();
            }
            else
            {
                requestList();
            }
        }

        private void requestList()
        {
            visitors = SQL.ReadSQL($"SELECT * FROM {MainWindow.table}.besucher WHERE Ersteller = '{Environment.UserName}' " +
                    $"OR Ersteller = '{Environment.UserDomainName}{Environment.UserName}' " +
                    $"OR Ersteller = '{SQL.ReadSingleValue($"SELECT Vertreter FROM {MainWindow.table}.ansprechpartner WHERE Name = '{Helper.InsertSpaceBeforeUpperCase(Environment.UserName)}'")}' " +
                    $"OR Ansprechpartner_Intern = '{Helper.InsertSpaceBeforeUpperCase(Environment.UserName)}' ORDER BY Name ASC"
                    , visitors).Result;

            //VisitorView = Visitor.DataTableToVisitor(visitors);
            dgVisitors.DataContext = visitors;


            visitorSearchList.Clear();

            foreach (var firma in visitors.AsEnumerable().Select(p => p.Field<string>("Name").Trim()).ToList().Distinct())
            {
                if (firma.Contains(' '))
                {
                    visitorSearchList.Add(firma, new List<string>());

                    for (var i = 0; i < firma.Split(' ').Count(); i++)
                        visitorSearchList[firma].Add(firma.Split(' ')[i]);
                }
                else visitorSearchList.Add(firma, new List<string>());
            }
        }

        private void requestListAdmin()
        {
            visitors = SQL.ReadSQL($"SELECT * FROM {MainWindow.table}.besucher ORDER BY Name ASC", visitors).Result;
            //VisitorView = Visitor.DataTableToVisitor(visitors);
            dgVisitors.DataContext = visitors;

            visitorSearchList.Clear();

            foreach (var firma in visitors.AsEnumerable().Select(p => p.Field<string>("Name").Trim()).ToList().Distinct())
            {
                if (firma.Contains(' '))
                {
                    visitorSearchList.Add(firma, new List<string>());

                    for (var i = 0; i < firma.Split(' ').Count(); i++)
                        visitorSearchList[firma].Add(firma.Split(' ')[i]);
                }
                else visitorSearchList.Add(firma, new List<string>());
            }
        }

        private void BtnClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private async void BtnAdd_Click(object sender, RoutedEventArgs e)
        {
            if (tbAnzahl_Begleiter.Text == "") tbAnzahl_Begleiter.Text = "0";

            tt.IsOpen = false;

            if (visitorSearchList.Keys.Select(p => p.ToLower()).Contains(tbName.Text.Trim().ToLower()))
            {
                if (MessageBox.Show($"Der Besucher {tbName.Text} ist bereits angelegt.\n" +
                    $"Besucher dürfen nicht mehrfach angelegt werden!\n\n" +
                    $"Bitte den Besucher in der Liste bearbeiten.\n" +
                    $"Hierfür einfach die zu ändernden Felder anklicken und bearbeiten.\n\n" +
                    $"Sollte es sich um einen anderen Besucher handeln, kann diese Meldung ignoriert werden\n" +
                    $"Möchten Sie diesen Besucher sicher nochmals hinzufügen?", "Doppelter Eintrag", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.No)
                {
                    return;
                }
            }
            else
            {
                List<string> similarities = new List<string>();

                foreach (var item in visitorSearchList)
                {
                    if (item.Value.Count > 0)
                    {
                        foreach (var val in item.Value)
                            if (Fuzz.Ratio(tbName.Text.ToLower(), val.ToLower()) > 70)
                                similarities.Add(item.Key);
                    }
                    else if (Fuzz.Ratio(tbName.Text.ToLower(), item.Key.ToLower()) > 70)
                        similarities.Add(item.Key);
                }

                if (similarities.Count > 0)
                {
                    similarities.Sort();
                    if (MessageBox.Show($"Der Besucher {tbName.Text} ist sehr ähnlich zum bereits angelegten Besucher {Helper.FirstCharToUpperCase(similarities.First())}.\n" +
                        $"Besucher dürfen nicht mehrfach angelegt werden!\n\n" +
                        $"Bitte den Besucher in der Liste bearbeiten.\n" +
                        $"Hierfür einfach die zu ändernden Felder anklicken und bearbeiten.\n\n" +
                        $"Sollte es sich um einen anderen Besucher handeln, kann diese Meldung ignoriert werden\n" +
                        $"Möchten Sie diesen Besucher sicher hinzufügen?", "Doppelter Eintrag?", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.No)
                    {
                        return;
                    }
                }
            }


            if (string.IsNullOrWhiteSpace(tbName.Text))
                MessageBox.Show("Name eintragen!", "Fehler");
            else if (string.IsNullOrWhiteSpace(tbVerantwortlicher_MA.Text))
                MessageBox.Show("Verantwortlichen MA eintragen!", "Fehler");
            else if (tbVerantwortlicher_MA.Text.ToList<char>().Distinct().Count() < 5)
            {
                MessageBox.Show("Verantwortlicher MA muss qualifiziert angegeben werden!\nFalls kein Verantwortlicher bekannt ist, ist der Zutritt unzulässig", "Fehler");
                return;
            }
            else if (string.IsNullOrWhiteSpace(tbTel_Besucher.Text))
                MessageBox.Show("Telefonnummer Besucher eintragen!", "Fehler");
            else if (tbTel_Besucher.Text.ToList<char>().Distinct().Count() < 5)
            {
                MessageBox.Show("Telefonnummer des Besuchers muss qualifiziert angegeben werden!\nFalls keine Nummer bekannt, die Nummer des Erstellers eintragen", "Fehler");
                return;
            }
            else if (!System.Text.RegularExpressions.Regex.IsMatch(tbTel_Besucher.Text, "^[0-9()+\\-/ ]*$"))
            {
                MessageBox.Show("Telefonnummer des Besuchers muss qualifiziert angegeben werden!\nFalls keine Nummer bekannt, die Nummer des Erstellers eintragen", "Fehler");
                return;
            }
            else if (!dpBesuchstag.SelectedDate.HasValue)
                MessageBox.Show("Besuchstag eintragen!", "Fehler");
            else if (string.IsNullOrWhiteSpace(tbGrundDesBesuchs.Text))
                MessageBox.Show("'Grund des Besuchs' eintragen!", "Fehler");
            else if (tbGrundDesBesuchs.Text.ToList<char>().Distinct().Count() < 5)
            {
                MessageBox.Show("Besuchsgrund muss qualifiziert angegeben werden!", "Fehler");
                return;
            }
            else if (string.IsNullOrWhiteSpace(tbOertlichkeit.Text))
                MessageBox.Show("'Örtlichkeit' eintragen!", "Fehler");
            else if (string.IsNullOrWhiteSpace(tbAnsprechp_Intern.Text))
                MessageBox.Show("'Ansprechpartner intern' auswählen oder eintragen!", "Fehler");
            else if (string.IsNullOrWhiteSpace(tbTel_Ansprechp.Text))
                MessageBox.Show("'Telefonnr. Ansprechpartner intern' eintragen!", "Fehler");
            else
            {
                if (!System.Text.RegularExpressions.Regex.IsMatch(tbAnzahl_Begleiter.Text, "^[0-9]*$"))
                    MessageBox.Show(this, "Anzahl Begleiter darf nur Zahlen enthalten", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                else
                {
                    if (Convert.ToInt16(tbAnzahl_Begleiter.Text) > 1)
                    {
                        MessageBox.Show("Bei mehreren Besuchern müssen alle Namen angegeben werden", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);

                        AddVisitorsList aVl = new AddVisitorsList(Convert.ToInt16(tbAnzahl_Begleiter.Text));
                        aVl.Owner = this;
                        aVl.WindowStartupLocation = WindowStartupLocation.CenterOwner;

                        if (aVl.ShowDialog() == true)
                        {
                            var groupId = aVl.GroupID;

                            //await SQL.WriteSQL($"INSERT INTO {MainWindow.table}.besucher (Name,Verantwortlicher_MA,Tel_Nr_Besucher,Anzahl_Begleitpersonen,Besuchstag,Grund_des_Besuchs,Ansprechpartner_Intern,Tel_Nr_Ansprechpartner_Intern,Oertlichkeit,Ersteller,idBesucherGroups) VALUES " +
                            //                    $"('{tbName.Text}','{tbVerantwortlicher_MA.Text}','{tbTel_Besucher.Text}','{tbAnzahl_Begleiter.Text}','{dpBesuchstag.SelectedDate.Value.ToString("yyyy-MM-dd")}','{tbGrundDesBesuchs.Text}','{tbAnsprechp_Intern.Text}','{tbTel_Ansprechp.Text}','{tbOertlichkeit.Text}','{Environment.UserName}','{groupId}')");
                            var lastID = await SQL.CreateAndWriteSQL($"INSERT INTO {MainWindow.table}.besucher (Name,Verantwortlicher_MA,Tel_Nr_Besucher,Anzahl_Begleitpersonen,Besuchstag,Grund_des_Besuchs,Ansprechpartner_Intern,Tel_Nr_Ansprechpartner_Intern,Oertlichkeit,Ersteller,idBesucherGroups) VALUES (@tbName,@tbVerantwortlicher_MA,@tbTel_Besucher,@tbAnzahl_Begleiter,@Besuchstag,@tbGrundDesBesuchs,@tbAnsprechp_Intern,@tbTel_Ansprechp,@tbOertlichkeit,@UserName,@groupId)", new List<MySqlParameter>()
                                                        {
                                                            new MySqlParameter("@tbName", tbName.Text),
                                                            new MySqlParameter("@tbVerantwortlicher_MA", tbVerantwortlicher_MA.Text),
                                                            new MySqlParameter("@tbTel_Besucher", tbTel_Besucher.Text),
                                                            new MySqlParameter("@tbAnzahl_Begleiter", tbAnzahl_Begleiter.Text),
                                                            new MySqlParameter("@Besuchstag", dpBesuchstag.SelectedDate.Value.ToString("yyyy-MM-dd")),
                                                            new MySqlParameter("@tbGrundDesBesuchs", tbGrundDesBesuchs.Text),
                                                            new MySqlParameter("@tbAnsprechp_Intern", tbAnsprechp_Intern.Text),
                                                            new MySqlParameter("@tbTel_Ansprechp", tbTel_Ansprechp.Text),
                                                            new MySqlParameter("@tbOertlichkeit", tbOertlichkeit.Text),
                                                            new MySqlParameter("@UserName", Environment.UserName),
                                                            new MySqlParameter("@groupId", groupId)
                                                        });


                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucherGroups SET idbesucher = '{lastID}' WHERE idbesucherGroups = '{groupId}'");
                        }
                        else
                        {
                            MessageBox.Show("Es wurden keine Änderungen übernommen", "Hinweis", MessageBoxButton.OK, MessageBoxImage.Information);
                            return;
                        }
                    }
                    else
                    {
                        //await SQL.WriteSQL($"INSERT INTO {MainWindow.table}.besucher (Name,Verantwortlicher_MA,Tel_Nr_Besucher,Anzahl_Begleitpersonen,Besuchstag,Grund_des_Besuchs,Ansprechpartner_Intern,Tel_Nr_Ansprechpartner_Intern,Oertlichkeit,Ersteller) VALUES " +
                        //                                            $"('{tbName.Text}','{tbVerantwortlicher_MA.Text}','{tbTel_Besucher.Text}','{tbAnzahl_Begleiter.Text}','{dpBesuchstag.SelectedDate.Value.ToString("yyyy-MM-dd")}','{tbGrundDesBesuchs.Text}','{tbAnsprechp_Intern.Text}','{tbTel_Ansprechp.Text}','{tbOertlichkeit.Text}','{Environment.UserName}')");
                        await SQL.CreateAndWriteSQL($"INSERT INTO {MainWindow.table}.besucher (Name,Verantwortlicher_MA,Tel_Nr_Besucher,Anzahl_Begleitpersonen,Besuchstag,Grund_des_Besuchs,Ansprechpartner_Intern,Tel_Nr_Ansprechpartner_Intern,Oertlichkeit,Ersteller) VALUES (@tbName,@tbVerantwortlicher_MA,@tbTel_Besucher,@tbAnzahl_Begleiter,@Besuchstag,@tbGrundDesBesuchs,@tbAnsprechp_Intern,@tbTel_Ansprechp,@tbOertlichkeit,@UserName)", new List<MySqlParameter>()
                                                    {
                                                        new MySqlParameter("@tbName", tbName.Text),
                                                        new MySqlParameter("@tbVerantwortlicher_MA", tbVerantwortlicher_MA.Text),
                                                        new MySqlParameter("@tbTel_Besucher", tbTel_Besucher.Text),
                                                        new MySqlParameter("@tbAnzahl_Begleiter", tbAnzahl_Begleiter.Text),
                                                        new MySqlParameter("@Besuchstag", dpBesuchstag.SelectedDate.Value.ToString("yyyy-MM-dd")),
                                                        new MySqlParameter("@tbGrundDesBesuchs", tbGrundDesBesuchs.Text),
                                                        new MySqlParameter("@tbAnsprechp_Intern", tbAnsprechp_Intern.Text),
                                                        new MySqlParameter("@tbTel_Ansprechp", tbTel_Ansprechp.Text),
                                                        new MySqlParameter("@tbOertlichkeit", tbOertlichkeit.Text),
                                                        new MySqlParameter("@UserName", Environment.UserName)
                                                    });
                    }
                }

                updateList();

                dgVisitors.ScrollIntoView(dgVisitors.Items[dgVisitors.Items.Count - 1]); //scroll to last
                dgVisitors.UpdateLayout();
                ResetInput();
            }
        }

        private void ResetInput()
        {
            tbName.Text = "";
            tbVerantwortlicher_MA.Text = "";
            tbTel_Besucher.Text = "";
            tbAnzahl_Begleiter.Text = "";
            dpBesuchstag.Text = "";
            tbGrundDesBesuchs.Text = "";
            tbOertlichkeit.Text = "";
            cBAsp.SelectedIndex = -1;
            tbAnsprechp_Intern.Text = "";
            tbTel_Ansprechp.Text = "";
        }

        private async void DgVisitors_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            var dg = sender as DataGrid;
            var row = dg.SelectedItem as DataRowView;
            var arr = row.Row.ItemArray;

            if (e.Key == Key.Delete)
            {
                deleteRow(arr);
            }
        }



        private void DgVisitors_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
        {
            dgVisitors.PreviewKeyDown -= DgVisitors_PreviewKeyDown;
        }


        private async void DgVisitors_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
            var newValue = "";
            var header = e.Column.Header;
            if (header.ToString() == "Anspr. intern")
                newValue = (e.EditingElement as ComboBox).Text;
            else if (header.ToString() == "Besuchstag")
                newValue = (e.EditingElement as DatePicker).Text;
            else if (e.EditingElement.GetType() == typeof(TextBox))
                newValue = (e.EditingElement as TextBox).Text;
            else return;


            var id = (e.Row.Item as DataRowView).Row.ItemArray[0];
            DateTime date = DateTime.Now;

            if (DateTime.TryParseExact(newValue, "dd.MM.yyyy", null, System.Globalization.DateTimeStyles.None, out date))
                newValue = date.ToString("yyyy-MM-dd");

            var MessageValue = newValue;
            var MessageDate = DateTime.Now;
            if (DateTime.TryParse(newValue, out MessageDate))
                MessageValue = MessageDate.ToString("dd.MM.yyyy");

            if (oldValue != MessageValue)
            {
                if (MessageBox.Show(this, $"Möchten Sie den Eintrag '{oldValue}' in der Spalte '{header}' sicher zu '{MessageValue}' ändern?", "Sicher ändern?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    switch (header)
                    {
                        case "Name":
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Name = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Verantw. MA":
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Verantwortlicher_MA = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Tel. Besucher":
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Tel_Nr_Besucher = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Anz. Begleitp.":
                            if (!System.Text.RegularExpressions.Regex.IsMatch(newValue, "^[0-9]*$"))
                                MessageBox.Show(this, "Anzahl Begleiter darf nur Zahlen enthalten", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                            else
                                await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Anzahl_Begleitpersonen = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Besuchstag":
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Besuchstag = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Grund des Besuchs":
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Grund_des_Besuchs = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Örtlichkeit":
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Oertlichkeit = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Anspr. intern":                            
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Ansprechpartner_Intern = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                        case "Tel. Ansprechp.":                            
                            await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Tel_Nr_Ansprechpartner_Intern = '{newValue}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                            break;
                    }
                }
            }

            index = e.Row.GetIndex();
            dgVisitors.PreviewKeyDown += DgVisitors_PreviewKeyDown;

            updateList();

            dgVisitors.RowValidationErrorTemplate = new ControlTemplate();

            dgVisitors.SelectedIndex = (index);
            dgVisitors.ScrollIntoView(dgVisitors.Items[index]);

            //ScrollTo();
        }

        private async Task ScrollTo()
        {
            if (index != 0 && index != -1 && (dgVisitors.Items.Count - 1) >= index)
            {
                dgVisitors.SelectedIndex = index;
                dgVisitors.ScrollIntoView(dgVisitors.Items[index]);

                DataGridRow row = (DataGridRow)dgVisitors.ItemContainerGenerator.ContainerFromIndex(index - 1);

                if (row != null)
                {
                    row.Focusable = true;
                    row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
                }
            }
        }

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            System.Diagnostics.Debug.WriteLine("PropertyChanged   " + propertyName);
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void TbAnzahl_Begleiter_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Tab)
            {
                dpBesuchstag.Focus();
                dpBesuchstag.IsDropDownOpen = true;
            }

            if (e.Key != Key.OemComma)
            {
                e.Handled = false;
                return;
            }
            else
            {
                MessageBox.Show(this, "Komma (',') ist ein nicht erlaubtes Zeichen", "Achtung", MessageBoxButton.OK, MessageBoxImage.Information);
                e.Handled = true;
            }
            return;
        }

        private void DpBesuchstag_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Tab)
            {
                dpBesuchstag.IsDropDownOpen = false;
                dpBesuchstag.Focus();
            }
        }



        private void dgVisitors_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (dgVisitors.SelectedIndex != -1) btnDelete.IsEnabled = true;
            else btnDelete.IsEnabled = false;

            ScrollTo();
        }
        private async void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            var dg = dgVisitors;
            var row = dg.SelectedItem as DataRowView;
            var arr = row.Row.ItemArray;

            if (MessageBox.Show(this, $"Markierten Besucher wirklich entfernen?", "Besucher entfernen?", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
            {
                deleteRow(arr);
            }
        }

        private async void deleteRow(object[] arr)
        {
            //await SQL.WriteSQL($"INSERT INTO {MainWindow.table}.besucherLog (idbesucher, Name,Verantwortlicher_MA,Tel_Nr_Besucher,Anzahl_Begleitpersonen,Besuchstag,Grund_des_Besuchs,Ansprechpartner_Intern,Tel_Nr_Ansprechpartner_Intern,Oertlichkeit,Geloescht_Von) VALUES " +
            //                    $"('{arr[0]}','{arr[1].ToString()}','{arr[2].ToString()}','{arr[3].ToString()}','{arr[4].ToString()}','{Convert.ToDateTime(arr[5].ToString()).ToString("yyyy-MM-dd")}','{arr[6].ToString()}','{arr[7].ToString()}','{arr[8].ToString()}','{arr[10].ToString()}','{Environment.UserName}')");
            await SQL.CreateAndWriteSQL($"INSERT INTO {MainWindow.table}.besucherLog (idbesucher, Name,Verantwortlicher_MA,Tel_Nr_Besucher,Anzahl_Begleitpersonen,Besuchstag,Grund_des_Besuchs,Ansprechpartner_Intern,Tel_Nr_Ansprechpartner_Intern,Oertlichkeit,Geloescht_Von) VALUES (@arr0,@arr1,@arr2,@arr3,@arr4,@arr5,@arr6,@arr7,@arr8,@arr10,@UserName)", new List<MySqlParameter>()
                                        {
                                            new MySqlParameter("@arr0", arr[0]),
                                            new MySqlParameter("@arr1", arr[1].ToString()),
                                            new MySqlParameter("@arr2", arr[2].ToString()),
                                            new MySqlParameter("@arr3", arr[3].ToString()),
                                            new MySqlParameter("@arr4", arr[4].ToString()),
                                            new MySqlParameter("@arr5", Convert.ToDateTime(arr[5].ToString()).ToString("yyyy-MM-dd")),
                                            new MySqlParameter("@arr6", arr[6].ToString()),
                                            new MySqlParameter("@arr7", arr[7].ToString()),
                                            new MySqlParameter("@arr8", arr[8].ToString()),
                                            new MySqlParameter("@arr10", arr[10].ToString()),
                                            new MySqlParameter("@UserName", Environment.UserName)
                                        });

            await SQL.WriteSQL($"DELETE FROM {MainWindow.table}.besucher WHERE `idBesucher` = '{arr[0]}'");

            updateList();
        }

        private async void cBAsp_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cBAsp.SelectedIndex != -1 && cBAsp.SelectedItem.ToString() != "")
            {
                var list = await SQL.ReadListStringTwoColumns($"SELECT Name, Tel_Nr FROM {MainWindow.table}.ansprechpartner WHERE Name = '{cBAsp.SelectedItem.ToString()}'");
                tbAnsprechp_Intern.Text = list[0].Split(';')[0].ToString();
                tbTel_Ansprechp.Text = list[0].Split(';')[1].ToString();
            }
            else
            {
                tbAnsprechp_Intern.Text = "";
                tbTel_Ansprechp.Text = "";
            }
        }

        private void TextBoxes_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.OemComma)
            {
                e.Handled = false;
                return;
            }
            {
                MessageBox.Show(this, "Komma (',') ist ein nicht erlaubtes Zeichen", "Achtung", MessageBoxButton.OK, MessageBoxImage.Information);
                e.Handled = true;
            }
            return;
        }

        string oldValue = "";
        private void dgVisitors_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
        {
            oldValue = (e.EditingElement as TextBox) != null ? (e.EditingElement as TextBox).Text : "";
        }

        private void tbAnzahl_Begleiter_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            if ((sender as TextBox).Text.Length >= 2) e.Handled = true;
            if (!System.Text.RegularExpressions.Regex.IsMatch(e.Text, "^[0-9]*$")) e.Handled = true;
        }

        private void ComboBox_DropDownOpened(object sender, EventArgs e)
        {

        }

        private void Textboxes_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.Paste)
            {
                e.Handled = true;
            }
        }

        private void dpBesuchstag_DateValidationError(object sender, DatePickerDateValidationErrorEventArgs e)
        {
            MessageBox.Show("Kein gültiges Datumsformat in Feld 'Besuchstag'", "Fehler", MessageBoxButton.OK, MessageBoxImage.Warning);
        }  

        private void DatePicker_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            oldValue = (sender as DatePicker).Text;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Helper.CheckWindowIsInScreenSpace(this);
        }

        private async void dpDataGridBesuchstag_CalendarClosed(object sender, RoutedEventArgs e)
        {
            if (oldValue != (sender as DatePicker).Text)
            {
                if (MessageBox.Show(this, $"Möchten Sie den Eintrag '{oldValue}' in der Spalte 'Besuchstag' sicher zu '{(sender as DatePicker).Text}' ändern?", "Sicher ändern?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    var id = (DataGridRow.GetRowContainingElement((sender as DatePicker)).Item as DataRowView).Row.ItemArray[0];
                    await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Besuchstag = '{(sender as DatePicker).SelectedDate.Value.ToString("yyyy-MM-dd")}', Bearbeiter = '{Environment.UserName}' WHERE idBesucher = '{id}'");
                }
            }
        }

        private void dpDataGridBesuchstag_CalendarOpened(object sender, RoutedEventArgs e)
        {
            oldValue = (sender as DatePicker).Text;
        }

        string oldValueAsp = "";
        private void dgFirmen_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
        {
            if (e.Column.Header.ToString() == "Anspr. intern")
                oldValueAsp = (e.EditingElement as ComboBox) != null ? (e.EditingElement as ComboBox).Text : "";
            else
                oldValueAsp = (e.EditingElement as TextBox) != null ? (e.EditingElement as TextBox).Text : "";
        }


        private void dg_cbASP_DropDownOpened(object sender, EventArgs e)
        {
            oldValueAsp = (sender as ComboBox) != null ? (sender as ComboBox).Text : "";
        }

        private async void dg_cbAsp_DropDownClosed(object sender, EventArgs e)
        {
            var box = sender as ComboBox;
            DataGridRow dataGridRow = Helper.FindParent<DataGridRow>(box);
            int index = dataGridRow.GetIndex();

            var id = ((System.Data.DataRowView)dataGridRow.DataContext).Row.ItemArray[0];

            if ((sender as ComboBox).SelectedIndex != -1 && (sender as ComboBox).SelectedItem.ToString() != "")
            {
                if (oldValueAsp != box.Text)
                {
                    if (MessageBox.Show(this, $"Möchten Sie den Eintrag '{oldValueAsp}' in der Spalte 'Anspr. intern' sicher zu '{box.Text}' ändern?", "Sicher ändern?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Ansprechpartner_Intern = '{box.Text}',Tel_Nr_Ansprechpartner_Intern = '{SQL.ReadSingleValue($"SELECT Tel_Nr FROM {MainWindow.table}.ansprechpartner WHERE Name = '{(sender as ComboBox).Text}'")}', Bearbeiter = '{Environment.UserName}' WHERE idbesucher = '{id}'");

                        updateList();


                        dgVisitors.RowValidationErrorTemplate = new ControlTemplate();

                        dgVisitors.SelectedIndex = (index);
                        dgVisitors.ScrollIntoView(dgVisitors.Items[index]);
                    }
                }
            }
            else
            {
                //tbAnsprechp_Intern.Text = "";
                //tbTel_Ansprechp.Text = "";
            }
        }



        private async void Tel_Nr_Besucher_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            var box = sender as TextBox;
            DataGridRow dataGridRow = Helper.FindParent<DataGridRow>(box);
            int index = dataGridRow.GetIndex();

            var id = ((System.Data.DataRowView)dataGridRow.DataContext).Row.ItemArray[0];

            if (oldValueAsp != box.Text)
            {
                if (MessageBox.Show(this, $"Möchten Sie den Eintrag '{oldValueAsp}' in der Spalte 'Tel. Besucher' sicher zu '{box.Text}' ändern?", "Sicher ändern?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    await SQL.WriteSQL($"UPDATE {MainWindow.table}.besucher SET Tel_Nr_Besucher = '{box.Text}' WHERE idbesucher = '{id}'");

                    updateList();


                    dgVisitors.RowValidationErrorTemplate = new ControlTemplate();

                    dgVisitors.SelectedIndex = (index);
                    dgVisitors.ScrollIntoView(dgVisitors.Items[index]);
                }
            }
        }


        string searchTerm = "";
        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (searchTerm == "")
            {
                lblSearch.Visibility = Visibility.Visible;
                searchProgress.Visibility = Visibility.Visible;
            }
            else
            {
                lblSearch.Visibility = Visibility.Collapsed;
                searchProgress.Visibility = Visibility.Visible;
            }

            searchTerm = (sender as TextBox).Text;
            searchTimer.Start();
        }
        private void SearchTimer_Tick(object sender, EventArgs e)
        {
            if (searchTerm == "")
            {
                visitors.DefaultView.RowFilter = $"";

                //Task.Run(() => VisitorView = Visitor.DataTableToVisitor(visitors));
                dgVisitors.DataContext = visitors;
            }
            else
            {
                visitors.DefaultView.RowFilter = $"Name LIKE '%{searchTerm}%' OR Verantwortlicher_MA LIKE '%{searchTerm}%'";
                dgVisitors.DataContext = visitors;

                if (visitors.DefaultView.Count == 0)
                {
                    List<string> similarities = new List<string>();

                    foreach (var item in visitors.Rows)
                    {
                        var ratio = Fuzz.Ratio(tbSearch.Text.ToLower(), (item as DataRow).ItemArray[1].ToString().ToLower());
                        if (ratio > 60)
                            similarities.Add((item as DataRow).ItemArray[1].ToString());

                        ratio = Fuzz.Ratio(tbSearch.Text.ToLower(), (item as DataRow).ItemArray[2].ToString().ToLower());
                        if (ratio > 60)
                            similarities.Add((item as DataRow).ItemArray[1].ToString());

                        ratio = Fuzz.Ratio(tbSearch.Text.ToLower(), (item as DataRow).ItemArray[6].ToString().ToLower());
                        if (ratio > 60)
                            similarities.Add((item as DataRow).ItemArray[1].ToString());
                    }


                    if (similarities.Count > 0)
                    {
                        StringBuilder str = new StringBuilder();
                        str.Append($"Name LIKE '%");

                        foreach (var s in similarities)
                            str.Append($"{s}%' OR Name LIKE '%");

                        str.Remove(str.Length - 16, 16);


                        str.Append(" OR Verantwortlicher_MA LIKE '%");

                        foreach (var s in similarities)
                            str.Append($"{s}%' OR Verantwortlicher_MA LIKE '%");

                        str.Remove(str.Length - 31, 31);


                        str.Append(" OR Grund_des_Besuchs LIKE '%");

                        foreach (var s in similarities)
                            str.Append($"{s}%' OR Grund_des_Besuchs LIKE '%");

                        str.Remove(str.Length - 29, 29);




                        visitors.DefaultView.RowFilter = str.ToString();
                    }
                    else
                    {
                        visitors.DefaultView.RowFilter = "";
                    }
                }
            }


            //else
            //{
            //    visitors.DefaultView.RowFilter = $"Name LIKE '%{searchTerm}%' OR Verantwortlicher_MA LIKE '%{searchTerm}%'";

            //    Task.Run(() => VisitorView = Visitor.DataTableToVisitor(visitors));
            //    dgVisitors.DataContext = visitors;
            //}

            searchProgress.Visibility = Visibility.Collapsed;
            searchTimer.Stop();
        }

        private void Tel_Nr_Besucher_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            if (!System.Text.RegularExpressions.Regex.IsMatch(e.Text, "^[0-9()+\\-/ ]*$"))
            {
                e.Handled = true;
                new System.Windows.Controls.Primitives.Popup() { Child = new TextBlock() { Text = $"'{e.Text}' ist kein gültiges Zeichen\nTelefonnummer muss qualifiziert eingetragen werden!", Foreground = new SolidColorBrush(Colors.White), Margin = new Thickness(5) }, IsOpen = true, StaysOpen = false, Placement = System.Windows.Controls.Primitives.PlacementMode.Mouse };
            }
        }


        ToolTip tt = new ToolTip();
        private void tbName_TextChanged(object sender, TextChangedEventArgs e)
        {
            List<Tuple<int, string>> similarities = new List<Tuple<int, string>>();

            //foreach(var item in FirmenNamen)
            //{
            //    if(Fuzz.Ratio(tbName.Text, item) > 60)
            //        similarities.Add(item);

            //}

            foreach (var item in visitorSearchList)
            {
                if (item.Value.Count > 0)
                {
                    foreach (var val in item.Value)
                    {
                        var ratio = Fuzz.Ratio(tbName.Text.ToLower(), val.ToLower());
                        if (ratio > 60)
                            similarities.Add(new Tuple<int, string>(ratio, item.Key));
                        else if (!string.IsNullOrWhiteSpace(tbName.Text) && val.ToLower().StartsWith(tbName.Text.ToLower()))
                            similarities.Add(new Tuple<int, string>(50, val));
                    }
                }
                else if (Fuzz.Ratio(tbName.Text.ToLower(), item.Key.ToLower()) > 80)
                    similarities.Add(new Tuple<int, string>(100, item.Key));
                else if (!string.IsNullOrWhiteSpace(tbName.Text) && item.Key.ToLower().StartsWith(tbName.Text.ToLower()))
                    similarities.Add(new Tuple<int, string>(65, item.Key));

            }

            similarities = similarities.OrderByDescending(p => p.Item1).ToList();

            if (similarities.Count > 0)
            {
                tt.Placement = PlacementMode.RelativePoint;
                tt.PlacementTarget = tbName;
                tt.HorizontalOffset = tbName.Width * .75;
                tt.Width = tbName.Width;
                tt.Background = new SolidColorBrush(Colors.Red);
                tt.Content = new Grid();
                (tt.Content as Grid).Background = new SolidColorBrush(Colors.Red);
                (tt.Content as Grid).Children.Add(new StackPanel());
                ((tt.Content as Grid).Children[0] as StackPanel).Children.Add(new TextBlock() { Text = "Besucher nicht doppelt anlegen!\n\nMeinen Sie:\n" });

                foreach (var item in similarities.Select(p => p.Item2).Distinct())
                    ((tt.Content as Grid).Children[0] as StackPanel).Children.Add(new TextBlock() { Text = Helper.FirstCharToUpperCase(item) });

                tt.IsOpen = true;
                tbName.ToolTip = tt;
            }
            else
            {
                tt.IsOpen = false;
                tbName.ToolTip = tt;
            }
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            tt.IsOpen = false;
        }

        private void tbName_LostFocus(object sender, RoutedEventArgs e)
        {
            tt.IsOpen = false;
        }

        //int editID = 0;
        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            int editID = Convert.ToInt32((((sender as Button).Parent as StackPanel).DataContext as DataRowView).Row.ItemArray[0]);
            var anz = Convert.ToInt16((((sender as Button).Parent as StackPanel).DataContext as DataRowView).Row.ItemArray[4]);

            AddVisitorsList aVl = new AddVisitorsList(anz, true, editID);
            aVl.Owner = this;
            aVl.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            aVl.ShowDialog();

            updateList();
        }


        private void Window_LocationChanged(object sender, EventArgs e)
        {
            this.LocationChanged -= Window_LocationChanged;
            Helper.CheckWindowIsInScreenSpace(this);
            this.LocationChanged += Window_LocationChanged;
        }
    }


    //public class Visitor
    //{
    //    public string Name;
    //    string Verantwortlicher_MA;
    //    string Tel_Nr_Besucher;
    //    string Anzahl_Begleitpersonen;
    //    string Besuchstag;
    //    string Grund_des_Besuchs;
    //    string Oertlichkeit;
    //    string Ansprechpartner_Intern;
    //    string Tel_Nr_Ansprechpartner_Intern;




    //    public static List<Visitor> DataTableToVisitor(System.Data.DataTable dataTable)
    //    {
    //        List<Visitor> x = new List<Visitor>();

    //        foreach (DataRow dr in dataTable.Rows)
    //        {
    //            x.Add(new Visitor()
    //            {
    //                Name = dr[1].ToString(),
    //                Verantwortlicher_MA = dr[2].ToString(),
    //                Tel_Nr_Besucher = dr[3].ToString(),
    //                Anzahl_Begleitpersonen = dr[4].ToString(),
    //                Besuchstag = dr[5].ToString(),
    //                Grund_des_Besuchs = dr[6].ToString(),
    //                Ansprechpartner_Intern = dr[7].ToString(),
    //                Tel_Nr_Ansprechpartner_Intern = dr[8].ToString(),
    //                Oertlichkeit = dr[9].ToString()
    //            });
    //        }

    //        return x;
    //    }
    //}
}
