using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class ModelViewerDownloader
{
//    public static string UrlBase = "";
//    public static string SaveLocation = "/idbfs/ModelViewer/";

//    public static ModelViewerDownloader Instance;
//    public bool SyncRequired;

//    public ModelViewerDownloader() : this(UrlBase, "/idbfs/ModelViewer/") { }

//    public ModelViewerDownloader(string baseUrl, string saveLocation)
//    {
//        UrlBase = baseUrl;
//        SaveLocation = saveLocation;
//        ModelViewerMain.GetInstance().StartCoroutine(Loop());
//    }

//    public class DownloadTask
//    {
//        public string Name;
//        public bool Redownload = false;
//        public bool Finished = false;
//        public bool Success = false;
//        public int Priority = 0;
//        public string ResultText;
//        public byte[] ResultBytes;
//        public System.Action OnDownloadSuccess;

//        public DownloadTask(string name, int priority, bool redownload)
//        {
//            Name = name;
//            Priority = priority;
//            Redownload = redownload;
//        }
//    }

//    private static List<DownloadTask> _downloadRunning = new List<DownloadTask>();
//    private static List<DownloadTask> _downloadQueue = new List<DownloadTask>();

//    public IEnumerator Loop()
//    {
//        float lastSync = 5;
//        while (true)
//        {
//            if(_downloadQueue.Count > 0)
//            {
//                _downloadRunning.AddRange(_downloadQueue);
//                _downloadRunning = _downloadRunning.OrderByDescending(d=>d.Priority).ToList();
//                _downloadQueue.Clear();
//            }
//            if(_downloadRunning.Count > 0)
//            {
//                var fileToDownload = _downloadRunning[0];
//                _downloadRunning.RemoveAt(0);
//                yield return DownloadFile(fileToDownload);
//                if(!_downloadRunning.Any() && !_downloadQueue.Any())
//                {
//                    SyncRequired = true;
//                    lastSync = 0;
//                }
//            }
//            if(SyncRequired)
//            {
//                lastSync += Time.deltaTime;
//                if(lastSync >= 5)
//                {
//                    CommitChanges();
//                }
//            }
//            yield return 0;
//        }
//    }

//    public static IEnumerator WaitForDownload(string name, int priority = 0, bool redownload = false, System.Action<string[]> lines = null, System.Action<byte[]> bytes = null, System.Action<string> text = null, System.Action onDownloadSuccess = null)
//    {
//        var task = _downloadQueue.Concat(_downloadRunning).FirstOrDefault(t => t.Name == name);
            
//        if(task == null)
//        {
//            task = new DownloadTask(name, priority, redownload);
//            task.OnDownloadSuccess = onDownloadSuccess;
//            _downloadQueue.Add(task);
//        }

//        while (!task.Finished)
//        {
//            yield return 0;
//        }

//        lines?.Invoke(task.ResultText.Split('\n').Select(s => s.Trim()).ToArray());
//        bytes?.Invoke(task.ResultBytes);
//        text?.Invoke(task.ResultText);
//    }

//    private IEnumerator DownloadFile(DownloadTask task)
//    {
//#if UNITY_WEBGL && !UNITY_EDITOR
//        string fileSavePath = $"{SaveLocation}{task.Name}";
//#else
//        string fileSavePath = Application.persistentDataPath + " /" + task.Name;
//#endif

//        if (!task.Redownload && LoadFromIdbfs(fileSavePath, out var data))
//        {
//            //Debug.Log("Loaded from " + fileSavePath);
//            task.Success = true;
//            task.ResultText = Encoding.UTF8.GetString(data);
//            task.ResultBytes = data;
//            task.Finished = true;
//            yield break;
//        }

//        string url = UrlBase + task.Name + (task.Redownload ? "?time=" + DateTime.Now.Ticks.ToString() : "");
//        //var downloadPanel = KFKViewerUI.Instance.DownloadPanel;

//        //Msg.Log(url);

//        using (var www = UnityWebRequest.Get(url))
//        {
//            //downloadPanel.gameObject.SetActive(true);

//            var operation = www.SendWebRequest();

//            do
//            {
//                //downloadPanel.SetStatus(task.Name, www.downloadProgress);
//                yield return null;
//            }
//            while (!operation.isDone);

//            if (www.result != UnityWebRequest.Result.Success)
//            {
//                Error.Log(Color.red, www.error);
//                task.Success = false;
//                task.ResultText = "";
//                task.ResultBytes = new byte[0];
//            }
//            else
//            {
//                SaveToIdbfs(fileSavePath, www.downloadHandler.data);
//                task.OnDownloadSuccess?.Invoke();
//                task.Success = true;
//                task.ResultText = www.downloadHandler.text;
//                task.ResultBytes = www.downloadHandler.data;
//            }
//        }

//        //downloadPanel.SetStatus(task.Name, 0);
//        //downloadPanel.gameObject.SetActive(false);

//        task.Finished = true;
//    }

//    public static bool LoadFromIdbfs(string name, out byte[] data)
//    {
//        if(File.Exists(name))
//        {
//            data = File.ReadAllBytes(name);
//            return true;
//        }
//        else
//        {
//            data = null;
//            return false;
//        }
//    }

//    public static void SaveToIdbfs(string path, byte[] data)
//    {
//        Directory.CreateDirectory(Path.GetDirectoryName(path));
//        File.WriteAllBytes(path, data);
//        //Debug.Log("Saved " + path);
//    }

//    private static void CommitChanges()
//    {
//        Instance.SyncRequired = false;
//        Debug.Log("Database Updated");
//#if UNITY_WEBGL && !UNITY_EDITOR
//        SyncFiles();
//#endif
//    }

//    [DllImport("__Internal")]
//    private static extern void SyncFiles();
}
