using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

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


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

        DataTable firmen = new DataTable("firmen");

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

        DataTable besucher = new DataTable("besucher"); 


        private List<Overview> overview = new List<Overview>();
        public List<Overview> Overviews
        {
            get { return overview; }
            set { overview = value; OnPropertyChanged(); }
        }

        DataTable overv = new DataTable("Overview");

        public List<string> Kategorien { get; set; } = new List<string>();


        public MainWindow()
        {
            InitializeComponent();

            AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            
            AuthenticateUser();
        }

        private async void AuthenticateUser()
        {
            if (AuthenticateDomain())
            {
                if (!Thread.CurrentPrincipal.Identity.IsAuthenticated)
                {
                    MessageBox.Show($"Ihr User {Thread.CurrentPrincipal.Identity.Name} ist nicht zum Zugriff berechtigt", "Zugriff verweigert");
                    Application.Current.Shutdown();
                    return;
                }
                else
                {
                    string auth = "";
                    string role = "";

                    auth = await SQL.ReadSingleValue($"SELECT EXISTS(SELECT * FROM users WHERE `Username` = '{Environment.UserName}')");

                    if (auth == "1")
                        role = await SQL.ReadSingleValue($"SELECT Role FROM users WHERE `Username` = '{Environment.UserName}'");
                    else
                    {
                        MessageBox.Show($"Ihr User {Thread.CurrentPrincipal.Identity.Name} ist nicht zum Zugriff berechtigt", "Zugriff verweigert");
                        Application.Current.Shutdown();
                        return;
                    }

                    switch (role)
                    {
                        case "0":
                            PfoertnerStart();
                            break;
                        case "1":
                            EditorStart();
                            break;
                        case "2":
                            AdminStart();
                            break;
                        default:
                            PfoertnerStart();
                            break;
                    }

                    Kategorien.Add("Fremdfirma");
                    Kategorien.Add("Besucher");

                    firmen = await SQL.ReadSQL($"SELECT Name FROM firmen", firmen);
                    besucher = await SQL.ReadSQL($"SELECT Name From besucher", besucher);

                    FirmenList = DataTableToFirmenList(firmen);
                    BesucherList = DataTableToFirmenList(besucher);

                    overv = await SQL.ReadSQL("SELECT * FROM zutritte", overv);

                    //Overviews = DataTableToOverview(overv);
                    dgOverview.DataContext = overv;
                }
            }
            else
            {
                MessageBox.Show("User nicht in der Domäne aktiviert");
                Application.Current.Shutdown();
                return;
            }
        }

        private bool AuthenticateDomain()
        {
            using (var domainContext = new PrincipalContext(ContextType.Domain, Environment.UserDomainName))
            {
                using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, Environment.UserName))
                {
                    if (foundUser.Enabled.HasValue)
                    {
                        return (bool)foundUser.Enabled;
                    }
                    else
                    {
                        return false; //or false depending what result you want in the case of Enabled being NULL
                    }
                }
            }
        }

        private void AdminStart()
        {
            btnManageUsers.Visibility = Visibility.Visible;
            btnCreateVisitor.Visibility = Visibility.Visible;
            btnCreateFirma.Visibility = Visibility.Visible;

            //MessageBox.Show("Sie sind Admin");
            // something that only an admin user should be able to do
        }

        private void EditorStart()
        {
            btnCreateVisitor.Visibility = Visibility.Visible;
            btnCreateFirma.Visibility = Visibility.Visible;
            btnManageUsers.Visibility = Visibility.Collapsed;
            

            //MessageBox.Show("Sie sind Editor");
            // something that only an admin user should be able to do
        }

        private void PfoertnerStart()
        {
            btnCreateVisitor.Visibility = Visibility.Collapsed;
            btnManageUsers.Visibility = Visibility.Collapsed;
            btnCreateFirma.Visibility = Visibility.Collapsed;
            //MessageBox.Show("Sie sind Pförtner");
            // something that only an admin user should be able to do
        }



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

            //TextBlock persnummer = null;
            var KatFramework = dgOverview.Columns[1].GetCellContent(dgOverview.Items[index]);
            var Kat = FindVisualChild<ComboBox>(KatFramework);


            if (Kat.Text == "Fremdfirma")
                firmen = await SQL.ReadSQL($"SELECT Name FROM firmen", firmen);

            //firmen = await SQL.ReadSQL($"SELECT Name FROM firmen", firmen);
            //FirmenList = DataTableToFirmenList(firmen);
            if (Kat.SelectedIndex == -1)
                FirmenList.Add("Zuerst Kategorie wählen");
            //if (t.Count >= 1)
            if (Kat.Text == "Fremdfirma")
            {
                FirmenList = DataTableToFirmenList(firmen);
                if (Kat.SelectedIndex == -1)
                    FirmenList.Add("Zuerst Kategorie wählen");

                box.ItemsSource = FirmenList;
            }
        }


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

            //TextBlock persnummer = null;
            var KatFramework = dgOverview.Columns[1].GetCellContent(dgOverview.Items[index]);
            var Kat = FindVisualChild<ComboBox>(KatFramework);


            if (Kat.Text == "Besucher")
                besucher = await SQL.ReadSQL($"SELECT Name From besucher", besucher);

            if (Kat.Text == "Besucher")
            {
                BesucherList = DataTableToFirmenList(besucher);
                if (Kat.SelectedIndex == -1)
                    BesucherList.Add("Zuerst Kategorie wählen");

                box.ItemsSource = BesucherList;
            }
        }



        string selectedKategorie = "";
        private void ComboBox_DropDownClosed_1(object sender, EventArgs e)
        {
            selectedKategorie = (sender as ComboBox).Text;
        }
        string selectedFirma = "";
        private void ComboBox_DropDownClosed(object sender, EventArgs e)
        {
            selectedFirma = (sender as ComboBox).Text;
        }
        string selectedBesucher = "";
        private void ComboBox_Besucher_DropDownClosed_2(object sender, EventArgs e)
        {
            selectedBesucher = (sender as ComboBox).Text;
        }

        private async void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            //var box = sender as CheckBox;
            //DataGridRow dataGridRow = FindParent<DataGridRow>(box);
            //int index = dataGridRow.GetIndex();

            //var stamp = dgOverview.Columns[4].GetCellContent(dgOverview.Items[index]) as TextBlock;
            //var time = DateTime.Now.ToString("dd.MM.yyyy HH:mm");
            //stamp.Text = time;


            //var checkEinweisung = await SQL.ReadSingleValue($"SELECT Örtliche_Einweisung_bis FROM firmen WHERE Name = '{selectedFirma}'");


            //var einweis = dgOverview.Columns[6].GetCellContent(dgOverview.Items[index]) as TextBlock;
            //var zutritt = dgOverview.Columns[5].GetCellContent(dgOverview.Items[index]) as TextBlock;

            //if (Convert.ToDateTime(time) > Convert.ToDateTime(checkEinweisung))
            //{                
            //    einweis.Text = "Prüfen!";
            //    einweis.Background = new SolidColorBrush(Colors.Red);
            //}
            //else
            //{
            //    einweis.Text = "OK!";
            //    einweis.Background = new SolidColorBrush(Colors.Green);
            //}

            //var checkZutritt = await SQL.ReadSingleValue($"SELECT Arbeitsende FROM firmen WHERE Name = '{selectedFirma}'");
            

            //if (Convert.ToDateTime(time) > Convert.ToDateTime(checkZutritt))
            //{
            //    zutritt.Text = "Prüfen!";
            //    zutritt.Background = new SolidColorBrush(Colors.Red);
            //}
            //else
            //{
            //    zutritt.Text = "OK!";
            //    zutritt.Background = new SolidColorBrush(Colors.Green);
            //}


            //await SQL.WriteSQL($"INSERT INTO zutritte (Kategorie,Firma_Name,Zutritt,Pruefung_Zutritt,Pruefung_Einweisung) VALUES ('{selectedKategorie}','{selectedFirma}','{Convert.ToDateTime(time).ToString("yyyy-MM-dd HH:mm:ss")}','{zutritt.Text}','{einweis.Text}')");
            //overv = await SQL.ReadSQL("SELECT * FROM zutritte", overv);
            //dgOverview.DataContext = overv;
            ////overv.NewRow();
            ////Overviews = DataTableToOverview(overv);

            //dgOverview.CommitEdit(DataGridEditingUnit.Row,true);
        }

        private void DgOverview_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
        {
            e.Cancel = true;
        }





        private void BtnManageUsers_Click(object sender, RoutedEventArgs e)
        {
            ManageUsers mU = new ManageUsers();
            mU.ShowDialog();
        }

        private void BtnCreateVisitor_Click(object sender, RoutedEventArgs e)
        {
            CreateVisitor cV = new CreateVisitor();
            cV.ShowDialog();
        }

        private void BtnCreateFirma_Click(object sender, RoutedEventArgs e)
        {
            CreateFirma cF = new CreateFirma();
            cF.ShowDialog();
        }






        public static List<string> DataTableToFirmenList(System.Data.DataTable dataTable)
        {
            List<string> x = new List<string>();
            
            foreach (DataRow dr in dataTable.Rows)
            {
                x.Add(dr[0].ToString());
            }

            return x;
        }

        public static List<Overview> DataTableToOverview(System.Data.DataTable dataTable)
        {
            List<Overview> x = new List<Overview>();

            foreach (DataRow dr in dataTable.Rows)
            {
                x.Add(new Overview()
                {
                    Kategorie = dr[1].ToString(),
                    NameFirma = dr[2].ToString(),
                    NameBesucher = dr[3].ToString(),
                    Zutritt = dr[4].ToString(),
                    Pruefung_Zutritt = dr[5].ToString(),
                    Pruefung_Einweisung = dr[6].ToString()
                });
            }

            return x;
        }


        public static Parent FindParent<Parent>(DependencyObject child)
            where Parent : DependencyObject
        {
            DependencyObject parentObject = child;

            //We are not dealing with Visual, so either we need to fnd parent or
            //get Visual to get parent from Parent Heirarchy.
            while (!((parentObject is System.Windows.Media.Visual)
                    || (parentObject is System.Windows.Media.Media3D.Visual3D)))
            {
                if (parentObject is Parent || parentObject == null)
                {
                    return parentObject as Parent;
                }
                else
                {
                    parentObject = (parentObject as FrameworkContentElement).Parent;
                }
            }

            //We have not found parent yet , and we have now visual to work with.
            parentObject = VisualTreeHelper.GetParent(parentObject);

            //check if the parent matches the type we're looking for
            if (parentObject is Parent || parentObject == null)
            {
                return parentObject as Parent;
            }
            else
            {
                //use recursion to proceed with next level
                return FindParent<Parent>(parentObject);
            }
        }

        public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj)
       where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

        public static childItem FindVisualChild<childItem>(DependencyObject obj)
            where childItem : DependencyObject
        {
            foreach (childItem child in FindVisualChildren<childItem>(obj))
            {
                return child;
            }

            return null;
        }


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

        private void DgOverview_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //foreach (var cell in dgOverview.Items)
            //{
            //    if (cell is DataRowView)
            //    {
            //        //DataRowView view = cell as DataRowView;
            //        //if (view.Row.ItemArray[5].ToString() == "Prüfen!")
            //        //    (view.Row.ItemArray[5] as DataGridCell).Background = new SolidColorBrush(Colors.Red);
            //        //else if (view.Row.ItemArray[5].ToString() == "OK!")
            //        //    (view.Row..ItemArray[5] as DataGridCell).Background = new SolidColorBrush(Colors.Red);

            //        //if (cell.Content.ToString() == "OK!") cell.Background = new SolidColorBrush(Colors.Green);
            //    }
            //}
        }

        private void DgOverview_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
        {
            foreach (DataGridCell cell in dgOverview.Items)
            {
                if (cell.Content.ToString() == "Prüfen!") cell.Background = new SolidColorBrush(Colors.Red);

                if (cell.Content.ToString() == "OK!") cell.Background = new SolidColorBrush(Colors.Green);
            }
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            var box = sender as Button;
            DataGridRow dataGridRow = FindParent<DataGridRow>(box);
            

            int index = dataGridRow.GetIndex();

            if (dgOverview.Items.Count - 1 == index)
            {
                var KatFramework = dgOverview.Columns[1].GetCellContent(dgOverview.Items[index]);
                var FirmFramework = dgOverview.Columns[2].GetCellContent(dgOverview.Items[index]);
                var BesuchFramework = dgOverview.Columns[3].GetCellContent(dgOverview.Items[index]);

                var Kat = FindVisualChild<ComboBox>(KatFramework);
                var Firm = FindVisualChild<ComboBox>(FirmFramework);
                var Besuch = FindVisualChild<ComboBox>(BesuchFramework);



                if (Kat.SelectedIndex == -1)
                    MessageBox.Show("Bitte Kategorie wählen", "Fehler!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                else if (Firm.SelectedIndex == -1 && Besuch.SelectedIndex == -1)
                    MessageBox.Show("Bitte Firma/Besucher wählen", "Fehler!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                else
                {
                    var stamp = dgOverview.Columns[5].GetCellContent(dgOverview.Items[index]) as TextBlock;
                    var time = DateTime.Now.ToString("dd.MM.yyyy HH:mm");
                    stamp.Text = time;

                    var checkEinweisung = "";
                    var checkZutritt = "";

                    if (Kat.Text == "Fremdfirma")
                        checkEinweisung = await SQL.ReadSingleValue($"SELECT Örtliche_Einweisung_bis FROM firmen WHERE Name = '{selectedFirma}'");
                    else if (Kat.Text == "Besucher")
                        checkEinweisung = await SQL.ReadSingleValue($"SELECT Unterwiesen_Bis FROM besucher WHERE Name = '{selectedBesucher}'");

                    var einweis = dgOverview.Columns[6].GetCellContent(dgOverview.Items[index]) as TextBlock;
                    var zutritt = dgOverview.Columns[5].GetCellContent(dgOverview.Items[index]) as TextBlock;

                    if (Convert.ToDateTime(time) > Convert.ToDateTime(checkEinweisung))
                    {
                        einweis.Text = "Prüfen!";
                        einweis.Background = new SolidColorBrush(Colors.Red);
                    }
                    else
                    {
                        einweis.Text = "OK!";
                        einweis.Background = new SolidColorBrush(Colors.Green);
                    }

                    if (Kat.Text == "Fremdfirma")
                    {
                        checkZutritt = await SQL.ReadSingleValue($"SELECT Arbeitsende FROM firmen WHERE Name = '{selectedFirma}'");

                        if (Convert.ToDateTime(time) > Convert.ToDateTime(checkZutritt))
                        {
                            zutritt.Text = "Prüfen!";
                            zutritt.Background = new SolidColorBrush(Colors.Red);
                        }
                        else
                        {
                            zutritt.Text = "OK!";
                            zutritt.Background = new SolidColorBrush(Colors.Green);
                        }

                        if (Convert.ToDateTime(time) > Convert.ToDateTime(checkZutritt))
                        {
                            zutritt.Text = "Prüfen!";
                            zutritt.Background = new SolidColorBrush(Colors.Red);
                        }
                        else
                        {
                            zutritt.Text = "OK!";
                            zutritt.Background = new SolidColorBrush(Colors.Green);
                        }

                        await SQL.WriteSQL($"INSERT INTO zutritte (Kategorie,NameFirma,Zutritt,Pruefung_Zutritt,Pruefung_Einweisung) VALUES ('{selectedKategorie}','{selectedFirma}','{Convert.ToDateTime(time).ToString("yyyy-MM-dd HH:mm:ss")}','{zutritt.Text}','{einweis.Text}')");
                    }
                    else if (Kat.Text == "Besucher")
                    {
                        checkZutritt = await SQL.ReadSingleValue($"SELECT Besuchstag FROM besucher WHERE Name = '{selectedBesucher}'");

                        if (Convert.ToDateTime(time).Date != Convert.ToDateTime(checkZutritt).Date)
                        {
                            zutritt.Text = "Prüfen!";
                            zutritt.Background = new SolidColorBrush(Colors.Red);
                        }
                        else
                        {
                            zutritt.Text = "OK!";
                            zutritt.Background = new SolidColorBrush(Colors.Green);
                        }

                        if (Convert.ToDateTime(time).Date != Convert.ToDateTime(checkZutritt).Date)
                        {
                            zutritt.Text = "Prüfen!";
                            zutritt.Background = new SolidColorBrush(Colors.Red);
                        }
                        else
                        {
                            zutritt.Text = "OK!";
                            zutritt.Background = new SolidColorBrush(Colors.Green);
                        }

                        await SQL.WriteSQL($"INSERT INTO zutritte (Kategorie,NameBesucher,Zutritt,Pruefung_Zutritt,Pruefung_Einweisung) VALUES ('{selectedKategorie}','{selectedBesucher}','{Convert.ToDateTime(time).ToString("yyyy-MM-dd HH:mm:ss")}','{zutritt.Text}','{einweis.Text}')");
                    }





                    //await SQL.WriteSQL($"INSERT INTO zutritte (Kategorie,Name,Zutritt,Pruefung_Zutritt,Pruefung_Einweisung) VALUES ('{selectedKategorie}','{selectedFirma}','{Convert.ToDateTime(time).ToString("yyyy-MM-dd HH:mm:ss")}','{zutritt.Text}','{einweis.Text}')");
                    overv = await SQL.ReadSQL("SELECT * FROM zutritte", overv);
                    dgOverview.DataContext = overv;
                    //overv.NewRow();
                    //Overviews = DataTableToOverview(overv);

                    dgOverview.CommitEdit(DataGridEditingUnit.Row, true);
                    dgOverview.IsHitTestVisible = false;
                    dgOverview.CanUserAddRows = false;
                }
            }
            else
                MessageBox.Show("Editieren ist nicht möglich", "Achtung");
        }

        private void BtnNew_Click(object sender, RoutedEventArgs e)
        {
            dgOverview.IsHitTestVisible = true;
            dgOverview.CanUserAddRows = true;
        }

    }


    public class Overview
    {
        public string Kategorie;
        public string NameFirma;
        public string NameBesucher;
        public string Zutritt;
        public string Pruefung_Zutritt;
        public string Pruefung_Einweisung;
    }
}
