using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.MultiLanguage;
using C4IT.Security;
using C4IT.XML;

using static C4IT.Logging.cLogManager;

namespace C4IT.DataHistoryProvider
{
    public class cDataHistoryConfigM42Wpm : IConfigNodeValidation
    {
        public enum enumApiTokenLifetime
        {
            days30 = 30,
            days90 = 90,
            days180 = 180,
            year1 = 360,
            never = -1
        };

        public bool IsValid { get; private set; } = false;

        public string Server { get; private set; } = null;

        public cCredential Credential { get; private set; } = null;

        public int ClosedTicketHistory { get; private set; } = 10;
        public enumActivityQueueFilterOptions ActivityQueueFilterOption { get; private set; } = enumActivityQueueFilterOptions.showAll;
        public List<cApiM42TicketQueueInfo> ActivityQueues { get; private set; } = new List<cApiM42TicketQueueInfo>();

        [Obsolete("This property is no longer used and will be removed in future versions.")]
        public bool DisableAutomaticTimeTracking { get; private set; } = false;

        public cMultiLanguageDictionary DisplayNames { get; private set; } = new cMultiLanguageDictionary();

        public enumApiTokenLifetime ApiLifetime { get; private set; } = enumApiTokenLifetime.never;

        [Obsolete("This property is no longer used and will be removed in future versions.")]
        public enumShowDocumentCaseDialog ShowDocumentCaseDialog { get; private set; } = enumShowDocumentCaseDialog.ifRequired;

        internal cDataHistoryConfigM42Wpm(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
        {
            MethodBase CM = null;
            if (cLogManager.DefaultLogger.IsDebug)
            {
                CM = MethodBase.GetCurrentMethod();
                LogMethodBegin(CM);
            }
            try
            {
                if (!(XNode.SelectSingleNode("Matrix42-WPM") is XmlElement XNode2))
                    return;

                Parser.EnterElement("Matrix42-WPM");

                try
                {
                    Server = cXmlParser.GetStringFromXmlAttribute(XNode2, "Server", "");
                    if (string.IsNullOrWhiteSpace(Server))
                    {
                        Parser.AddMessage(XNode, $"The attribute 'Server' in element <{XNode2.Name}> is not set.");
                        return;
                    }

                    var strCredential = cXmlParser.GetStringFromXmlAttribute(XNode2, "Credential");
                    if (string.IsNullOrWhiteSpace(strCredential))
                    {
                        Parser.AddInvalidAttribute(XNode, null, "Credential");
                        return;
                    }

                    if (!Credentials.TryGetValue(strCredential, out var _Cred))
                    {
                        Parser.AddMessage(XNode, $"The credential attribute value '{strCredential}' of the element <{XNode.Name}> coud not be resolved.");
                        return;
                    }
                    Credential = _Cred;

                    ClosedTicketHistory = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "ClosedTicketHistory", ClosedTicketHistory);

                    ActivityQueueFilterOption = cXmlParser.GetEnumFromAttribute(XNode2, "ActivityQueueFilter", enumActivityQueueFilterOptions.showAll);
                    if ((XNode2.SelectSingleNode("Queues") is XmlElement XNode3))
                    {
                        Parser.EnterElement("Queues");
                        try
                        {
                            ActivityQueues = cXmlParser.GetObjectsFromXml(
                                XNode3,
                                "Queue",
                                node =>
                                {
                                    XmlAttributeCollection a = node.Attributes;
                                    if (a == null) return null;

                                    string name = a["QueueName"]?.Value;
                                    string id = a["QueueID"]?.Value;
                                    Guid guid = Guid.Empty;

                                    if (string.IsNullOrWhiteSpace(name))
                                        return null;

                                    if (!string.IsNullOrWhiteSpace(id) && !Guid.TryParse(id, out guid))
                                        return null;

                                    return new cApiM42TicketQueueInfo
                                    {
                                        QueueName = name.Trim(),
                                        QueueID = guid
                                    };
                                }
                            );
                        }
                        catch (Exception E)
                        {
                            LogException(E);
                        }
                        finally
                        {
                            Parser.LeaveElement("Queues");
                        }
                    }
                    DisplayNames.LoadFromXmlAttributeList(XNode2, "DisplayName");

                    var _str = cXmlParser.GetStringFromXmlAttribute(XNode2, "ApiTokenLifetime")?.ToLowerInvariant();
                    switch (_str)
                    {
                        case "90 days":
                            ApiLifetime = enumApiTokenLifetime.days90;
                            break;
                        case "180 days":
                            ApiLifetime = enumApiTokenLifetime.days180;
                            break;
                        case "1 year":
                            ApiLifetime = enumApiTokenLifetime.year1;
                            break;
                        case "never":
                            ApiLifetime = enumApiTokenLifetime.never;
                            break;
                        default:
                            ApiLifetime = enumApiTokenLifetime.days30;
                            break;
                    }
                    parseMatrix42Ticket(XNode2, Parser);
                    IsValid = true;
                }
                catch (Exception E)
                {
                    LogException(E);
                }
                finally
                {
                    Parser.LeaveElement("Matrix42-WPM");
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }
        }

        internal void parseMatrix42Ticket(XmlElement XNode, cXmlParser Parser)
        {
            MethodBase CM = null;
            if (cLogManager.DefaultLogger.IsDebug)
            {
                CM = MethodBase.GetCurrentMethod();
                LogMethodBegin(CM);
            }
            try
            {
                if (!(XNode.SelectSingleNode("Matrix42-Ticket") is XmlElement XNode2))
                    return;

                Parser.EnterElement("Matrix42-Ticket");

                try
                {
#pragma warning disable CS0618 // Type or member is obsolete
                    DisableAutomaticTimeTracking = cXmlParser.GetBoolFromXmlAttribute(XNode2, "DisableAutomaticTimeTracking");
                    ShowDocumentCaseDialog = cXmlParser.GetEnumFromAttribute(XNode2, "ShowDocumentCaseDialog", enumShowDocumentCaseDialog.ifRequired);
#pragma warning restore CS0618 // Type or member is obsolete
                }
                catch (Exception E)
                {
                    LogException(E);
                }
                finally
                {
                    Parser.LeaveElement("Matrix42-Ticket");
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }
        }
    }
}
