using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using COSXML;
using COSXML.Auth;
using COSXML.Model.Object;
using COSXML.Model.Bucket;
using COSXML.CosException;
using System;
using Newtonsoft.Json;
using LitJson;
using System.Threading.Tasks;
using COSXML.Transfer;
using System.IO;
using COSXML.Model;
using Newtonsoft.Json.Linq;

public class COSDownLoad:MonoSingleton<COSDownLoad>
{

    /*
     *  根据下载的类型  分为   -1 Scene  Materail -2 vuforial
     * 
     */

    public SuccessCOS materialSuccessCos;
    public SuccessCOS sceneSuccessCos;
    public SuccessCOS imageSuccessCos;

    public SuccessCOS publicSuccessCos;
    //  QCloudCredentialProvider cosCredentialProvider;
    CosXml materialCosXml;
    CosXml sceneCosXml;
    CosXml imageCosXml;
    CosXml publicCosXml;
    // Start is called before the first frame update

   

private void Start()
    {
       

        
    }

    public void Credential()
    {
        Credential credential = new Credential();
        credential.type = "material";
        string data = JsonConvert.SerializeObject(credential);
        //Debug.Log(data);
        HttpTool.Instance.Post("/storage/credential/create", data, CredentialMaterialCallBack);

        Credential credential2 = new Credential();
        credential2.type = "scene";
        string data2 = JsonConvert.SerializeObject(credential2);
        HttpTool.Instance.Post("/storage/credential/create", data2, CredentialSceneCallBack);

        Credential credential3 = new Credential();
        credential3.type = "image";
        string data3 = JsonConvert.SerializeObject(credential3);
        HttpTool.Instance.Post("/storage/credential/create", data3, CredentialImageCallBack);



//        publicSuccessCos = JsonConvert.DeserializeObject<SuccessCOS>("{'credentials':{'tmpSecretId':'AKIDLyyDWYsUvRDzn - HqetC4XZ9pNMhOjDEYuSKBvlWcep8iVS1dFa87FyVartAR1 - E_','tmpSecretKey':'rTXSx44gpPR / fgrUaT1zvK0xZQZe2SplrpTkoGEsgN4 = ','sessionToken':'3WfLBVhQ7lK1jNbOBMfcKC0BkZEamXYa9b61b73db72c57039c9cd0b65b4e19a7_9 - RKlXQeKHOCLXyEJscL705yLZxSuPrVLA1c - ZCA4TZmW8RA8dp1dJ7k4VZhRrNQhQ2zheytiN2wAqxKElmycMTnbk97t_FuAAqGPdO9IAnuYNbvOSgDXICIpxMsVPSqWS6cXrHeDhVCLkpZUaHiM2Exk - xbvlCflv4VPjsr6gFYQynEa3RBrvL4mWjg0xrSn0Lpz4h_VmEUW7cT3i07bnNqhA9nsdvCbyxf3JL3fwz92m8ltm - x0NK6fCsdIwaWnkHkWfWHBqwTqxMoID4vlGj84_FK4ZEc_HbXIqruZLikSM - 8u16ks78fODGILOt36EX_2_IRz5JGAX2kNj5BvkVUjIV - 6eB - qbJDkQce2sB_dDaA0cfNsrlfYFMQCWizcv5kDDbgkg4uengC0GbTZQUPm9Jyj9QuLsI9N2V7UuIUL41sN0LLWPSxrpZ4nUxjRJykleSnQ0_WnZaBIa2bFJAxdxOvJXuGIDqIhcTVsPmJkN_O7VUMFPousM9bAVQJjYeSh2a39eVcUJnvWIpiLSNtbgOZFOuXsofS4FYD8aNX3GWrzEyQXoAGBwasRFvjj7aiSgURVM7ue11i_Wz56RiFo2bNihu5cgGsx271ts'},'startTime':1694402249,'expiredTime':1694402549,'bucket':'fat - store - 10001 - 1317557471','path':' / personal / image / 156','region':'ap - shanghai'}");


//        CosXmlConfig config = new CosXmlConfig.Builder()
//         .IsHttps(true)
//         .SetRegion(publicSuccessCos.region)
//         .SetDebugLog(true)
//         .Build();

//        Debug.Log("" + publicSuccessCos.credentials);
//        QCloudCredentialProvider cosCredentialProvider = new DefaultSessionQCloudCredentialProvider(
//publicSuccessCos.credentials.tmpSecretId, publicSuccessCos.credentials.tmpSecretKey, publicSuccessCos.expiredTime, publicSuccessCos.credentials.sessionToken);
//        publicCosXml = new CosXmlServer(config, cosCredentialProvider);

//        TestDownloadObject("default/c39352b7-0ecf-402b-8693-ca8dee01cc0e.dat", Application.persistentDataPath + "/");


    }

    private void InitMaterialCos()
    {
        CosXmlConfig config = new CosXmlConfig.Builder()
            .IsHttps(true)
            .SetRegion(materialSuccessCos.region)
            .SetDebugLog(true)
            .Build();
        QCloudCredentialProvider cosCredentialProvider  = new DefaultSessionQCloudCredentialProvider(
 materialSuccessCos.credentials.tmpSecretId, materialSuccessCos.credentials.tmpSecretKey, materialSuccessCos.expiredTime, materialSuccessCos.credentials.sessionToken);

        materialCosXml = new CosXmlServer(config, cosCredentialProvider);

    }

    private void InitImageCos()
    {
        CosXmlConfig config = new CosXmlConfig.Builder()
            .IsHttps(true)
            .SetRegion(imageSuccessCos.region)
            .SetDebugLog(true)
            .Build();
        QCloudCredentialProvider cosCredentialProvider = new DefaultSessionQCloudCredentialProvider(
 imageSuccessCos.credentials.tmpSecretId, imageSuccessCos.credentials.tmpSecretKey, imageSuccessCos.expiredTime, imageSuccessCos.credentials.sessionToken);

        imageCosXml = new CosXmlServer(config, cosCredentialProvider);


    }

    private void InitSceneCos()
    {
        CosXmlConfig config = new CosXmlConfig.Builder()
            .IsHttps(true)
            .SetRegion(sceneSuccessCos.region)
            .SetDebugLog(true)
            .Build();
        QCloudCredentialProvider cosCredentialProvider = new DefaultSessionQCloudCredentialProvider(
 sceneSuccessCos.credentials.tmpSecretId, sceneSuccessCos.credentials.tmpSecretKey, sceneSuccessCos.expiredTime, sceneSuccessCos.credentials.sessionToken);

        sceneCosXml = new CosXmlServer(config, cosCredentialProvider);
    }

    private void CredentialMaterialCallBack( string msg)
    {
        Debug.Log(msg);
        JObject jObject = JObject.Parse(msg);

        if (jObject["code"].ToString() == "200")
        {
            materialSuccessCos = JsonConvert.DeserializeObject<SuccessCOS>(jObject["data"].ToString());
            InitMaterialCos();
        }
        else
        {
            Debug.LogError(msg);
        }
    }

    private void CredentialSceneCallBack(string msg)
    {
        Debug.Log(msg);
        JObject jObject = JObject.Parse(msg);

        if (jObject["code"].ToString() == "200")
        {
            sceneSuccessCos = JsonConvert.DeserializeObject<SuccessCOS>(jObject["data"].ToString());
            InitSceneCos();
        }
        else
        {
            Debug.LogError(msg);
        }

    }

    private void CredentialImageCallBack(string msg)
    {
        Debug.Log(msg);
        JObject jObject = JObject.Parse(msg);

        if (jObject["code"].ToString() == "200")
        {
            imageSuccessCos = JsonConvert.DeserializeObject<SuccessCOS>(jObject["data"].ToString());
            InitImageCos();
        }
        else
        {
            Debug.LogError(msg);
        }

    }

    public static int showDownLoadCount;
    public static int showDownEndLoadCount;
    public static float showDownLoadPre;

    public async void TestDownloadObject( string downloadPath,string localDir)
    {
        TransferConfig transferConfig = new TransferConfig();
        TransferManager transferManager;  // 初始化 TransferManager
        String bucket; //存储桶,格式:BucketName-APPID
        transferManager = new TransferManager(publicCosXml, transferConfig);
        bucket = publicSuccessCos.bucket;

        string localFileName = Path.GetFileName(downloadPath);

     //   localDir = downloadMaterial.localLoadPath.Substring(0, downloadMaterial.localLoadPath.Length - localFileName.Length);
        // 下载对象
        COSXMLDownloadTask downloadTask = new COSXMLDownloadTask(bucket, downloadPath,
          localDir, localFileName);
        // 手动设置高级下载接口的并发数 (默认为5), 从5.4.26版本开始支持!
        //downloadTask.SetMaxTasks(10);
        downloadTask.progressCallback = delegate (long completed, long total)
        {
            //  Debug.Log(String.Format("Hjj    download"+downloadMaterial.downLoadPath+"progress = {0:##.##}%", completed * 100.0 / total));
           // showDownLoadPre = completed * 100.0f / total;
        };
        Debug.Log(downloadPath + "|||||||||  DGJ");
      //  downloadTask.onState += OnState;
      //  listDownLoadTask.Add(downloadTask);
        try
        {
            
            COSXML.Transfer.COSXMLDownloadTask.DownloadTaskResult result = await
              transferManager.DownloadAsync(downloadTask);
            Console.WriteLine(result.GetResultInfo());
            string eTag = result.eTag;
        }
        catch (COSXML.CosException.CosClientException clientEx)
        {
            //请求失败
            Debug.LogError(downloadPath + "   CosClientException: " + clientEx);
            DownloadResManager.Instance.DownLoadFaild(downloadTask.localFileName);
           
        }
        catch (COSXML.CosException.CosServerException serverEx)
        {
            //请求失败
            Debug.LogError(downloadPath + "    CosServerException: " + serverEx.GetInfo());
            DownloadResManager.Instance.DownLoadFaild(downloadTask.localFileName);
          
        }
    }

    /// <summary>
    /// 高级接口下载对象
    /// </summary>
    /// <param name="cosPath"> 下载地址 </param>
    /// <param name="localDir"> 本地保存文件夹</param>
    /// <param name="localFileName"> 本地保存文件名</param>
    /// <returns></returns>
    public async void TransferDownloadObject(DownLoadMaterial downloadMaterial, string localDir)
    {
        // 初始化 TransferConfig
        TransferConfig transferConfig = new TransferConfig();
        // 手动设置高级下载接口的分块阈值为 20MB(默认为20MB), 从5.4.26版本开始支持!
        //transferConfig.DivisionForDownload = 20 * 1024 * 1024;
        // 手动设置高级下载接口的分块大小为 10MB(默认为5MB),不建议此处设置过小的分块值,可能导致频繁重试或下载速度不合预期
        //transferConfig.SliceSizeForDownload = 10 * 1024 * 1024;
        TransferManager transferManager;  // 初始化 TransferManager
        String bucket; //存储桶,格式:BucketName-APPID


        Debug.Log("Hjj   TransferDownloadObject===>"+ downloadMaterial.type);
        switch (downloadMaterial.type)
        {
            case "-1":
                transferManager = new TransferManager(sceneCosXml, transferConfig);
                bucket = sceneSuccessCos.bucket;
                break;
            case "-2":
                transferManager = new TransferManager(imageCosXml, transferConfig);
                bucket = imageSuccessCos.bucket;
                break;
           

            default:
                transferManager = new TransferManager(materialCosXml, transferConfig);
                if(materialSuccessCos!=null)
                bucket = materialSuccessCos.bucket;
                else
                {
                    showDownEndLoadCount++;
                    return;
                }
                break;
        }

       /// if()

    
                                           // String cosPath = "exampleobject"; //对象在存储桶中的位置标识符,即称对象键
                                           // string localDir = System.IO.Path.GetTempPath();//本地文件夹
                                           // string localFileName = "my-local-temp-file"; //指定本地保存的文件名

        string localFileName = Path.GetFileName(downloadMaterial.localLoadPath);

        localDir = downloadMaterial.localLoadPath.Substring(0, downloadMaterial.localLoadPath.Length - localFileName.Length);
        // 下载对象
        COSXMLDownloadTask downloadTask = new COSXMLDownloadTask(bucket, downloadMaterial.downLoadPath,
          localDir, localFileName);
        // 手动设置高级下载接口的并发数 (默认为5), 从5.4.26版本开始支持!
        //downloadTask.SetMaxTasks(10);
        downloadTask.progressCallback = delegate (long completed, long total)
        {
          //  Debug.Log(String.Format("Hjj    download"+downloadMaterial.downLoadPath+"progress = {0:##.##}%", completed * 100.0 / total));
            showDownLoadPre = completed * 100.0f / total;
        };
        Debug.Log(downloadMaterial.downLoadPath +"|||||||||  DGJ");
        downloadTask.onState += OnState;
        listDownLoadTask.Add(downloadTask);
        try
        {
            COSXML.Transfer.COSXMLDownloadTask.DownloadTaskResult result = await
              transferManager.DownloadAsync(downloadTask);
            Console.WriteLine(result.GetResultInfo());
            string eTag = result.eTag;
        }
        catch (COSXML.CosException.CosClientException clientEx)
        {
            //请求失败
            Debug.LogError(downloadMaterial.downLoadPath + "   CosClientException: " + clientEx);
            DownloadResManager.Instance.DownLoadFaild(downloadTask.localFileName);
            listDownLoadTask.Remove(downloadTask);
            showDownEndLoadCount++;
        }
        catch (COSXML.CosException.CosServerException serverEx)
        {
            //请求失败
            Debug.LogError(downloadMaterial.downLoadPath+ "    CosServerException: " + serverEx.GetInfo());
            DownloadResManager.Instance.DownLoadFaild(downloadTask.localFileName);
            listDownLoadTask.Remove(downloadTask);
            showDownEndLoadCount++;
        }
       
    }

    private List<COSXML.Transfer.COSXMLDownloadTask.DownloadTaskResult> listResult = new List<COSXMLDownloadTask.DownloadTaskResult>();
    private List<COSXMLDownloadTask> listDownLoadTask = new List<COSXMLDownloadTask>();
    /// <summary>
    ///  批量下载 
    /// </summary>
    /// <param name="listDLMaterial">素材列表 </param>
    /// <param name="localDir"> 本地下载文件夹 </param>
    public async void TransferBatchDownloadObjects( List<DownLoadMaterial> listDLMaterial , string localDir)
    {
        if (listDLMaterial.Count == 0 || listDLMaterial == null)
            return;
        //.cssg-snippet-body-start:[transfer-batch-download-objects]
        TransferConfig transferConfig = new TransferConfig();

        // 初始化 TransferManager
        TransferManager transferManager = new TransferManager(materialCosXml, transferConfig);

        // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer
        string bucket = materialSuccessCos.bucket;
        //string localDir = System.IO.Path.GetTempPath();//本地文件夹
        Debug.Log(listDLMaterial.Count);

        for (int i = 0; i < listDLMaterial.Count; i++)
        {
            string cosPath = listDLMaterial[i].downLoadPath;
            Debug.Log(cosPath);
            if(cosPath==null||cosPath=="")
            {
                DownloadResManager.Instance.DownLoadFaild(listDLMaterial[i].localLoadPath);
                continue;
            }    

            string localFileName = Path.GetFileName(listDLMaterial[i].localLoadPath);
            Debug.Log(cosPath + "      " + localDir + localFileName);
            COSXMLDownloadTask downloadTask = new COSXMLDownloadTask(bucket, cosPath,
           localDir, localFileName);
            downloadTask.failCallback = delegate (CosClientException clientException, CosServerException serverException)
            {
                Debug.LogError("clientException.errorCode : " + clientException.errorCode + "  serverException.errorCode: " + serverException.errorCode +
                    "  serverException.errorMessage : " + serverException.errorMessage);
            };
            downloadTask.onState += OnState;

            try
            {
                await transferManager.DownloadAsync(downloadTask);
            }
            catch (COSXML.CosException.CosClientException clientEx)
            {
                //请求失败
               Debug.LogError("CosClientException: " + clientEx);
                DownloadResManager.Instance.DownLoadFaild(downloadTask.localFileName);
                listDownLoadTask.RemoveAt(0);
            }
            catch (COSXML.CosException.CosServerException serverEx)
            {
                //请求失败
                Debug.LogError("CosServerException: " + serverEx.GetInfo());
                DownloadResManager.Instance.DownLoadFaild(downloadTask.localFileName);
                listDownLoadTask.RemoveAt(0);
            }
        
            listDownLoadTask.Add(downloadTask);
        }
    }

    public Queue<TaskState> taskQueue = new Queue<TaskState>();
    private void OnState(TaskState state)
    {
        taskQueue.Enqueue(state);
    }
    private void Update()
    {
        if(taskQueue.Count>0)
        {
            var state = taskQueue.Dequeue();

            if (state == TaskState.Completed || state == TaskState.Failed)
            {
                int ct = listDownLoadTask.Count - 1;
                for (int i = ct; i >= 0; i--)
                {

                    if (listDownLoadTask[i].State() == TaskState.Completed)
                    {
                        showDownEndLoadCount++;
                        Debug.Log(listDownLoadTask.Count + "   " + listDownLoadTask[i].State() + "   " + listDownLoadTask[i].localFileName);
                        DownloadResManager.Instance.DownLoadCompleted(listDownLoadTask[i].localFileName);
                        listDownLoadTask.RemoveAt(i);
                    }else if (listDownLoadTask[i].State() == TaskState.Failed)
                    {
                        showDownEndLoadCount++;
                        Debug.Log(listDownLoadTask.Count + "   " + listDownLoadTask[i].State() + "   " + listDownLoadTask[i].localFileName);
                        DownloadResManager.Instance.DownLoadFaild(listDownLoadTask[i].localFileName);
                        listDownLoadTask.RemoveAt(i);
                    }
                }
            }

        }
    }
}

public class Credential
{
    public string type { get; set; }
}

public class SuccessCOS
{
    public CredentialsCos credentials { get; set; }
    public long startTime { get; set; }
    public long expiredTime { get; set; }
    public string bucket { get; set; }
    public string path { get; set; }
    public string region { get; set; }
}

public class CredentialsCos
{
    public string tmpSecretId { get; set; }
    public string tmpSecretKey { get; set; }

    public string sessionToken { get; set; }
}