﻿using System;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using Toast.SmartDL;

public class DLCBehaviour : MonoSingleton<DLCBehaviour>
{
    public LogType LogLevel = LogType.Log;

    public ProgressBar TotalPercentageProgressBar;

    public APIResultLog APIResultLog;

    public InputField CdnUrlInputField;
    public InputField MetaFileNameInputField;
    public InputField TargetPathInputField;

    //private Toast.SmartDL.DLCSkin _skin;

    public static event Action<float> OnPercentageChanged;

    private bool DownloadCompleted = false;
    private bool DownloadStopped = false;

    protected override void OnAwake()
    {
        SmartDLUnitySkin.Initialize();
        OnPercentageChanged += percentage => TotalPercentageProgressBar.Percentage = percentage;

        CdnUrlInputField.text = DLCConfiguration.CdnUrl;
        MetaFileNameInputField.text = DLCConfiguration.MetaFileName;
        TargetPathInputField.text = DLCConfiguration.DownloadPath;

        CdnUrlInputField.onEndEdit.AddListener(DLCConfiguration.SaveCdnUrl);
        MetaFileNameInputField.onEndEdit.AddListener(DLCConfiguration.SaveMetaFileName);
        TargetPathInputField.onEndEdit.AddListener(DLCConfiguration.SaveDownloadPath);

    }

    private void StartDownloadCallback(SmartDLResult result)
    {
        LogFormat(LogType.Log, "<color=yellow>Result is {0}</color>", SmartDLUtil.ToString(result));
        DownloadCompleted = true;
        if (result.ResultCode == (int)DLCErrorCode.DLC_ERR_OK)
            APIResultLog.ResultText = "StartDownload completed successfully.(Full Download)";
        else if (result.ResultCode == (int)DLCErrorCode.DLC_ERR_NO_DIFF)
            APIResultLog.ResultText = "StartDownload completed successfully.(No diff from CDN)";
        else
            APIResultLog.ResultText = "StartDownload failed. ErrorCode : " + result.ResultCode.ToString();
    }

    public void OnClickStart()
    {
        if (DownloadCompleted == true)
            DownloadCompleted = false;

        if (DownloadStopped == true)
            DownloadStopped = false;
        SmartDLUnitySkin.SetAppKey("cJmgZBNr0DxfHe0L");

        SmartDLUnitySkin.StartDownloadCallback callback = StartDownloadCallback;
        SmartDLUnitySkin.StartDownload(CdnUrlInputField.text, MetaFileNameInputField.text, TargetPathInputField.text, callback);
        APIResultLog.ResultText = "Download started.";
        StartCoroutine(UpdateDownloadInfo());
    }

    public void OnClickStop()
    {
        SmartDLUnitySkin.StopDownload();
        DownloadStopped = true;
        APIResultLog.ResultText = "Download stopped.";
    }

    public void OnClickDelete()
    {
        FileUtil.DeleteDirectory(TargetPathInputField.text);
        APIResultLog.ResultText = "TargetPath files are deleted.";
    }

    public void OnClickVerifyFiles()
    {
        //_skin = DLCSkin.GetInstance();
        //var verifyFiles = _skin.VerifyDownloadList(CdnUrlInputField.text, MetaFileNameInputField.text, TargetPathInputField.text);
        //if (verifyFiles.Count == 0)
        //{
        //    APIResultLog.ResultText = "Verify files success. Downloaded contents is the same as CDN Metafile contents.";
        //    Debug.Log("Verify files success. Downloaded contents is the same as CDN Metafile contents.");
        //}
        //else
        //{
        //    APIResultLog.ResultText = "Verify files failed. Downloaded contents is different from CDN Metafile contents.";
        //    Debug.Log("Verify files failed. Downloaded contents is different from CDN Metafile contents.");
        //    foreach (string verifyFile in verifyFiles)
        //    {
        //        Console.WriteLine(verifyFile);
        //    }
        //}
    }

    private IEnumerator UpdateDownloadInfo()
    {
        var container = ThreadProgressContainer.Instance;
        while (true)
        {
            SmartDLProgressInfo progressInfo = SmartDLUnitySkin.GetProgressInfo();
            var percentage = progressInfo.Percentage;
            
            ThreadProgressContainer.Instance.ThreadCount = progressInfo.FileMap.Count;
            
            if (OnPercentageChanged != null) OnPercentageChanged(percentage);
            var fileMapCount = progressInfo.FileMap.Count;
            for (int i = 0; i < fileMapCount; i++)
            {
                SmartDLFileStreamInfo info = progressInfo.FileMap[i];
                container[i].ThreadNumber = i.ToString();
                container[i].FileName = info.FileName;
                container[i].ProgressBar.Percentage = ((float)info.DownloadedBytes / info.TotalBytes) * 100.0f;
            }

            yield return new WaitForEndOfFrame();

            if (DownloadCompleted == true || DownloadStopped == true)
                yield break;
        }
    }

    private void LogFormat(LogType logLevel, string format, params object[] args)
    {
        if ((int)LogLevel >= (int)logLevel)
        {
            switch (LogLevel)
            {
                case LogType.Exception:
                case LogType.Error:
                case LogType.Assert:
                    Debug.LogErrorFormat(format, args);
                    break;
                case LogType.Warning:
                    Debug.LogWarningFormat(format, args);
                    break;
                default:
                    Debug.LogFormat(format, args);
                    break;
            }
        }
    }
}
