﻿#if UNITY_EDITOR
using System;
using RKOKO.Config.Free.Editor;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;

public static class NewtonsoftJsonInstaller
{
    private const string PackageName = "com.unity.nuget.newtonsoft-json";

    private static AddRequest _addRequest;
    private static double _startTime;
    private static bool _isInstalling;
    private static Action<bool, string> _onCompleted;

    public static void InstallNewtonsoftJson(Action<bool, string> onCompleted = null)
    {
        if (_isInstalling)
        {
            onCompleted?.Invoke(false, EditorLocalize.Get(2001));
            return;
        }

        _isInstalling = true;
        _startTime = EditorApplication.timeSinceStartup;
        _onCompleted = onCompleted;
        EditorUtility.DisplayProgressBar(EditorLocalize.Get(2002), EditorLocalize.Get(2003), 0.05f);
        _addRequest = Client.Add(PackageName);
        EditorApplication.update += Progress;
    }

    private static void Progress()
    {
        if (_addRequest == null)
        {
            Complete(false, EditorLocalize.Get(2004));
            return;
        }

        double elapsed = EditorApplication.timeSinceStartup - _startTime;
        float progress = Mathf.Clamp01(0.1f + (float)(elapsed / 8.0f) * 0.8f);
        progress = Mathf.Min(progress, 0.9f);
        EditorUtility.DisplayProgressBar(EditorLocalize.Get(2002), EditorLocalize.Get(2003), progress);
        if (!_addRequest.IsCompleted)
            return;
        try
        {
            EditorUtility.DisplayProgressBar(EditorLocalize.Get(2002), EditorLocalize.Get(2005), 1f);
            if (_addRequest.Status == StatusCode.Success)
            {
                string packageId = _addRequest.Result != null
                    ? _addRequest.Result.packageId
                    : PackageName;
                Complete(true, EditorLocalize.Get(2006) + packageId);
            }
            else
            {
                string error = _addRequest.Error != null
                    ? _addRequest.Error.message
                    : EditorLocalize.Get(2007);
                Complete(false, EditorLocalize.Get(2008) + error);
            }
        }
        catch (Exception e)
        {
            Complete(false, EditorLocalize.Get(2009) + e.Message);
        }
    }

    private static void Complete(bool success, string message)
    {
        var callback = _onCompleted;
        EditorApplication.update -= Progress;
        EditorUtility.ClearProgressBar();
        _addRequest = null;
        _onCompleted = null;
        _isInstalling = false;
        callback?.Invoke(success, message);
    }
}
#endif