using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using log4net;

namespace Common.Soap
{
    public class CommonSoapHandler
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
            typeof(CommonSoapHandler)
        );

        public static async Task<string> ExecuteAsync(string url, string soapBody)
        {
            try
            {
                log.Debug($"url: {url} => soapBody: {@soapBody.Replace("\n", "")}");

                // Convert the envelope to a byte array
                var content = new StringContent(
                    @soapBody.Replace("\n", ""),
                    Encoding.UTF8,
                    "text/xml"
                );

                // Send the request
                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromSeconds(120);
                    // Make the POST request
                    var response = await client.PostAsync(url, content);

                    // Read the response content
                    var responseContent = await response.Content.ReadAsStringAsync();

                    log.Debug($"res: {responseContent}");
                    return responseContent;
                }
            }
            catch (Exception ex)
            {
                log.Error("Exception: ", ex);
            }
            return "Error";
        }

        public static HttpWebRequest CreateWebRequest(string url)
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.Headers.Add(@"SOAP:Action");
            webRequest.ContentType = "text/xml;charset=\"utf-8\"";
            webRequest.Accept = "text/xml";
            webRequest.Method = "POST";
            return webRequest;
        }

        public static (string, string) GetResultFromSoap(string data)
        {
            Regex regex = new Regex(
                $"""(?<=<return>)(.*?)(?=<\/return>)""",
                RegexOptions.IgnoreCase
            );
            Match match;
            string result = "-1|Error";
            for (match = regex.Match(data); match.Success; match = match.NextMatch())
            {
                result = match.Groups[0].Value;
            }
            log.Debug($"result regex: {result}");
            if (result.Contains("|"))
            {
                string[] resultSepa = result.Split("|");
                return (resultSepa[0], resultSepa[1]);
            }
            else if (result.Contains("errorCode"))
            {
                string resultErrorCode = "";
                regex = new Regex(
                    $"""(?<=<errorCode>)(.*?)(?=<\/errorCode>)""",
                    RegexOptions.IgnoreCase
                );
                for (match = regex.Match(result); match.Success; match = match.NextMatch())
                {
                    resultErrorCode = match.Groups[0].Value;
                }
                log.Debug($"resultErrorCode regex: {resultErrorCode}");
                return (resultErrorCode, "");
            }
            else
            {
                return (result, "Success");
            }
        }
    }
}
