using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Networking;

class nodeNetProxyItem {
    public string url;
    public Dictionary<string, System.Object> data = null;
    public int Type = 0;//0 get 1 post 2 down ....
    public int faileInterval = 0;
    public bool isText = false;
    public onUrlBackHandler back;
    public int call(string id,bool isSuccess,System.Object netdata)
    {
        return back(id, url, isSuccess, netdata);
    }
}
public class nodeNetProxy : MonoBehaviour
{
    List<nodeNetProxyItem> queues = new List<nodeNetProxyItem>();
    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        List<nodeNetProxyItem> waitRemoves = new List<nodeNetProxyItem>();
        foreach (var item in queues)
        {
            item.faileInterval = item.faileInterval - 1;
            if (item.faileInterval < 0)
            {
                
                int ret = 0;
                if (item.Type == 0)
                {
                    ret = 0;
                    StartCoroutine(httpget(item));
                }else if(item.Type == 2)
                {
                    StartCoroutine(DonLoadImage(item));
                    ret = 0;
                }else if(item.Type == 1)
                {
                    StartCoroutine(httpPost(item));
                    ret = 0;
                }
                if(ret!= 1)
                {
                    waitRemoves.Add(item);
                }
            }
        }
        if(waitRemoves.Count > 0)
        {
            foreach (var item in waitRemoves)
            {
                queues.Remove(item);
            }
        }
    }
    IEnumerator httpget(nodeNetProxyItem item)
    {
        UnityWebRequest request = UnityWebRequest.Get(item.url);
        yield return request.SendWebRequest();
        if (request.isHttpError || request.isNetworkError)
        {
            item.call("", false, null);
            yield return -1;
        }
        if (request.isDone)
        {
            int ret = 0;
            if (item.isText)
            {
                String text = request.downloadHandler.text;
                ret = item.call("", true, text);
            }
            else
            {
                ret = item.call("", true, request.downloadHandler.data);
            }
            if (ret == 1)
            {
                item.faileInterval = 10;
            }
            yield return ret;
        }
        
    }
    IEnumerator httpPost(nodeNetProxyItem item)
    {
        Debug.Log("httpPost::" + item.url);
        Debug.Log("httpPost::" + item.data["netparams"].ToString());
        UnityWebRequest request = UnityWebRequest.Post(item.url, (String)item.data["netparams"], "application/json");
        
        yield return request.SendWebRequest();
        if (request.isHttpError || request.isNetworkError)
        {
            POST(item.url, item.data["srcParams"].ToString(), item.isText, item.back);
        }
        else
        {
            if (item.isText)
            {
                item.back("", item.url, true, request.downloadHandler.text);
            }
            else
            {
                item.back("",item.url,true,null);
            }
            //string receiveContent = request.downloadHandler.text;
            
        }
    }
    public void POST(string url, string jsonParam, bool isText, onUrlBackHandler back)
    {
        nodeNetProxyItem newItem = new nodeNetProxyItem();
        newItem.url = url;
        newItem.back = back;
        newItem.isText = isText;
        newItem.Type = 1;
        newItem.data = new Dictionary<string, object>();
        

        newItem.data["netparams"] = jsonParam;
        newItem.data["srcParams"] = jsonParam;
        this.queues.Add(newItem);
    }
    public void GET(string urlFormat, bool isText, onUrlBackHandler back,params System.Object[] objects)
    {
        GET(string.Format(urlFormat, objects), isText, back);
    }
    public void GET(string url, bool isText, onUrlBackHandler back)
    {
        nodeNetProxyItem newItem = new nodeNetProxyItem();
        newItem.url = url;
        newItem.back = back;
        newItem.Type = 0;
        newItem.isText = isText;
        this.queues.Add(newItem);
    }
    //�����url ����Ĳ��� ����ֵ���� ���������Ƿ����ı�����
    public void GET(string url, Dictionary<String, object> param,bool isText, onUrlBackHandler back)
    {
        string urlNew = url;
        
        if (param != null)
        {
            urlNew = urlNew + "?";
            string str = "";
            foreach (var item in param)
            {
                str += item.Key + "=" + item.Value + "&";
            }
            urlNew = urlNew + str.ToString();
            urlNew = urlNew.Substring(0, urlNew.Length - 1);
        }
        GET(url, isText, back);
    }
    IEnumerator loadLocalFileData(string url,string wurl, onUrlBackHandler back)
    {
        UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);

        yield return request.SendWebRequest();   //���������Ҫ�󷢳�ȥ�����ȴ����

        //��������Ѿ����
        if (request.isDone)
        {
            if (request.isNetworkError || request.isHttpError)  //���������󣬻��ߵ�ַ����
            {
                Debug.Log("error " + request.error + url);       //����������
                back("", wurl, false, null);
            }
            else     //���û��
            {
                //Debug.Log("Ok " + url);
                Texture2D texture2d = DownloadHandlerTexture.GetContent(request);
                back("", wurl, true, texture2d);
            }
        }
    }
    IEnumerator loadLocalTextFileData(string url, string wurl, onUrlBackHandler back)
    {

        UnityWebRequest request = UnityWebRequest.Get(url);
        
        yield return request.SendWebRequest();   //���������Ҫ�󷢳�ȥ�����ȴ����

        //��������Ѿ����
        if (request.isDone)
        {
            Debug.Log("load end " + url);
            if (request.isNetworkError || request.isHttpError)  //���������󣬻��ߵ�ַ����
            {
                Debug.Log(request.error);       //����������
                back("", wurl, false, null);
            }
            else     //���û��
            {

                Debug.Log("load end ok " + url);
                String data1 = DownloadHandlerBuffer.GetContent(request);
                back("", wurl, true, data1);
            }
        }
    }
    public void DOWNTEXT(string url, string localpath, onUrlBackHandler back)
    {
        string abspath = utilsTools.getWritableByPath(localpath);
        if (File.Exists(abspath))
        {
            if (utilsTools.IsPhone == false)
            {
                StartCoroutine(loadLocalTextFileData("file://" + abspath, url, back));
            }
            else
            {
                Debug.Log("jar:file://" + abspath);
                StartCoroutine(loadLocalTextFileData("jar:file://" + abspath, url, back));
            }

            return;
        }else if (url.Equals(""))
        {
            if (back != null) back("", url, false, null);
            return;
        }
        else
        {
            nodeNetProxyItem newItem = new nodeNetProxyItem();
            newItem.url = url;
            newItem.back = back;
            newItem.Type = 2;
            newItem.isText = false;
            newItem.data = new Dictionary<string, object>
            {
                { "path", localpath }
            };
            StartCoroutine(DonLoadText(newItem));
        }
    }
    ////��һ��2DͼƬ����request���ͼƬ���������Ž�ȥ
    //

    ////��һ��sprite��ʽ��ͼƬ��������������ͼƬת����ʽ���Ž�ȥ��
    ////������ֱ��ǣ�ת���Ķ���ת��������ͼƬ�����꣬�Ϳ��ߣ�
    ////    ������������������ԭ��λ�ã�00�������½ǣ�0.5,0.5�����м䣬1,1�������Ͻǣ�
    //Sprite sprite = Sprite.Create(texture2d, new Rect(0, 0, texture2d.width, texture2d.height), new Vector2(0.5f, 0.5f));
    public void DOWNIMG(string url,string localpath, onUrlBackHandler back)
    {
        string abspath = utilsTools.getWritableByPath(localpath);
        if (File.Exists(abspath))
        {
            if (utilsTools.IsPhone == false)
                StartCoroutine(loadLocalFileData("file://" + abspath, url, back));
            else
            {
                //Debug.Log("jar:file://" + abspath);
                StartCoroutine(loadLocalFileData("jar:file://" + abspath, url, back));
            }
            return;
        }else if (url.Equals(""))
        {
            if (back == null) return;
            back("", url, false, null);
            return;
        }
        //Debug.Log("no find path " + localpath + " >> " + abspath);
        //Debug.Log(url);
        nodeNetProxyItem newItem = new nodeNetProxyItem();
        newItem.url = url;
        newItem.back = back;
        newItem.Type = 2;
        newItem.isText = false;
        newItem.data = new Dictionary<string, object>
        {
            { "path", localpath }
        };
        this.queues.Add(newItem);
    }
    IEnumerator DonLoadText(nodeNetProxyItem item)
    {
        string url = item.url;

        var unityWebRequest = UnityWebRequest.Get(url);
        yield return unityWebRequest.SendWebRequest();
        if (unityWebRequest.error != null)
        {
            Debug.Log("DonLoadText error");
            Debug.Log(unityWebRequest.error);
            Debug.Log(unityWebRequest.ToString());
            item.back("", url, false, null);
            yield return unityWebRequest;
        }
        var downloadHandler = unityWebRequest.downloadHandler;
        if (!downloadHandler.isDone)
        {
            Debug.Log("DonLoadText wait");
            yield return downloadHandler;
        }
        else
        {
            Debug.Log("DonLoadText ok");
            var handlerData = downloadHandler;
            string path = item.data["path"] as string;
            yield return File.WriteAllBytesAsync(utilsTools.getWritableByPath(path), handlerData.data);
            StreamReader streamReader = File.OpenText(utilsTools.getWritableByPath(path));
            string data = streamReader.ReadToEnd();
            item.back("", url, true, data);
        }
        yield return null;
    }
    IEnumerator DonLoadImage(nodeNetProxyItem item)
    {
        string url = item.url;

        var unityWebRequest = UnityWebRequestTexture.GetTexture(url);
        yield return unityWebRequest.SendWebRequest();
        if (unityWebRequest.error != null)
        {
            Debug.Log("DonLoadImage error");
            item.back("", url, false, null);
            yield return unityWebRequest;
        }
        var downloadHandler = unityWebRequest.downloadHandler;
        if (!downloadHandler.isDone)
        {
            Debug.Log("DonLoadImage wait");
            yield return downloadHandler;
        }
        else
        {
            //Debug.Log("DonLoadImage ok");
            var handlerData = downloadHandler;
            string path = item.data["path"] as string;
            path = utilsTools.getWritableByPath(path);
            yield return File.WriteAllBytesAsync(path, handlerData.data);
            //AssetDatabase.Refresh();
            string path1 = path;
            string expath = Path.GetExtension(path1);
            path1 = path1.Substring(0, path1.Length - expath.Length);
            if (utilsTools.IsPhone == false)
                StartCoroutine(loadLocalFileData("file://" + path1, url, item.back));
            else
            {
                Debug.Log("jar:file://" + path1);
                StartCoroutine(loadLocalFileData("jar:file://" + path1, url, item.back));
            }

            //Debug.Log(path1);
            //var texture = Resources.Load<Texture>(path1);
            //item.back("", url, true, texture);

        }
        yield return null;
    }
}
