using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using BodyshopPartner.Utils.Growls;
using Interop.QBFC13;
using Interop.QBXMLRP2;
using ToastNotifications.Messages;

namespace BodyshopPartner.Utils
{
    public static class QuickBooksInterop
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private static string ticket;
        private static RequestProcessor2 rp;
        private static string maxVersion;
        private static QBFileMode mode = QBFileMode.qbFileOpenDoNotCare;
        private static string appID = "ImEXBSP";
        private static string appName = "BodyshopPartner";
        private static GrowlNotification Growler;

        public static void ConnectToQuickBooks()
        {
            if (String.IsNullOrWhiteSpace(Properties.Settings.Default.QuickBooksFilePath) || !File.Exists(Properties.Settings.Default.QuickBooksFilePath))
            {
                throw new Exception("The QuickBooks file specified does not exist.");
            }
            try
            {
                logger.Debug("Attempting to connect to QuickBooks...");
                App.Current.Dispatcher.Invoke(() =>
                {
                    string msg = Properties.Resources.Msg_QbConnection_Title + " " + Properties.Resources.Msg_QbConnection_Msg;

                    Notifications.notifier.ShowInformation(msg);
                    //Growler.AddNotification(new Notification()
                    //{
                    //    Id = new Random().Next(),
                    //    Title = Properties.Resources.Msg_QbConnection_Title,
                    //    Message = Properties.Resources.Msg_QbConnection_Msg
                    //});
                });

                rp = new RequestProcessor2Class();
                rp.OpenConnection(appID, appName);
                ticket = rp.BeginSession(Properties.Settings.Default.QuickBooksFilePath, mode);
                string[] versions = rp.get_QBXMLVersionsForSession(ticket);
                maxVersion = versions[versions.Length - 1];
                logger.Debug("Connected to QuickBooks. Ticket: " + ticket.ToString());

                App.Current.Dispatcher.Invoke(() =>
                {
                    string msg = Properties.Resources.Msg_QbConnected_Title + " " + Properties.Resources.Msg_QbConnected_Msg;

                    Notifications.notifier.ShowInformation(msg);
                    //Growler.AddNotification(new Notification()
                    //{
                    //    Id = new Random().Next(),
                    //    Title = Properties.Resources.Msg_QbConnected_Title,
                    //    Message = Properties.Resources.Msg_QbConnected_Msg
                    //});
                });
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                if (ex.Message.Contains("80040154 Class not registered"))
                {
                    logger.Error("QuickBooks Request Processor not registered. Is QuickBooks installed on this computer?");
                    throw new Exception("QuickBooks Request Processor not registered. Is QuickBooks installed on this computer?");
                }
            }

        }

        public static void DisconnectFromQuickBooks()
        {
            if (ticket != null)
            {
                try
                {
                    rp.EndSession(ticket);
                    ticket = null;
                    rp.CloseConnection();
                    App.Current.Dispatcher.Invoke(() =>
                    {
                        string msg = Properties.Resources.Msg_QbDisconnection_Title + " " + Properties.Resources.Msg_QbDisconnection_Msg;

                        Notifications.notifier.ShowSuccess(msg);

                        //Growler.AddNotification(new Notification()
                        //{
                        //    Id = new Random().Next(),
                        //    Title = Properties.Resources.Msg_QbDisconnection_Title,
                        //    Message = Properties.Resources.Msg_QbDisconnection_Msg
                        //});
                    });
                    logger.Debug("Disconnected from QuickBooks successfully.");
                }
                catch (Exception ex)
                {
                    logger.Error(ex);
                }
            }
        }
        public static string ProcessQBXmlRequest(string request)
        {
            try
            {
                ConnectToQuickBooks();
                var ret = rp.ProcessRequest(ticket, request);
                DisconnectFromQuickBooks();
                return ret;
            }
            catch (Exception e)
            {
                logger.Error(e.Message);
                DisconnectFromQuickBooks();
                return null;
            }
        }
        public static string ProcessQBXmlRequestUnManaged(string request)
        {
            try
            {
                //ConnectToQuickBooks();
                var ret = rp.ProcessRequest(ticket, request);
                //DisconnectFromQuickBooks();
                return ret;
            }
            catch (Exception e)
            {
                logger.Error(e.Message);
                // DisconnectFromQuickBooks();
                return null;
            }
        }
        public static Models.QbXmlResponse ParseResponseXml(XDocument response)
        {
            XElement QueryResponse = response.Root.Descendants("QBXMLMsgsRs").Descendants().FirstOrDefault();
            XAttribute StatusCode = QueryResponse.Attribute("statusCode");
            XAttribute StatusSeverity = QueryResponse.Attribute("statusSeverity");
            XAttribute statusMessage = QueryResponse.Attribute("statusMessage");

            return new Models.QbXmlResponse()
            {
                StatusCode = System.Text.RegularExpressions.Regex.Unescape(StatusCode.Value),
                StatusMessage = System.Text.RegularExpressions.Regex.Unescape(statusMessage.Value),
                StatusSeverity = System.Text.RegularExpressions.Regex.Unescape(StatusSeverity.Value),
                ResponseType = System.Text.RegularExpressions.Regex.Unescape(QueryResponse.Name.LocalName),
                Response = response
            };
        }
        public static void SetGrowler(GrowlNotification g)
        {
            Growler = g;
        }

    }
}
