using Digst.OioIdws.OioWsTrust;
using Digst.OioIdws.Wsc.OioWsTrust;
using SEI2.TestConsole.SEI2ReportProxy;
using System;
using System.Collections.Generic;

namespace SEI2.TestConsole.Bundles
{
    public static class BundleSender
    {
        public static SEI2DataContractResponseBundle Process(List<SEI2DataContractBundleEntry> entries, bool enforceImportOrder = false)
        {
            return Process(
                new SEI2DataContractBundle()
                {
                    enforceImportOrder = enforceImportOrder,
                    id = Guid.NewGuid().ToString(),
                    entries = entries.ToArray()
                });
        }

        public static SEI2DataContractResponseBundle Process(SEI2DataContractBundle bundle)
        {
            Console.WriteLine("");
            using (var client = new SEI2ReportClient("SoapBinding_ISEI2Report"))
            {
                LogRequest(bundle);

                IStsTokenService stsTokenService = new StsTokenServiceCache(TokenServiceConfigurationFactory.CreateConfiguration());
                var securityToken = stsTokenService.GetToken();
                var channelWithIssuedToken = client.ChannelFactory.CreateChannelWithIssuedToken(securityToken);

                var response = channelWithIssuedToken.ProcessBundle(bundle);
                LogResponse(response);

                return response;
            }
        }

        private static void LogRequest(SEI2DataContractBundle bundle)
        {
            Console.WriteLine($"Processing bundle ({bundle.id}):");
            Console.WriteLine($"- EnforceImportOrder: {bundle.enforceImportOrder}");
            Console.WriteLine($"- Total entries: {bundle.entries.Length} (will be sent in the following order):");
            for (int i = 0; i < bundle.entries.Length; i++)
            {
                var entry = bundle.entries[i];
                Console.WriteLine($"- - {i}: {entry.entryId}, with importOrder: {entry.importOrder}.");
            }
            Console.WriteLine("");
        }

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

                Console.WriteLine($"Enforced import order: {response?.importOrderEnforced}");
                Console.WriteLine($"Entries processed: {response?.entryCountProcessed}/{response?.entryCountTotal}");
                Console.WriteLine($"Entries with error: {response?.entryCountError}");

                Console.WriteLine("Entries:");
                foreach (var entry in response?.entryResults)
                {
                    Console.WriteLine($"- Success: {entry.success}. {entry.entryId}, imported as {entry.importOrderActual} (requested: {entry.importOrderRequested}).");
                    if (!entry.success)
                    {
                        Console.WriteLine($"- - Error: {entry.errorMessage}.");
                    }

                    if (entry is SEI2DataContractResponseBundleEntrySchemaReport reportResponse)
                    {
                        Console.WriteLine($"- - Type: {reportResponse.schemaType}. Version: {reportResponse.schemaVersionNumber}. SchemaId: {reportResponse.schemaId}. SchemaGuid: {reportResponse.schemaGuid}.");
                    }
                    else if (entry is SEI2DataContractResponseBundleEntrySchemaCancel cancelResponse)
                    {
                        Console.WriteLine($"- - (Cancel) Type: {cancelResponse.schemaType}. Version: {cancelResponse.schemaVersionNumber}. SchemaId: {cancelResponse.schemaId}. SchemaGuid: {cancelResponse.schemaGuid}.");
                    }
                    else if (entry is SEI2DataContractResponseBundleEntryUserMgmt userMgmtResponse)
                    {
                        Console.WriteLine($"- - (UserMgmt)");
                        if (userMgmtResponse.userMgmtResponse is SEI2DataContractResponseUserMgmtUser)
                        {
                            var info = userMgmtResponse.userMgmtResponse as SEI2DataContractResponseUserMgmtUser;
                            
                            Console.WriteLine($"- - Name: {info.userDetails.userName}. Status: {info.userDetails.userStatus}.");
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("Error message: " + response.errorMessage);
            }
        }
    }
}
