using Microsoft.Win32;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
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;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
namespace StoreServer
{
    /// <summary>
    /// Interaction logic for MonitoringCashierPage.xaml
    /// </summary>
    public partial class MonitoringCashierPage : Page
    {
        public List<WorkShift> WorkShiftOnCashier = new List<WorkShift>();                                     
        public MonitoringCashierPage()
        {
            InitializeComponent();
            List<StringFormatCasier> cashier = new List<StringFormatCasier>();
            foreach (var item in Helper.FindStore.Cashier)
            {
                WorkShiftOnCashier.Add(new WorkShift
                {
                    StartDateAndTimeWork = null,
                    EndDateAndTimeWork = null,
                    Cashier = item,
                    EmployeeInStore = null
                });
                cashier.Add(new StringFormatCasier { NumberCasier = "№" + item.CashierID.ToString(), Number = item.CashierID });
            }
            cashier.Insert(0, new StringFormatCasier { NumberCasier = "Все кассы", Number = 0 });
            CmbCasier.ItemsSource = cashier;
            DaPStartDate.SelectedDate = DateTime.Now;
            DaPEndDate.SelectedDate = DateTime.Now.AddDays(30);
            ListCashier.ItemsSource = WorkShiftOnCashier;
            StartSocketServer();
            StartHttpServer();
            ShowData();
        }

        public void ShowData()
        {
            if (DaPStartDate.SelectedDate == null || DaPEndDate.SelectedDate == null)
            {
                return;
            }
            if (CmbCasier.SelectedIndex == 0)
            {
                OrderList.ItemsSource = DB.db.Order.Where(x => x.Date >= DaPStartDate.SelectedDate
                && x.Date <= DaPEndDate.SelectedDate).ToList();
                return;
            }
            int NumberCasier = (CmbCasier.SelectedItem as StringFormatCasier).Number;
            OrderList.ItemsSource = DB.db.Order.Where(x => x.Date >= DaPStartDate.SelectedDate
            && x.Date <= DaPEndDate.SelectedDate
            && x.WorkShift.Cashier.CashierID == NumberCasier).ToList();

        }

        public class StringFormatCasier
        {
            public string NumberCasier { get; set; }
            public int Number { get; set; }
        }


        public void StartWorkCashier(int CashierID, EmployeeInStore AuthEmployee)
        {
            var CurrentWorkShift = WorkShiftOnCashier.FirstOrDefault(x => x.Cashier.CashierID == CashierID);
            CurrentWorkShift.EmployeeInStore = AuthEmployee;
            ListCashier.ItemsSource = null;
            ListCashier.ItemsSource = WorkShiftOnCashier;
        }

        public void StartWorkShift(int CashierID)
        {
            var CurrentWorkShift = WorkShiftOnCashier.FirstOrDefault(x => x.Cashier.CashierID == CashierID);
            if (CurrentWorkShift.EndDateAndTimeWork != null)
            {
                var NewWorkShift = new WorkShift()
                {
                    StartDateAndTimeWork = null,
                    EndDateAndTimeWork = null,
                    Cashier = CurrentWorkShift.Cashier,
                    EmployeeInStore = CurrentWorkShift.EmployeeInStore
                };
                WorkShiftOnCashier.Remove(CurrentWorkShift);
                WorkShiftOnCashier.Add(NewWorkShift);
            }
            CurrentWorkShift.StartDateAndTimeWork = DateTime.Now;
            ListCashier.ItemsSource = null;
            ListCashier.ItemsSource = WorkShiftOnCashier;
        }

        public void EndWorkShift(int CashierID)
        {
            var CurrentWorkShift = WorkShiftOnCashier.FirstOrDefault(x => x.Cashier.CashierID == CashierID);
            CurrentWorkShift.EndDateAndTimeWork = DateTime.Now;
            ListCashier.ItemsSource = null;
            ListCashier.ItemsSource = WorkShiftOnCashier;
        }


        public async void StartSocketServer()
        {
            string IDStore = Helper.FindStore.StoreID.ToString();
            if (IDStore.Length == 1) IDStore = IDStore.Insert(0, "0");
            IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), Convert.ToInt32("102" + IDStore));
            Socket Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            Listener.Bind(iPEndPoint);
            Listener.Listen(10);
            while (true)
            {
                Socket SocketClient = await Listener.AcceptAsync();
                StringBuilder stringBuilder = new StringBuilder();
                byte[] data = new byte[256];
                int bytes = 0;
                do
                {
                    bytes = SocketClient.Receive(data, data.Length,0);
                    stringBuilder = stringBuilder.Append(Encoding.UTF8.GetString(data, 0, bytes));
                } while (SocketClient.Available >0);
                string Message = stringBuilder.ToString();
                if (Message.Contains("Authorization - Code cashier="))
                {
                    int NumberCashier = Convert.ToInt32(Message.Split(';')[0].Split('=')[1]);
                    var FindCashier = DB.db.Cashier.FirstOrDefault(x => x.IDStore == Helper.FindStore.StoreID && x.CashierID == NumberCashier);
                    if (FindCashier == null)
                    {
                        byte[] buffer = Encoding.UTF8.GetBytes("Магазин не поддерживает кассу с таким номером");
                        SocketClient.Send(buffer);
                        SocketClient.Shutdown(SocketShutdown.Both);
                        SocketClient.Close();
                    }
                    else
                    {
                        string CodeEmployee = Message.Split('=')[2];
                        var FindEmployee = DB.db.EmployeeInStore.FirstOrDefault(x => x.Employee.Code == CodeEmployee && x.IDStore == Helper.FindStore.StoreID);
                        if (FindEmployee == null)
                        {
                            byte[] buffer = Encoding.UTF8.GetBytes("Сотрудник не найден");
                            SocketClient.Send(buffer);
                            SocketClient.Shutdown(SocketShutdown.Both);
                            SocketClient.Close();
                        }
                        else
                        {
                            StartWorkCashier(FindCashier.CashierID, FindEmployee);
                            List<RootDataOfProductInStore> dataOfProductInStores = new List<RootDataOfProductInStore>();
                            foreach (var item in Helper.FindStore.ProductInStore)
                            {
                                dataOfProductInStores.Add(new RootDataOfProductInStore
                                {
                                    ProductInStoreID = item.ProductInStoreID,
                                    RemainsProduct = item.RemainsProduct,
                                    NameProduct = item.Product.NameProduct,
                                    Weight = item.Product.Weight,
                                    Packaging = item.Product.Packaging,
                                    PriceOfOne = item.Product.PriceOfOne,
                                    BarCode = item.Product.BarCode
                                });
                            }
                            string Json = JsonConvert.SerializeObject(dataOfProductInStores);
                            byte[] buffer = Encoding.UTF8.GetBytes("Добро пожаловать =" + Json);
                            SocketClient.Send(buffer);
                            SocketClient.Shutdown(SocketShutdown.Both);
                            SocketClient.Close();
                        }
                    }
                }
                if (Message.Contains("Start work shift ="))
                {
                    int CashierID = Convert.ToInt32(Message.Split('=')[1]);
                    StartWorkShift(CashierID);
                    var CurrentWorkShift = WorkShiftOnCashier.FirstOrDefault(x => x.Cashier.CashierID == CashierID);
                    DB.db.WorkShift.Add(CurrentWorkShift);
                    DB.db.SaveChanges();
                    byte[] buffer = Encoding.UTF8.GetBytes(CurrentWorkShift.WorkShiftID.ToString());
                    SocketClient.Send(buffer);
                    SocketClient.Shutdown(SocketShutdown.Both);
                    SocketClient.Close();
                }
                if (Message.Contains("End work shift ="))
                {
                    int CashierID = Convert.ToInt32(Message.Split('=')[1]);
                    EndWorkShift(CashierID);
                    var CurrentWorkShift = WorkShiftOnCashier.FirstOrDefault(x => x.Cashier.CashierID == CashierID);
                    var FindWorkShift =  DB.db.WorkShift.Find(CurrentWorkShift.WorkShiftID);
                    FindWorkShift.EndDateAndTimeWork = CurrentWorkShift.EndDateAndTimeWork;
                    DB.db.SaveChanges();
                    byte[] buffer = Encoding.UTF8.GetBytes(CurrentWorkShift.WorkShiftID.ToString());
                    SocketClient.Send(buffer);
                    SocketClient.Shutdown(SocketShutdown.Both);
                    SocketClient.Close();
                }
                if (Message.Contains("Data of Order ="))
                {
                    string JsonDataOfOrder = Message.Split('=')[1];
                    var PostOrder = JsonConvert.DeserializeObject<RootDataOfOrder>(JsonDataOfOrder);
                    Order NewOrder = new Order
                    {
                        Date = PostOrder.Date,
                        IDWorkShift = PostOrder.IDWorkShift,
                        State = true,
                        
                    };
                    DB.db.Order.Add(NewOrder);
                    DB.db.SaveChanges();
                    List<ProductInOrder> productInOrders = new List<ProductInOrder>();
                    foreach (var item in PostOrder.ProductInOrders)
                    {
                        productInOrders.Add(new ProductInOrder
                        {
                            AmountProduct = item.AmountProduct,
                            IDOrder = NewOrder.OrderID,
                            IDProduct = item.ProductInStore.ProductInStoreID
                        });
                    }
                    DB.db.ProductInOrder.AddRange(productInOrders);
                    DB.db.SaveChanges();
                    foreach (var item in productInOrders)
                    {
                        var ProductInStore = DB.db.ProductInStore.Find(item.IDProduct);
                        ProductInStore.RemainsProduct = ProductInStore.RemainsProduct - item.AmountProduct;
                        DB.db.SaveChanges();
                    }
                    SocketClient.Shutdown(SocketShutdown.Both);
                    SocketClient.Close();
                }
            }
        } 

        public async void StartHttpServer()
        {
            HttpListener listener = new HttpListener();
            listener.Prefixes.Add("http://127.0.0.2:" + Helper.FindStore.StoreID.ToString() + "/");
            listener.Start();
            while (true)
            {
                HttpListenerContext context = await listener.GetContextAsync();
                HttpListenerRequest request = context.Request;
            }
        }


        private void BtnInToPDF_Click(object sender, RoutedEventArgs e)
        {
            if ((OrderList.ItemsSource as List<Order>).Count == 0)
            {
                return;
            }
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.FileName = "PDFreport";
            saveFileDialog.Filter = "PDF document |*.pdf";
            if (saveFileDialog.ShowDialog() == true)
            {
                ToPDFText(saveFileDialog.FileName);
            }
        }

        public void ToPDFTable()
        {
            Word.Application app = new Word.Application();
            Word.Document doc = app.Documents.Add();
        }

        public void ToPDFText(string Path)
        {
            Word.Application app = new Word.Application();
            Word.Document doc = app.Documents.Add();
            Word.Paragraph paragraph = doc.Paragraphs.Add();
            List<Order> Orders = OrderList.ItemsSource as List<Order>;
            string Data = $"Отчётный период: c {DaPStartDate.SelectedDate.Value.ToString("dd.MM.yyyy")} по {DaPEndDate.SelectedDate.Value.ToString("dd.MM.yyyy")}\n\n";
            foreach (var item in Orders)
            {
                Data += $"Касса №: {item.WorkShift.Cashier.CashierID}\n" +
                    $"Кассир: {item.WorkShift.EmployeeInStore.Employee.FullName}\n" +
                    $"Номер заказа: {item.OrderID}\n" +
                    $"Дата: {item.Date.ToString("dd.MM.yyyy")}\n" +
                    $"Продукт: {item.ProductInOrderString}" +
                    $"Стоимость: {item.CostOfOrder}\n\n";
            }
            paragraph.Range.Text = Data;
            doc.SaveAs2(Path, Word.WdSaveFormat.wdFormatPDF);
        }

        public void ToCSV(string Path)
        {
            Excel.Application app = new Excel.Application();
            Excel.Workbook workbook = app.Workbooks.Add();
            Excel.Worksheet worksheet = workbook.Worksheets.Add();
            OrderList.SelectAllCells();
            OrderList.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
            ApplicationCommands.Copy.Execute(null, OrderList);
            worksheet.Paste();
            workbook.SaveAs(Path);
            workbook.Close();
            app.Quit();
        }

        private void BtnInToCSV_Click(object sender, RoutedEventArgs e)
        {
            if ((OrderList.ItemsSource as List<Order>).Count == 0)
            {
                return;
            }
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.FileName = "CSVreport";
            saveFileDialog.Filter = "CSV document |*.csv";
            if (saveFileDialog.ShowDialog()==true)
            {
                ToCSV(saveFileDialog.FileName);
            }
        }

        private void CmbCasier_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowData();
        }

        private void DaPStartDate_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowData();
        }

        private void DaPEndDate_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowData();
        }
    }
}
