using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;

namespace Adaptation.Shared.Metrology;

public partial class WS
{

    public static (string, Results) SendData(string url, object payload, int timeoutSeconds = 120)
    {
        Results results = new();
        string resultsJson = string.Empty;
        try
        {
            string json = JsonSerializer.Serialize(payload, payload.GetType());
            if (string.IsNullOrEmpty(url) || !url.Contains(":") || !url.Contains("."))
                throw new Exception("Invalid URL");
            using (HttpClient httpClient = new())
            {
                httpClient.Timeout = new TimeSpan(0, 0, 0, timeoutSeconds, 0);
                HttpRequestMessage httpRequestMessage = new()
                {
                    RequestUri = new Uri(url),
                    Method = HttpMethod.Post,
                    Content = new StringContent(json, Encoding.UTF8, "application/json")
                };
                HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result;
                resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result;
                results = JsonSerializer.Deserialize<Results>(resultsJson);
            }
            if (!results.Success)
                results.Errors.Add(results.ToString());
        }
        catch (Exception e)
        {
            Exception exception = e;
            StringBuilder stringBuilder = new();
            while (exception is not null)
            {
                _ = stringBuilder.AppendLine(exception.Message);
                exception = exception.InnerException;
            }
            if (results.Errors is null)
                results.Errors = new List<string>();
            results.Errors.Add(stringBuilder.ToString());
        }
        return new(resultsJson, results);
    }

    // this method is a wrapper for attaching a file to either a header or data record
    //   URL is the same URL used for SendData, ex: http://localhost/api/inbound/CDE
    //   attachToHeaderId is the ID returned by SendData 
    //   attachToDataUniqueId is the string unique ID for the data record, aka the Title of the Sharepoint list entry
    //   fileContents is a byte array with the contents of the file
    //   fileName is which attachment this is, image.pdf, data.pdf, data.txt, header.pdf, etc
    //   timeoutSeconds is configured as the request timeout
    // this method will either succeed or throw an exception
    // also, this has been made synchronous
    public static void AttachFile(string url, long attachToHeaderId, string attachToDataUniqueId, byte[] fileContents, string fileName, int timeoutSeconds = 60)
    {
        using HttpClient httpClient = new();
        string requestUrl = url + "/attachment?headerid=" + attachToHeaderId.ToString();
        if (!string.IsNullOrWhiteSpace(attachToDataUniqueId))
        {
            requestUrl += "&datauniqueid=";
            requestUrl += System.Net.WebUtility.UrlEncode(attachToDataUniqueId);
        }
        requestUrl += "&filename="; // this is just so the web server log shows the filename
        requestUrl += System.Net.WebUtility.UrlEncode(fileName);

        httpClient.Timeout = new TimeSpan(0, 0, 0, timeoutSeconds, 0);

        MultipartFormDataContent multipartFormDataContent = new();
        ByteArrayContent byteArrayContent = new(fileContents);
        byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");

        multipartFormDataContent.Add(byteArrayContent, "attachment", fileName);

        HttpResponseMessage httpResponseMessage = httpClient.PostAsync(requestUrl, multipartFormDataContent).Result;

        if (httpResponseMessage.IsSuccessStatusCode)
            return;

        string resultBody = httpResponseMessage.Content.ReadAsStringAsync().Result;

        throw new Exception("Attachment failed: " + resultBody);
    }

    public static void AttachFiles(string url, long headerID, List<Attachment> headerAttachments = null, List<Attachment> dataAttachments = null)
    {
        try
        {
            if (headerAttachments is not null)
            {
                foreach (Attachment attachment in headerAttachments)
                    AttachFile(url, headerID, "", File.ReadAllBytes(attachment.SourceFileName), attachment.DestinationFileName);
            }
            if (dataAttachments is not null)
            {
                foreach (Attachment attachment in dataAttachments)
                    AttachFile(url, headerID, attachment.UniqueId, File.ReadAllBytes(attachment.SourceFileName), attachment.DestinationFileName);
            }
            //MessageBox.Show(r.ToString());
        }
        catch (Exception e)
        {
            Exception exception = e;
            StringBuilder stringBuilder = new();
            while (exception is not null)
            {
                _ = stringBuilder.AppendLine(exception.Message);
                exception = exception.InnerException;
            }
            //MessageBox.Show(msgs.ToString(), "Exception", //MessageBoxButtons.OK, //MessageBoxIcon.Error);
            throw new Exception(stringBuilder.ToString());
        }
    }

}