using Gremlin.GremlinData.DBClasses;
using Gremlin.GremlinUI.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Data;
using Microsoft.EntityFrameworkCore;
using Gremlin.GremlinData.EntityClasses;

namespace Gremlin.ViewModels
{
    internal class ContactVM : BaseVM
    {
        public byte Gender { get; private set; }
        public string FirstName { get; private set; }
        public string LastName { get; private set; }
        public string EMail { get; private set; }
        public string AccountName { get; private set; }
        public string AccountStreet { get; private set; }
        public uint AccountZIP { get; private set; }
        public string AccountCity { get; private set; }

        public ContactVM() { }

        public ContactVM(byte gender, string firstName, string lastName, string eMail, string accountName, string accountStreet, uint accountZIP, string accountCity)
        {
            Gender = gender;
            FirstName = firstName ?? throw new ArgumentNullException(nameof(firstName));
            LastName = lastName ?? throw new ArgumentNullException(nameof(lastName));
            EMail = eMail ?? throw new ArgumentNullException(nameof(eMail));
            AccountName = accountName ?? throw new ArgumentNullException(nameof(accountName));
            AccountStreet = accountStreet ?? throw new ArgumentNullException(nameof(accountStreet));
            AccountZIP = accountZIP;
            AccountCity = accountCity ?? throw new ArgumentNullException(nameof(accountCity));
        }

        internal static ContactVM ConvertObjectToContactVM(object selectedItem)
        {
            ContactVM selectedContact = new();

            if (selectedItem != CollectionView.NewItemPlaceholder)
            {
                //TryCast
                selectedContact = selectedItem as ContactVM;

                //if failed == null
                if (selectedContact == null)
                {
                    return default;
                }
            }

            return selectedContact;
        }

        public override string ToString()
        {
            return Gender == (byte)Enums.Gender.Male
                ? $"Herr {FirstName} {LastName}; {AccountName}, {AccountStreet}, {AccountZIP} {AccountCity}"
                : $"Frau {FirstName} {LastName}; {AccountName}, {AccountStreet}, {AccountZIP} {AccountCity}";
        }

        internal static Predicate<object> SearchContact(ListCollectionView listCollectionContacts, string search)
        {
            return listCollectionContacts.Filter = (c) =>
            {
                ContactVM contact = c as ContactVM;
                return contact.LastName.ToLower().Contains(search.ToLower())
                    || contact.FirstName.ToLower().Contains(search.ToLower())
                    || contact.AccountName.ToLower().Contains(search.ToLower())
                    || contact.AccountCity.ToLower().Contains(search.ToLower());
            };
        }

        internal static string FilterContacts(object selectedItem)
        {
            return selectedItem != null
                ? selectedItem == CollectionView.NewItemPlaceholder
                    ? "Bitte neuen Kontakt erstellen"
                    : CreateBriefkopf(selectedItem as ContactVM).ToString()
                : "Kein Kontakt gefunden!";
        }

        internal static ContactVM GetSalesRepAsContact(int SalesRepCode)
        {
            switch (SalesRepCode)
            {
                case 1:
                    {
                        ContactVM salesRepWoitschetzki = new((byte)Enums.Gender.Male,
                                            "Sascha",
                                            "Woitschetzki",
                                            "sascha.woitschetzki@non.agilent.com",
                                            "Handelsvertretung Sascha Woitschetzki",
                                            "Parsevalstr. 58",
                                            45470,
                                            "Mülheim an der Ruhr");
                        return salesRepWoitschetzki;
                    }

                case 2:
                    {
                        ContactVM salesRepWelsch = new((byte)Enums.Gender.Male,
                                                    "Sebastian",
                                                    "Welsch",
                                                    "sebastian.welsch@non.agilent.com",
                                                    "Handelsvertretung Sebastian Welsch",
                                                    "",
                                                    0,
                                                    "");
                        return salesRepWelsch;
                    }

                default:
                    {
                        ContactVM salesRep = new();
                        return salesRep;
                    }
            }
        }

        public static ObservableCollection<ContactVM> GetContacts()
        {
            try
            {
                using (GremlinContext gremlinContext = new())
                {
                    List<Contact> contacts = gremlinContext.Contacts.Include(contact => contact.Account).ToList();
                    ObservableCollection<ContactVM> contactsViewModel = new();

                    foreach (Contact contact in contacts)
                    {
                        ContactVM contactViewModel = new();
                        contactViewModel.Gender = contact.Gender;
                        contactViewModel.LastName = contact.LastName;
                        contactViewModel.FirstName = contact.FirstName;
                        contactViewModel.EMail = contact.EMail;
                        if (contact.Account != null)
                        {
                            contactViewModel.AccountName = contact.Account.AccountName;
                            contactViewModel.AccountStreet = contact.Account.Street;
                            contactViewModel.AccountZIP = contact.Account.ZIP;
                            contactViewModel.AccountCity = contact.Account.City;
                        }
                        contactsViewModel.Add(contactViewModel);
                    }

                    return contactsViewModel;
                }
            }
            catch (Exception ex)
            {
                ErrorHandler.ShowErrorInMessageBox(ex);
                return null;
                throw;
            }
        }

        internal static StringBuilder CreateBriefkopf(ContactVM contactVM, bool tex = false)
        {
            StringBuilder briefkopf = new();

            _ = contactVM.Gender == (byte)Enums.Gender.Male
                ? briefkopf.AppendLine($"Herr {contactVM.FirstName} {contactVM.LastName}")
                : briefkopf.AppendLine($"Frau {contactVM.FirstName} {contactVM.LastName}");
            if (tex) _ = briefkopf.AppendLine($"\\\\");

            string AccountName = contactVM.AccountName;

            //AccountNamen mit "&" im Namen abfangen 
            if (tex && AccountName.Contains("&"))
            {
                string[] accountNameSplit = AccountName.Split("&"); //.Replace?
                AccountName = "";
                for (int i = 0; i < accountNameSplit.Length; i++)
                {
                    AccountName += i < accountNameSplit.Length - 1
                        ? accountNameSplit[i] + "\\&"
                        : accountNameSplit[i];
                }
            }

            _ = briefkopf.AppendLine($"{AccountName}");

            if (tex) { briefkopf.AppendLine($"\\\\"); }
            _ = briefkopf.AppendLine($"{contactVM.AccountStreet}");
            if (tex) { briefkopf.AppendLine($"\\\\"); }
            _ = briefkopf.AppendLine($"{contactVM.AccountZIP} {contactVM.AccountCity}");
            if (tex) { briefkopf.AppendLine($"\\\\"); }

            return briefkopf;
        }

    }
}
