using System;
using MajacloudSdk.Internal;
using UnityEditor;
using UnityEngine.Networking;

namespace MajacloudSdk.Editor
{
    /// <summary>GET /v1/project from the editor (no play mode), polled through EditorApplication.update.</summary>
    internal sealed class MajacloudConnectionTester
    {
        private UnityWebRequest _request;
        private Action<MajacloudResult<MajacloudProjectInfo>> _callback;
        private double _startedAt;

        public bool IsRunning => _request != null;

        public void Start(string baseUrl, string projectId, string clientKey, Action<MajacloudResult<MajacloudProjectInfo>> callback)
        {
            Abort();
            _callback = callback;
            _request = UnityWebRequest.Get(baseUrl.TrimEnd('/') + MajacloudEndpoints.Project);
            _request.SetRequestHeader("Accept", "application/json");
            _request.SetRequestHeader("X-Project-ID", projectId);
            _request.SetRequestHeader("X-Client-Key", clientKey);
            _request.SetRequestHeader("X-Majacloud-SDK", "unity-editor/" + Majacloud.Version);
            _request.timeout = 10;
            _startedAt = EditorApplication.timeSinceStartup;
            _request.SendWebRequest();
            EditorApplication.update += Poll;
        }

        public void Abort()
        {
            EditorApplication.update -= Poll;
            if (_request != null)
            {
                try { _request.Abort(); _request.Dispose(); } catch (Exception) { }
            }
            _request = null;
        }

        private void Poll()
        {
            if (_request == null)
            {
                EditorApplication.update -= Poll;
                return;
            }
            if (!_request.isDone && EditorApplication.timeSinceStartup - _startedAt < 15) return;
            EditorApplication.update -= Poll;
            var request = _request;
            _request = null;
            MajacloudResult<MajacloudProjectInfo> result;
            var text = request.downloadHandler != null ? request.downloadHandler.text : string.Empty;
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.DataProcessingError || !request.isDone)
            {
                result = MajacloudResult<MajacloudProjectInfo>.Fail(MajacloudErrorCode.Network, "Could not reach the server: " + (request.error ?? "timeout"));
            }
            else if (JsonNode.TryParse(text, out var json, out _) && json.IsObject && json.GetBool("ok"))
            {
                result = MajacloudResult<MajacloudProjectInfo>.Success(MajacloudProjectInfo.FromJson(json.GetObject("project")));
            }
            else
            {
                var message = JsonNode.TryParse(text, out var err, out _) ? err["error"].GetString("message") : null;
                result = MajacloudResult<MajacloudProjectInfo>.Fail(MajacloudErrorCode.Unauthorized, (message ?? ("HTTP " + request.responseCode)) + (request.responseCode == 401 ? " Check the Project ID and Client Key." : string.Empty));
            }
            request.Dispose();
            var callback = _callback;
            _callback = null;
            callback?.Invoke(result);
        }
    }
}
