using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

using BeWo.ServiceProxy;
using BeWo.ViewModel;

using BS.Shared.Extensions;
using System.Windows.Controls;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using BS.Shared.DataContracts.Compact;
using DevExpress.XtraPrinting.XamlExport;
using Microsoft.Office.Interop.Word;
using Color = System.Drawing.Color;

namespace BeWo.View
{
    public partial class ChatView
    {
        public UserVM ViewModel { get; set; }
        public int abr = 0;


        protected Socket m_mainSocket;
        protected Socket[] m_workerSocket; // = new Socket[10];

        protected ArrayList m_workerSocketList; // = ArrayList.Synchronized(new ArrayList());

        protected AsyncCallback asyncWorkerCallBack;
        protected int clientCount = 0;
       
        protected ListBox saveOnlineList = new ListBox();
       

        public ChatView(String nameinf,String Chatinf ,ArrayList m_workerSocketList )
        {
            InitializeComponent();

            rootGroupBox.Header = nameinf;


         //   AktChatUser.Background = Color.Transparent;
       

          //  Chat.Items.Add(new KontakMessageBuilder(nameinf,Chatinf));

            //this.m_mainSocket = m_mainSocket;
            //this.m_workerSocket = m_workerSocket;
            this.m_workerSocketList = m_workerSocketList;

            //chat.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
           // chat.IsReadOnly = true;
           // chat.IsEnabled = true;

            SetChatSetting();
           
            closeWindow();
        }

        private void SetChatSetting()
        {
            List<string> data = new List<string>();
            data.Add("Gerade Online");
            data.Add("Gerade Offline");
            data.Add("Nur Team");
            data.Add("Nur Mitarbeiter");
            data.Add("Nur Klienten");

            chatSettingControll.ItemsSource = data;
            chatSettingControll.SelectedIndex = 0;
        }

        private void RootGroupBox_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                DragMove();
            }
            catch (Exception) { }
        }

        public void closeWindow() {
            CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, (s, e) =>
            {
                abr = 1;

                //Close();

                Visibility = Visibility.Collapsed;
            }));
        }

        public void SetTextFromMiniV(String[] text, String nameclient, long personoid)
        {
            if (AktChatUser.ItemsSource != null)
            {
                KontaktlistBuilder curItem = (KontaktlistBuilder) AktChatUser.Items[0];

                if (curItem.EmpfaengerOid == personoid)
                {
                    curItem.Receivems = "";
                    if (!nameclient.Equals("NULL") && personoid != 0 )
                    {
                        foreach (String i in text)
                        {
                            Chat.Items.Add(new KontakMessageBuilder(nameclient, i, DateTime.Now.ToString()));
                            SaveChatMessageinDB(personoid, i);
                        }

                        Chat.Items.MoveCurrentToLast();
                        Chat.ScrollIntoView(Chat.Items.CurrentItem);

                    }
                }
                else
                {
                    if (!nameclient.Equals("NULL") && personoid != 0)
                    {
                        int anzReceive = 0;

                        foreach (String i in text)
                        {
                            //hier muss aktualisierung hin für anzahl der ungelesenen nachrichten
                            foreach (var abc in saveOnlineList.Items)
                            {
                                KontaktlistBuilder curitem = (KontaktlistBuilder) abc;

                                if (curitem.EmpfaengerOid == personoid)
                                {
                                    curitem.Receivems = anzReceive++.ToString();
                                }
                            }
                            SaveChatMessageinDB(personoid, i);
                        }
                    }

                }
            }
            else
            {
                if (!nameclient.Equals("NULL") && personoid != 0)
                {
                    int anzRec = 0;

                    foreach (String i in text)
                    {
                        //hier muss aktualisierung hin für anzahl der ungelesenen nachrichten
                        foreach (var abc in saveOnlineList.Items)
                        {
                            KontaktlistBuilder curitem = (KontaktlistBuilder)abc;

                            if (curitem.EmpfaengerOid == personoid)
                            {
                                curitem.Receivems = anzRec++.ToString();
                            }
                        }


                        SaveChatMessageinDB(personoid, i);
                    }
                }
            }
        }

        public void SetText(String text, String nameclient, long personoid)
        {
            if (!nameclient.Equals("NULL") && personoid != 0)
            {

                //Hier mus abfrage hin für Chat , wenn personoid not open dann soll das nicht nur zur db gesendet werden sonder 
                //es soll im ClientList auf der rechten seite eine zahl angezeigt weden, diese zahl ist anzahl ungelesener Nachrichten
                if (AktChatUser.Items.Count != 0)
                {
                    KontaktlistBuilder curItem = (KontaktlistBuilder)AktChatUser.Items[0];
                   
                    if (curItem.EmpfaengerOid == personoid)
                    {
                        curItem.Receivems = "";

                        if (!nameclient.Equals("NULL") && personoid != 0)
                        {          
                            Chat.Items.Add(new KontakMessageBuilder(nameclient, text, DateTime.Now.ToString()));
                            SaveChatMessageinDB(personoid, text);                          

                            Chat.Items.MoveCurrentToLast();
                            Chat.ScrollIntoView(Chat.Items.CurrentItem);
                        }
                    }
                }
                else
                {
                    if (!nameclient.Equals("NULL") && personoid != 0)
                    {

                        //Abfrage foreach und da id zutrifft an der leiste eine nachricht anfügen
                        foreach (var abc in saveOnlineList.Items)
                        {
                            KontaktlistBuilder curitem = (KontaktlistBuilder)abc;

                            if (curitem.EmpfaengerOid == personoid)
                            {
                                int x;
                                bool wasdrin = int.TryParse(curitem.Receivems, out x);

                                if (wasdrin)
                                    curitem.Receivems = x++.ToString();
                                else
                                    curitem.Receivems = 1.ToString();
                            }
                        }

                        SaveChatMessageinDB(personoid, text);
                    }
                }  
            }
        }

        public void SetList(String clientname,long personoid, int workerid)
        {
            try
            {
                   // var person = ServiceFacade.DoCustomerServiceSync(s => s.GetPersonsById(personoid)); person[0].PersonOid.Value
                    String alfa = chatSettingControll.SelectionBoxItem as string;

                    if (alfa.Equals("Gerade Online")) 
                        Clientlist.Items.Add(new KontaktlistBuilder(clientname, "Online", null, personoid, workerid));

                    saveOnlineList.Items.Add(new KontaktlistBuilder(clientname, "Online", null, personoid, workerid));
            }
            catch (Exception)
            {
                //Wenn im Catch bereich dann NoName Chat Nachbar 
                    Clientlist.Items.Add(new KontaktlistBuilder(clientname, "Online", null, personoid, workerid));
            }
        }

        public void RemoveListItem(long clientid)
        {
            foreach (var abc in saveOnlineList.Items)
            {
                KontaktlistBuilder curItem = (KontaktlistBuilder)abc;

                if (curItem.EmpfaengerOid == clientid)
                {

                  /*  if (AktChatUser.Items.Count != 0)  Loscht akt user und akt chat von der view 
                    {
                        KontaktlistBuilder aktItem = (KontaktlistBuilder)AktChatUser.Items[0];

                        if (aktItem.EmpfaengerOid == curItem.EmpfaengerOid)
                        {

                            
                            AktChatUser.Items.Clear();
                            Chat.Items.Clear();
                            
                        }
                    }    */

                    //Item auslesen und nach der passenden oid suchen wenn equal dann delet
                    
                    saveOnlineList.Items.Remove(abc);
                    

                     Clientlist.Items.Clear();

                    if (saveOnlineList.Items.Count == 0)
                        break;
                    else
                    {
                        foreach (var xyz in saveOnlineList.Items) 
                        {
                            Clientlist.Items.Add(xyz);
                        }
                    }
                        

                }
            }
        }

        public void SetServerStats(String servstats)
        {
            ServerStats.Text = servstats;
        }

        private void SendButton_Click(object sender, RoutedEventArgs e)
        {
            if (!AktChatUser.Items.IsEmpty) 
            {
                KontaktlistBuilder curItem = (KontaktlistBuilder)AktChatUser.Items[0];
                
                SendMessage(curItem.EmpfaengerOid,curItem.WorkerId);
                
                SaveChatMessageinDB(curItem.EmpfaengerOid,Chatbox.Text);  

                Chat.Items.MoveCurrentToLast();
                Chat.ScrollIntoView(Chat.Items.CurrentItem);

                Chatbox.Text = "";

                if (Chatbox.Text.Equals(""))
                {
                    Chatbox.Text = "Nachricht schreiben";
                    Chatbox.Foreground = new SolidColorBrush(Colors.DarkGray);
                }
            }
            else
            {
                // gebe eine Nachricht aus das man éinen Chat partner wählen muss 
                Console.WriteLine("Kein Akteur Ausgewählt");
            }
        }

        private void OnKeyDownHandler(object sender, KeyEventArgs e)
        {  
            if (e.Key == Key.Return)
            {
                if (!AktChatUser.Items.IsEmpty) 
                {
                    KontaktlistBuilder curItem = (KontaktlistBuilder)AktChatUser.Items[0];  
                    
                    SendMessage(curItem.EmpfaengerOid,curItem.WorkerId-1);
                    
                    SaveChatMessageinDB(curItem.EmpfaengerOid, Chatbox.Text);   

                    Chat.Items.MoveCurrentToLast();
                    Chat.ScrollIntoView(Chat.Items.CurrentItem);

                    Chatbox.Text = "";
                }
                else
                {
                    // gebe eine NAchricht aus das man éinen Chat partner wählen muss 
                    Console.WriteLine("Kein Akteur Ausgewählt");
                }
            }
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string value = chatSettingControll.SelectedItem as string;

            switch (value)
            {
                case "Gerade Online":
      
                   // Alle zurzeit Online namen in eine liste packen und zwischen speichern und diese liste dann mit der anderen ersetzen 
                    Clientlist.Items.Clear();

                    foreach (var xyz in saveOnlineList.Items) //added alle Save list daten in die Clientlist list data 
                    {
                        Clientlist.Items.Add(xyz);
                    }

                    break;
                case "Gerade Offline":
                   
                    //Rufe alle listen auf und zeige diese an 
                    var offteams = ServiceFacade.DoEmployeeServiceSync(s => s.GetAllTeamsCompact());
                    var offmitarbeiter = ServiceFacade.DoEmployeeServiceSync(s => s.GetAllChatActiveEmployeesCompact());
                    var offklienten = ServiceFacade.DoCustomerServiceSync(s => s.GetAllChatActiveCustomersCompact());

                    Clientlist.Items.Clear();

                    string Goff = "Offline";

                    foreach (var team in offteams)
                    {
                        Clientlist.Items.Add(new KontaktlistBuilder(team.Name, Goff, BuildImg(null),team.TeamOid));
                    }
                    foreach (var list in offmitarbeiter)
                    {
                        Clientlist.Items.Add(new KontaktlistBuilder(list.FirstName, Goff, BuildImg(null),list.PersonOid));
                    }
                    foreach (var list in offklienten)
                    {
                        Clientlist.Items.Add(new KontaktlistBuilder(list.FirstName, Goff, BuildImg(ServiceFacade.DoCustomerServiceSync(s => s.GetCustomerImage(list.CustomerOid))),list.PersonOid));
                    }


                    // Gerade Online mit Gerade Offline Vergleichen und wenn es vergleiche gibt diese dann aus Clientlist nehemen da der ja online ist 
                    foreach (var clist in Clientlist.Items)
                    {
                        KontaktlistBuilder cl = (KontaktlistBuilder) clist;
                        foreach (var savelist in saveOnlineList.Items)
                        {
                            KontaktlistBuilder sl = (KontaktlistBuilder) savelist;
                            if (cl.EmpfaengerOid == sl.EmpfaengerOid )
                            {
                                Clientlist.Items.Remove(cl);
                            }
                        }
                    }



                    break;
                case "Nur Team":
                    
                    var teams = ServiceFacade.DoEmployeeServiceSync(s => s.GetAllTeamsCompact());

                    Clientlist.Items.Clear();

                    string Ton = "Online";
                    
                    //zeigt alle teams die die berechtigung haben an 
                    foreach (var team in teams)
                    {
                        Clientlist.Items.Add(new KontaktlistBuilder(team.Name,Ton,BuildImg(null),team.TeamOid));
                    }

                    break;
                case "Nur Mitarbeiter":      
              
                    var mitarbeiter = ServiceFacade.DoEmployeeServiceSync(s => s.GetAllChatActiveEmployeesCompact());

                    Clientlist.Items.Clear();

                    string Mon = "Online";

                    foreach (var list in mitarbeiter)
                    {                        
                        //überprüfen wer von denen grad online ist und je nachdem aussortieren    
                        foreach (var abc in saveOnlineList.Items)
                        {
                            KontaktlistBuilder curItem = (KontaktlistBuilder)abc;
                            
                            if (curItem.EmpfaengerOid == list.PersonOid)
                                Clientlist.Items.Add(new KontaktlistBuilder(list.FirstName, Mon, BuildImg(null), list.PersonOid));
                        }    
                     }


                    break;
                case "Nur Klienten":                    
                    var klienten = ServiceFacade.DoCustomerServiceSync(s => s.GetAllChatActiveCustomersCompact());

                    Clientlist.Items.Clear();

                    string Kon = "Online";

                    //Add items der Liste //funktionierendes original 
                    foreach (var list in klienten)
                    {
                        foreach (var sl in saveOnlineList.Items)
                        {
                            KontaktlistBuilder curItem = (KontaktlistBuilder)sl;

                            if (curItem.EmpfaengerOid == list.PersonOid)
                                Clientlist.Items.Add(new KontaktlistBuilder(list.FirstName, Kon, BuildImg(ServiceFacade.DoCustomerServiceSync(s => s.GetCustomerImage(list.CustomerOid))), list.PersonOid));                        
                        }
                   }

                    break;
            }
        }
    
        private void ListBoxSelectedIndexChanged(object sender, System.EventArgs e)
        {
            //Bei der auswahl einer neuen sortierung tretten fehler auf 
            //diese werden vorsichtshalber gecatched. 
            KontaktlistBuilder curItem;
            try
            {
                if (!Clientlist.Items.IsEmpty)
                {
                    curItem = (KontaktlistBuilder) Clientlist.SelectedItem;

                    Chat.Items.Clear();  

                    AktChatUser.Items.Clear();

                    if(!curItem.Receivems.Equals("")){
                        int isx = int.Parse(curItem.Receivems);

                        AktChatUser.Items.Add(new KontaktlistBuilder(curItem.Name, curItem.Lastms, curItem.Image,curItem.EmpfaengerOid,curItem.WorkerId.Value,isx));
                    }
                    else
                    {
                        if(curItem.WorkerId == null)
                            AktChatUser.Items.Add(new KontaktlistBuilder(curItem.Name, curItem.Lastms, curItem.Image,curItem.EmpfaengerOid));
                        else
                            AktChatUser.Items.Add(new KontaktlistBuilder(curItem.Name, curItem.Lastms, curItem.Image,curItem.EmpfaengerOid,curItem.WorkerId.Value));
                        
                    }

                    LoadChatMessagefromDB(curItem.EmpfaengerOid);
                    Chat.Items.MoveCurrentToLast();
                    Chat.ScrollIntoView(Chat.Items.CurrentItem);
                }
                else
                {
                    
                }
            }
            catch (Exception s)
            {
                curItem = null;
            }
        }

        public ImageSource BuildImg(Byte[] c)
        {
            if (c != null)
            {
                var biImg = new BitmapImage();
                var ms = new MemoryStream(c);

                biImg.BeginInit();
                biImg.StreamSource = ms;
                biImg.EndInit();

                return biImg;
            }
            else
            {
                return (ImageSource)new ImageSourceConverter().ConvertFromString("../../Ressources/Icons/UserHomeBoyDisabled.png");          
            }
                 
        }

        //Sendet eine Nachricht zum Ausgewählten Clienten
        public void SendMessage(long empfängeroid, int? workerid)
        {
            try
            {
                string sendername = BeWoApp.LoggedOnUser.LoginName;
                string msg = Chatbox.Text;
                Chat.Items.Add(new KontakMessageBuilder(sendername, msg, DateTime.Now.ToString()));
                msg = sendername+": " + msg + "\n";
                byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg);
                Socket workerSocket = null;

                if (workerid != null)
                {
                    workerSocket = (Socket)m_workerSocketList[workerid.Value];
                    if (workerSocket != null)
                    {
                        if (workerSocket.Connected) 
                        {
                            workerSocket.Send(byData);
                        }
                    }
                }
                
                Dispatcher.Invoke(
                DispatcherPriority.Normal,
                (ThreadStart)delegate { ServerStats.Text = "Nachricht erfolgreich gesendet"; });
            }
            catch (Exception xe)
            {
                Dispatcher.Invoke(
                DispatcherPriority.Normal,
                (ThreadStart)delegate { ServerStats.Text = "Ein Fehler im Bereich Message"; });
            }
        }

        //------------------ Speichere die gesendetet nachricht in die Datenbank  ------------------------
        public void SaveChatMessageinDB( long empfangid,string message)
        {
            try
            {  
                ServiceFacade.DoOperationsServiceSync(s => s.CreateNewChatMessagesDC(BeWoApp.LoggedOnEmployee.PersonOid.Value, empfangid, message));
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("Invalid SaveChatMessage Operation");
            }
        }
        
        //------------------ Hole die Gespeicherten Nachrichten aus der Datenbank ------------------------
        public void LoadChatMessagefromDB(long empfaengerOid)
        {
            //if() team abfrage muss noch geregelt werden 
            var allitems = ServiceFacade.DoCustomerServiceSync(s => s.FindAllChatMessages(BeWoApp.LoggedOnEmployee.PersonOid.Value, empfaengerOid));

            foreach (var list in allitems)
            {
               // list.SenderPersonOid
                //    ServiceFacade.
                if(list.SenderPersonOid == BeWoApp.LoggedOnEmployee.PersonOid.Value)
                    Chat.Items.Add(new KontakMessageBuilder(BeWoApp.LoggedOnUser.LoginName, list.ChatText,list.Uhrzeit.ToString()));
                else
                    Chat.Items.Add(new KontakMessageBuilder("Fanko", list.ChatText, DateTime.Now.ToString()));
            }

        }
        
        //placeholder
        private void OnFocus(object sender, EventArgs e)
        {
                Chatbox.Text = "";
                Chatbox.Foreground = new SolidColorBrush(Colors.Black);    
        }
        private void OnDefocus(object sender, EventArgs e)
        {
            if (Chatbox.Text.Equals(""))
            {
                Chatbox.Text = "Nachricht schreiben";
                Chatbox.Foreground = new SolidColorBrush(Colors.DarkGray);
            }
        }
    }

    //####################### Build eine KontaklisteFormat und einen KontaktMessageBuilder Classe || Mapping für die view ##################
    public class KontaktlistBuilder
    {
        public KontaktlistBuilder(string name, string lastms, ImageSource image,long empfaengerid, Int32 workerid/*,boolean isteam*/)
        {
            this.Name = name;
            this.Lastms = lastms;
            this.Image = image;
            this.EmpfaengerOid = empfaengerid;
            this.WorkerId = workerid;
            Receivems = "";
            //this.isTeam = isteam;
        }

        public KontaktlistBuilder(string name, string lastms, ImageSource image, long empfaengerid, Int32 workerid, int receivems/*,boolean isteam*/)
        {
            this.Name = name;
            this.Lastms = lastms;
            this.Image = image;
            this.EmpfaengerOid = empfaengerid;
            this.WorkerId = workerid;
            Receivems = receivems.ToString();
            //this.isTeam = isteam;
        }

        public KontaktlistBuilder(string name, string lastms, ImageSource image, long empfaengerid/*,boolean isteam*/)
        {
            this.Name = name;
            this.Lastms = lastms;
            this.Image = image;
            this.EmpfaengerOid = empfaengerid;
            this.WorkerId = null; 
            
            Receivems = "";
            //this.isTeam = isteam;
        }

        public string Name { get; private set; }

        public string Lastms { get; private set; }

        public ImageSource Image { get; private set; }

        public long EmpfaengerOid { get; private set; }

        public int? WorkerId { get; private set; }

        public string Receivems { get; set; }
        //public Boolean isTeam {get; private set; } 
    }

    public class KontakMessageBuilder
    {
        public KontakMessageBuilder(string username, string message, string sendtime)
        {
            Username = username;
            UserMessage = message;
            SendTime = sendtime;
         
        }

        public string Username { get; private set; }
        public string UserMessage { get; private set; }
        public string SendTime { get; private set; }
        
    }
    //######################################################################################################################################


}
