using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace CrazyStudio.Core.Common.Tools
{
    public static class HttpTool
    {
        public static async Task<byte[]?> GetBytes(string uri, HttpClient? httpClient = null)
        {

            if (httpClient == null)
            {
                httpClient = new HttpClient();
            }

            using var httpResponse = await httpClient!.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);

            httpResponse.EnsureSuccessStatusCode(); // throws if not 200-299

            httpClient.Dispose();

            if (httpResponse.Content != null)
            {
                var bytes = await httpResponse.Content.ReadAsByteArrayAsync();
                try
                {
                    return bytes;
                }
                catch (Exception)
                {
                    //Console.WriteLine("Exception:" + ex.Message + "; " + ex.StackTrace);
                }
            }
            else
            {
                Console.WriteLine("HTTP Response was invalid and cannot be deserialised.");
            }

            return null;
        }


        public static async Task<T?> GetJson<T>(string uri, HttpClient? httpClient = null)
        {

            if (httpClient == null)
            {
                httpClient = new HttpClient();
            }

            using var httpResponse = await httpClient!.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);

            httpResponse.EnsureSuccessStatusCode(); // throws if not 200-299

            httpClient.Dispose();

            if (httpResponse.Content is object && httpResponse.Content.Headers.ContentType?.MediaType == "application/json")
            {
                var contentStream = await httpResponse.Content.ReadAsStreamAsync();
                try
                {
                    return (await JsonSerializer.DeserializeAsync<T>(contentStream!).ConfigureAwait(false))!;
                }
                catch (Exception)
                {
                    Console.WriteLine("Invalid JSON.");
                }
            }
            else
            {
                Console.WriteLine("HTTP Response was invalid and cannot be deserialised.");
            }

            return default(T);
        }


        public static async Task<string> PostJson(string uri, object parms, Dictionary<string, string>? headers = null)
        {

            using var httpClient = new HttpClient();

            using var stringContent = new StringContent(parms is string ? (string)parms : JsonSerializer.Serialize(parms), Encoding.UTF8, "application/json");

            HttpRequestMessage request = new HttpRequestMessage()
            {
                RequestUri = new Uri(uri),
                Method = HttpMethod.Post,
                Content = stringContent
            };
            if (headers != null)
            {
                foreach (var header in headers!)
                {
                    if (request.Headers.Contains(header.Key))
                    {
                        request.Headers.Remove(header.Key);
                    }
                    request.Headers.Add(header.Key, header.Value);
                }
            }


            using var httpResponse = await httpClient!.SendAsync(request);

            httpResponse.EnsureSuccessStatusCode(); // throws if not 200-299

            httpClient.Dispose();

            if (httpResponse.Content is object)// && httpResponse.Content.Headers.ContentType?.MediaType == "application/json")
            {
                var contentStream = await httpResponse.Content.ReadAsStreamAsync();
                //if (isGetJson)
                //{
                //    try
                //    {
                //        return (await JsonSerializer.DeserializeAsync<T>(contentStream!).ConfigureAwait(false))!;
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine("Invalid JSON.");
                //    }
                //}
                //else
                //{
                //    byte[] bytes = new byte[contentStream.Length];
                //    contentStream.Read(bytes, 0, bytes.Length);
                //    string str = Encoding.UTF8.GetString(bytes);
                //    Console.WriteLine(str);
                //}
                contentStream.Seek(0, SeekOrigin.Begin);
                byte[] bytes = new byte[contentStream.Length];
                contentStream.Read(bytes, 0, bytes.Length);
                string str = Encoding.UTF8.GetString(bytes);
                return str;
            }
            else
            {
                Console.WriteLine("HTTP Response was invalid and cannot be deserialised.");
            }

            return string.Empty;
        }

        public static async Task<Image> GetImageFromUrlAsync(string imageUrl)
        {
            if (string.IsNullOrEmpty(imageUrl))
            {
                throw new ArgumentNullException(nameof(imageUrl), "图片URL不能为空");
            }

            using (var httpClient = new HttpClient())
            {
                try
                {
                    byte[] imageData = await httpClient.GetByteArrayAsync(imageUrl);
                    using (var memoryStream = new MemoryStream(imageData))
                    {
                        return Image.FromStream(memoryStream);
                    }
                }
                catch (HttpRequestException ex)
                {
                    throw new Exception($"HTTP请求失败: {ex.Message}", ex);
                }
                catch (Exception ex)
                {
                    throw new Exception($"处理图片时发生错误: {ex.Message}", ex);
                }
            }
        }
    }
}
