using SEI2.TestConsole.SEI2ReportProxy;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace SEI2.TestConsole
{
    public static class UserMgmt
    {
        private static string indent = "- ";

        public static bool TryDeserialize(XmlNode contractNode, ref object result)
        {
            if (contractNode.LocalName.Contains(typeof(SEI2DataContractUserMgmt).Name))
            {
                var objType = GetTypeFromXML(contractNode);
                DataContractSerializer serializer = new DataContractSerializer(objType);
                using (XmlNodeReader reader = new XmlNodeReader(contractNode))
                {
                    result = serializer.ReadObject(reader);
                }
            }

            return result != null;
        }

        private static Type GetTypeFromXML(XmlNode bodyNode)
        {
            return
                typeof(XppObjectBase)
                .Assembly
                .GetTypes()
                .Where(type => type.Name == bodyNode.LocalName)
                .Select(item => item).First();
        }

        public static Action<ISEI2Report, object> CreateServiceCall()
        {
            return (ISEI2Report client, object _contract) =>
            {
                var response = client.PerformUserMgmt((SEI2DataContractUserMgmt)_contract);
                LogInfoFromResponse(response);
                Console.WriteLine(string.Empty);
            };
        }

        private static void LogInfoFromResponse(SEI2DataContractResponseUserMgmt response)
        {
            Console.WriteLine("Success: " + response.success);
            if (response.success)
            {
                if (!string.IsNullOrEmpty(response.errorMessage))
                {
                    Console.WriteLine($"Success message: {response.errorMessage}");
                }

                if (response is SEI2DataContractResponseUserMgmtUser user)
                {
                    logUserDetails(user.userDetails);
                }
                else if (response is SEI2DataContractResponseUserMgmtUserGroup userGroup)
                {
                    logUserGroupDetails(userGroup.userGroupDetails);
                }
                else
                {
                    Console.WriteLine("TEST-CLIENT SYSTEM ERROR - UNKNOWN RESPONSE TYPE");
                }
            }
            else
            {
                //Console.WriteLine("Error code: " + response.errorCode); // OBSOLETE
                Console.WriteLine("Error message: " + response.errorMessage);
            }
        }

        private static void logUserDetails(SEI2DataContractUserMgmtUserDetails details)
        {
            string toLog = "USER DETAILS:\n";
            toLog += $"{indent}{nameof(details.userName)}: {details.userName}\n";
            toLog += $"{indent}{nameof(details.userStatus)}: {details.userStatus}\n";
            toLog += $"{indent}{nameof(details.seiUserId)}: {details.seiUserId}\n";
            toLog += $"{indent}{nameof(details.certificateId)}: {details.certificateId}\n";
            toLog += $"{indent}{nameof(details.email)}: {details.email}\n";
            toLog += $"{indent}{nameof(details.cvrNumber)}: {details.cvrNumber}\n";
            toLog += $"{indent}{nameof(details.activationCode)}: {details.activationCode}\n";
            toLog += $"{indent}{nameof(details.personCivilRegistrationIdentifier)}: {details.personCivilRegistrationIdentifier}\n";

            if (details.userSecurityRoles?.Length > 0)
            {
                toLog += $"\n{indent}SECURITY ROLES:\n";
                for (int i = 0; i < details.userSecurityRoles.Length; i++)
                {
                    var role = details.userSecurityRoles[i];
                    toLog += $"{indent}{indent}{nameof(role.name)}: {role.name}\n";
                    toLog += $"{indent}{indent}{indent}{nameof(role.approved)}: {role.approved}\n";
                    toLog += $"{indent}{indent}{indent}{nameof(role.reject)}: {role.reject}\n";
                    toLog += $"{indent}{indent}{indent}{nameof(role.request)}: {role.request}\n";
                };
            }

            if (details.userGroups?.Length > 0)
            {
                toLog += $"\n{indent}GROUPS:\n";
                for (int i = 0; i < details.userGroups.Length; i++)
                {
                    var group = details.userGroups[i];
                    toLog += $"{indent}{indent}{nameof(group.userGroupName)}: {group.userGroupName}\n";
                    toLog += $"{indent}{indent}{indent}{nameof(group.userGroupDescription)}: {group.userGroupDescription}\n";
                    toLog += $"{indent}{indent}{indent}{nameof(group.userGroupId)}: {group.userGroupId}\n";
                    toLog += $"{indent}{indent}{indent}{nameof(group.administrator)}: {group.administrator}\n";
                };


            }

            Console.WriteLine(toLog);
        }

        private static void logUserGroupDetails(SEI2DataContractUserMgmtUserGroupDetails details)
        {
            string toLog = "USER GROUP DETAILS:\n";
            toLog += $"{indent}{nameof(details.userGroupName)}: {details.userGroupName}\n";
            toLog += $"{indent}{indent}{nameof(details.userGroupDescription)}: {details.userGroupDescription}\n";
            toLog += $"{indent}{indent}{nameof(details.userGroupId)}: {details.userGroupId}\n";

            if (details.users?.Length > 0)
            {
                toLog += $"\n{indent}{indent}USERS:\n";
                for (int i = 0; i < details.users.Length; i++)
                {
                    var user = details.users[i];
                    toLog += $"{indent}{indent}{indent}{nameof(user.userName)}: {user.userName}\n";
                    toLog += $"{indent}{indent}{indent}{indent}{nameof(user.userStatus)}: {user.userStatus}\n";
                    toLog += $"{indent}{indent}{indent}{indent}{nameof(user.seiUserId)}: {user.seiUserId}\n";
                    toLog += $"{indent}{indent}{indent}{indent}{nameof(user.administrator)}: {user.administrator}\n";
                };
            }

            Console.WriteLine(toLog);
        }
    }
}
