using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

namespace MotionFramework.Scripts.Runtime.Engine.Engine.Network.WebRequest
{
    /// <summary>
    ///  WebRequest 管理器
    /// </summary>
    public sealed class WebRequestManager : ModuleSingleton<WebRequestManager>, IModule
    {
        /// <summary>
        /// Get获取内容
        /// </summary>-
        /// <param name="url"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<string> GetTextAsync(string url, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = UnityWebRequest.Get(url))
            {
                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return request.downloadHandler.text;
            }
        }

        /// <summary>
        /// 获取图片
        /// </summary>
        /// <param name="url"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<Texture2D> GetImageAsync(string url, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(url))
            {
                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return DownloadHandlerTexture.GetContent(request);
            }
        }

        /// <summary>
        /// 获取视频
        /// </summary>
        /// <param name="url"></param>
        /// <param name="localPath"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<string> GetVideoAsync(string url, string localPath, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = UnityWebRequest.Get(url))
            {
                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                File.WriteAllBytes(localPath, request.downloadHandler.data);
                return localPath;
            }
        }

        /// <summary>
        /// 获取文件
        /// </summary>
        /// <param name="url"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<byte[]> GetFileAsync(string url, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = UnityWebRequest.Get(url))
            {
                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return request.downloadHandler.data;
            }
        }

        /// <summary>
        /// 获取内容
        /// </summary>
        /// <param name="url"></param>
        /// <param name="jsonData"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<string> PostTextAsync(string url, string jsonData, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
            {
                byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(jsonData);
                request.uploadHandler = new UploadHandlerRaw(bodyRaw);
                request.downloadHandler = new DownloadHandlerBuffer();
                request.SetRequestHeader("Content-Type", "application/json");

                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return request.downloadHandler.text;
            }
        }

        /// <summary>
        /// 获取图片
        /// </summary>
        /// <param name="url"></param>
        /// <param name="jsonData"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<Texture2D> PostImageAsync(string url, string jsonData, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
            {
                byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(jsonData);
                request.uploadHandler = new UploadHandlerRaw(bodyRaw);
                request.downloadHandler = new DownloadHandlerTexture();
                request.SetRequestHeader("Content-Type", "application/json");

                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return DownloadHandlerTexture.GetContent(request);
            }
        }

        /// <summary>
        /// 获取视频
        /// </summary>
        /// <param name="url"></param>
        /// <param name="jsonData"></param>
        /// <param name="localPath"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<string> PostVideoAsync(string url, string jsonData, string localPath, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
            {
                byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(jsonData);
                request.uploadHandler = new UploadHandlerRaw(bodyRaw);
                request.downloadHandler = new DownloadHandlerBuffer();
                request.SetRequestHeader("Content-Type", "application/json");

                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                File.WriteAllBytes(localPath, request.downloadHandler.data);
                return localPath;
            }
        }

        /// <summary>
        /// 获取文件
        /// </summary>
        /// <param name="url"></param>
        /// <param name="jsonData"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<byte[]> PostFileAsync(string url, string jsonData, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
            {
                byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(jsonData);
                request.uploadHandler = new UploadHandlerRaw(bodyRaw);
                request.downloadHandler = new DownloadHandlerBuffer();
                request.SetRequestHeader("Content-Type", "application/json");

                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return request.downloadHandler.data;
            }
        }

        /// <summary>
        /// 提交表单
        /// </summary>
        /// <param name="url"></param>
        /// <param name="formFields"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async UniTask<string> PostFormAsync(string url, Dictionary<string, string> formFields, Action<float> onProgress = null, CancellationToken cancellationToken = default)
        {
            using (UnityWebRequest request = UnityWebRequest.Post(url, formFields))
            {
                await SendRequestWithProgress(request, onProgress, cancellationToken);
                if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                {
                    Debug.LogError($"异常： {request.error}");
                    return null;
                }
                return request.downloadHandler.text;
            }
        }

        /// <summary>
        /// 进度
        /// </summary>
        /// <param name="request"></param>
        /// <param name="onProgress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async UniTask SendRequestWithProgress(UnityWebRequest request, Action<float> onProgress, CancellationToken cancellationToken)
        {
            // 正确使用await来启动异步请求
            var operation = request.SendWebRequest();

            // 循环检查请求是否完成，并更新进度
            while (!operation.isDone)
            {
                onProgress?.Invoke(request.downloadProgress);

                //Debug.Log($"Progress: {request.downloadProgress * 100:F2}%");
                await UniTask.Delay(100, cancellationToken: cancellationToken);  // 每100毫秒更新一次进度
            }
            onProgress?.Invoke(1.0f);
            // 最后一次进度更新，确保进度显示为100%
            Debug.Log("Progress: 100%");
        }

        public void OnCreate(object createParam)
        {
        }

        public void OnUpdate()
        {
        }

        public void OnDestroy()
        {
        }

        public void OnGUI()
        {
        }
    }
}
