using BuechermarktClient.Models;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using MongoDB.Driver;
using MongoDB.Bson;
using System.Collections.Generic;
using System.Windows.Data;
using System;
using System.Globalization;
using System.Threading;

namespace BuechermarktClient
{
   [ValueConversion(typeof(object), typeof(string))]
   public class StringConverter : IValueConverter
   {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
         if((double)value == 0)
         {
            return "";
         }
         return value?.ToString();
      }

      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
         var style = NumberStyles.AllowDecimalPoint;
         var c = CultureInfo.CreateSpecificCulture("de-DE");
         if (value == null) return null;
         if ((string)value == "") return 0;
         if (!double.TryParse((string)value, style, c, out double outD)) return null;
         return outD;
      }
   }

   /// <summary>
   /// Interaktionslogik für BookEdit.xaml
   /// </summary>
   public partial class BooksEdit : Window, INotifyPropertyChanged
   {
      private bool New = false;
      private Book Book = null;

      public string LabelId
      {
         get
         {
            return Book.LabelId;
         }
         set
         {
            if(value != Book.LabelId)
            {
               Book.LabelId = value;
               OnPropertyChanged("LabelId");
            }
         }
      }
      public Student Student
      {
         get
         {
            while (true)
            {
               try
               {
                  return MainWindow.StudentCollection.Find(s => s.ID == Book.Student).FirstOrDefault();
               } catch (MongoExecutionTimeoutException)
               {
                  Thread.Sleep(100);
               }
            }
         }
         set
         {
            if (value != null && value.ID != Book.Student)
            {
               Book.Student = value.ID;
               OnPropertyChanged("Student");
            } else if(value == null)
            {
               Book.Student = new MongoDB.Bson.ObjectId();
            }
         }
      }

      public string StudentLabelId
      {
         get
         {
            return Student?.LabelId;
         }
         set
         {
            var st = Student;
            if (st == null || value != st.LabelId)
            {
               var f = true;
               while (f)
               {
                  try
                  {
                     Student = MainWindow.StudentCollection.Find(s => s.LabelId.Equals(value)).FirstOrDefault();
                     f = false;
                  } catch (MongoExecutionTimeoutException)
                  {
                     Thread.Sleep(100);
                  }
               }
               OnPropertyChanged("StudentLabelId");
            }
         }
      }

      public class ComboS
      {
         public ComboS(string name,BookState state)
         {
            Name = name;
            Sate = state;
         }
         public string Name { get; set; }
         public BookState Sate { get; set; }
      }

      public List<ComboS> StatesList;

      public ComboS ComboState
      {
         get
         {
            return StatesList.FirstOrDefault(s => s.Sate == Book.State);
         }
         set
         {
            if(value.Sate != Book.State)
            {
               Book.State = value.Sate;
               OnPropertyChanged("ComboState");
            }
         }
      }

      public double Price
      {
         get
         {
            return Book.Price;
         }
         set
         {
            if(value != Book.Price)
            {
               Book.Price = value;
               OnPropertyChanged("Price");
            }
         }
      }

      public BookType BookType
      {
         get
         {
            while (true)
            {
               try
               {
                  return MainWindow.BookTypeCollection.Find(b => b.ID == Book.BookType).FirstOrDefault();
               } catch (MongoExecutionTimeoutException)
               {
                  Thread.Sleep(100);
               }
            }
         }
         set
         {
            if (value != null && value.ID != Book.BookType)
            {
               Book.BookType = value.ID;
               OnPropertyChanged("BookType");
            }
            else if (value == null)
            {
               Book.BookType = new ObjectId();
            }
         }
      }

      public string BookTypeISBN
      {
         get
         {
            return BookType?.ISBN;

         }
         set
         {
            var bt = BookType;
            if(bt == null || value != bt.ISBN)
            {
               while (true)
               {
                  try
                  {
                     BookType = MainWindow.BookTypeCollection.Find(b => b.ISBN == value).FirstOrDefault();
                     //ToDO Fehler wenn buch nicht vorhanden
                     OnPropertyChanged("BookTypeISBN");
                     return;
                  } catch (MongoExecutionTimeoutException)
                  {
                     Thread.Sleep(100);
                  }
               }
            }
         }
      }

      public event PropertyChangedEventHandler PropertyChanged;
      protected void OnPropertyChanged(string propertyName)
      {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }

      public BooksEdit(Book book)
      {
         StatesList = new List<ComboS>
         {
            new ComboS("Im Lager", BookState.InStock),
            new ComboS("Verkauft", BookState.Selled),
            new ComboS("Verloren", BookState.Missing),
            new ComboS("Zurück an den Schüler", BookState.BackToStudent)
         };
         DataContext = this;
         if (book == null)
         {
            Book = new Book();
            New = true;
         }
         else
         {
            Book = book;
         }
         InitializeComponent();

         StateComboBox.ItemsSource = StatesList;
      }

      private void Save_Click(object sender, RoutedEventArgs e)
      {
         if (New)
         {
            while (true)
            {
               try
               {
                  MainWindow.BookCollection.InsertOne(Book);
                  //var oldStudent = Student;
                  var oldIsbn = BookTypeISBN;
                  Book = new Book();
                  BookTypeISBN = oldIsbn;
                  //Student = oldStudent;
                  Book.State = BookState.InStock;
                  OnPropertyChanged(string.Empty);
                  return;
               } catch (MongoExecutionTimeoutException)
               {
                  Thread.Sleep(100);
               }
            }
         }
         else
         {
            while (true)
            {
               try
               {
                  MainWindow.BookCollection.FindOneAndUpdate(b => b.ID == Book.ID, Builders<Book>.Update
                     .Set(b => b.Student, Book.Student)
                     .Set(b => b.BookType, Book.BookType)
                     .Set(b => b.Price, Book.Price)
                     .Set(b => b.State, Book.State)
                     .Set(b => b.LabelId, Book.LabelId));
                  Close();
                  return;
               } catch (MongoExecutionTimeoutException)
               {
                  Thread.Sleep(100);
               }
            }
         }
      }

      private void Delete_Click(object sender, RoutedEventArgs e)
      {
         if (Book != null && Book.ID != null)
         {
            while (true)
            {
               try
               {
                  MainWindow.StudentCollection.DeleteOne(bt => bt.ID == Book.ID);
                  Close();
                  return;
               }
               catch (MongoExecutionTimeoutException)
               {
                  Thread.Sleep(100);
               }
            }
         } else
         {
            Close();
         }
      }

      private void SelectBookType_Click(object sender, RoutedEventArgs e)
      {
         var btd = new BookTypes(true);
         btd.ShowDialog();
         if (btd.DialogResult == true)
         {
            BookTypeISBN = btd.SelectedItem.ISBN;
         }
      }

      private void BookTypeDetails_Click(object sender, RoutedEventArgs e)
      {
         var bte = new BookTypesEdit(BookType);
         bte.ShowDialog();
      }

      private void StudentDetails_Click(object sender, RoutedEventArgs e)
      {
         var se = new StudentsEdit(Student);
         se.ShowDialog();
      }

      private void SelectStudent_Click(object sender, RoutedEventArgs e)
      {
         var sd = new Students(true);
         sd.ShowDialog();
         if (sd.DialogResult == true)
         {
            StudentLabelId = sd.SelectedItem.LabelId;
         }
      }
   }
}
