using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

namespace WS
{
    [ObjectSystem]
    public class RequestAsyncUpdate : UpdateSystem<RequestAsync>
    {
        public override void Update(RequestAsync self)
        {
            self.Update();
        }
    }

    ///<summary>Web请求代理</summary>
    public class RequestAsync : WSComponent
    {
        ///<summary>HTTP请求</summary>
        public UnityWebRequest Request;
        ///<summary>取消</summary>
        public bool isCancel;
        ///<summary>异步</summary>
        private TaskCompletionSource<bool> tcs;

        public override void Dispose()
        {
            base.Dispose();
            Request?.Dispose();
            Request = null;
            isCancel = false;
            tcs = null;
        }

        ///<summary>进度</summary>
        public float Progress
        {
            get
            {
                if (Request == null)
                    return 0;
                return Request.downloadProgress;
            }
        }

        ///<summary>请求的字节数</summary>
        public ulong ByteDownloaded
        {
            get
            {
                if (Request == null)
                    return 0;
                return Request.downloadedBytes;
            }
        }

        public void Update()
        {
            if (isCancel)
            {
                tcs.SetResult(false);
                return;
            }

            if (!Request.isDone)
            {
                return;
            }
            if (!string.IsNullOrEmpty(Request.error))
            {
                tcs.SetResult(true);
                return;
            }
            tcs.SetResult(true);
        }

        /// <summary>Get请求</summary>
        public Task<bool> GetAsync(string url, params string[] header)
        {
            tcs = new TaskCompletionSource<bool>();
            Request = UnityWebRequest.Get(url);
            Request.timeout = RequestComponent.OutTime;
            RequestComponent.Instance.SetHeader(header, Request);
            Request.SendWebRequest();
            return tcs.Task;
        }

        ///<summary>Post请求</summary>
        public Task<bool> PostAsync(string url, string json, params string[] header)
        {
            tcs = new TaskCompletionSource<bool>();
            byte[] postBytes = System.Text.Encoding.Default.GetBytes(json);
            Request = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST);
            Request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
            Request.SetRequestHeader("Content-Type", "application/json");
            Request.timeout = RequestComponent.OutTime;
            RequestComponent.Instance.SetHeader(header, Request);
            Request.SendWebRequest();
            return tcs.Task;
        }

        ///<summary>Post请求</summary>
        public Task<bool> PostAsync(string url, WWWForm form, params string[] header)
        {
            tcs = new TaskCompletionSource<bool>();
            Request = UnityWebRequest.Post(url, form);
            Request.timeout = RequestComponent.OutTime;
            RequestComponent.Instance.SetHeader(header, Request);
            Request.SendWebRequest();
            return tcs.Task;
        }
    }
}