using System;
using System.IO;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;

namespace MajacloudSdk.Editor
{
    /// <summary>Shared IMGUI for the Setup window and the Project Settings page.</summary>
    internal sealed class MajacloudSetupGui
    {
        private readonly MajacloudConnectionTester _tester = new MajacloudConnectionTester();
        private string _baseUrl = "http://localhost/MAJACLOUD";
        private string _projectId = string.Empty;
        private string _clientKey = string.Empty;
        private bool _revealKey;
        private string _status;
        private MessageType _statusType = MessageType.None;
        private bool _loaded;

        public static MajacloudSettings LoadSettings() => AssetDatabase.LoadAssetAtPath<MajacloudSettings>(MajacloudEditorPaths.SettingsAssetPath);

        public void OnEnable()
        {
            if (_loaded) return;
            _loaded = true;
            var settings = LoadSettings();
            if (settings == null) return;
            _baseUrl = string.IsNullOrEmpty(settings.BaseUrl) ? _baseUrl : settings.BaseUrl;
            _projectId = settings.ProjectId;
            _clientKey = settings.ClientKey;
        }

        public void OnDisable() => _tester.Abort();

        public void Draw()
        {
            OnEnable();
            var settings = LoadSettings();
            EditorGUILayout.Space(6);
            EditorGUILayout.LabelField("Connection", EditorStyles.boldLabel);
            EditorGUILayout.HelpBox("Copy the Project ID and Client Key from your MAJACLOUD dashboard (Project ▸ API keys). The Client Key is public and safe to ship. Never put the server Secret Key in Unity.", MessageType.Info);
            _baseUrl = EditorGUILayout.TextField(new GUIContent("Base URL", "e.g. https://cloud.yourstudio.com or http://localhost/MAJACLOUD"), _baseUrl ?? string.Empty);
            _projectId = EditorGUILayout.TextField(new GUIContent("Project ID"), _projectId ?? string.Empty);
            using (new EditorGUILayout.HorizontalScope())
            {
                _clientKey = _revealKey ? EditorGUILayout.TextField(new GUIContent("Client Key"), _clientKey ?? string.Empty) : EditorGUILayout.PasswordField(new GUIContent("Client Key"), _clientKey ?? string.Empty);
                if (GUILayout.Button(_revealKey ? "Hide" : "Show", GUILayout.Width(50))) _revealKey = !_revealKey;
            }

            var normalizedUrl = NormalizeBaseUrl(_baseUrl);
            if (Uri.TryCreate(normalizedUrl, UriKind.Absolute, out var uri) && uri.Scheme == "http" && !uri.IsLoopback && uri.Host != "localhost")
            {
                EditorGUILayout.HelpBox("Plain http:// only works for localhost. Use https:// for a real server.", MessageType.Warning);
            }
            if (settings != null && settings.HasLegacySecretKey) EditorGUILayout.HelpBox("The settings asset still holds a server Secret Key from SDK 1.x. Saving removes it.", MessageType.Warning);
            if (!string.IsNullOrEmpty(_clientKey) && !_clientKey.StartsWith("pk_")) EditorGUILayout.HelpBox("That doesn't look like a Client Key (they start with pk_live_). Secret keys (sk_live_) must stay on your server.", MessageType.Warning);

            EditorGUILayout.Space(4);
            using (new EditorGUILayout.HorizontalScope())
            {
                using (new EditorGUI.DisabledScope(_tester.IsRunning || string.IsNullOrEmpty(_projectId) || string.IsNullOrEmpty(_clientKey)))
                {
                    if (GUILayout.Button(_tester.IsRunning ? "Testing…" : "Test connection", GUILayout.Height(28))) TestConnection();
                }
                if (GUILayout.Button("Save", GUILayout.Height(28), GUILayout.Width(90))) SaveSettings(null);
            }
            if (!string.IsNullOrEmpty(_status)) EditorGUILayout.HelpBox(_status, _statusType);

            EditorGUILayout.Space(10);
            EditorGUILayout.LabelField("Project", EditorStyles.boldLabel);
            if (settings == null)
            {
                EditorGUILayout.HelpBox("No settings asset yet. Test the connection or press Save to create " + MajacloudEditorPaths.SettingsAssetPath + ".", MessageType.None);
            }
            else
            {
                using (new EditorGUI.DisabledScope(true))
                {
                    EditorGUILayout.TextField("Name", settings.ProjectName);
                    EditorGUILayout.TextField("Plan", settings.Plan);
                    EditorGUILayout.TextField("Config public key", settings.HasConfigPublicKey ? "stored (" + settings.ConfigKeyId + ")" : "not stored – test the connection");
                }
                if (GUILayout.Button("Select settings asset")) EditorGUIUtility.PingObject(settings);
            }

            EditorGUILayout.Space(10);
            EditorGUILayout.LabelField("Demo scenes", EditorStyles.boldLabel);
            EditorGUILayout.HelpBox("Open the Home scene and press Play. It links to an All-in-One demo, one scene per service, a Test Data playground and a short Docs scene.", MessageType.None);
            using (new EditorGUILayout.HorizontalScope())
            {
                if (GUILayout.Button("Open demo (Home)", GUILayout.Height(26))) OpenStarterScene();
                if (GUILayout.Button("Rebuild demo scenes", GUILayout.Height(26))) StarterSampleBuilder.Build(true);
            }
            using (new EditorGUILayout.HorizontalScope())
            {
                if (GUILayout.Button("Export .unitypackage", GUILayout.Height(26))) MajacloudPackageExporter.ExportInteractive();
                if (GUILayout.Button("Documentation", GUILayout.Height(26))) Application.OpenURL(MajacloudEditorPaths.DocsUrl);
            }
        }

        private void TestConnection()
        {
            var url = NormalizeBaseUrl(_baseUrl);
            _status = "Contacting " + url + " …";
            _statusType = MessageType.None;
            _tester.Start(url, _projectId.Trim(), _clientKey.Trim(), result =>
            {
                if (!result.Ok)
                {
                    _status = "Connection failed: " + result.Error.Message;
                    _statusType = MessageType.Error;
                    Debug.LogWarning("[Majacloud] " + _status);
                    return;
                }
                var info = result.Value;
                SaveSettings(info);
                _status = "Connected to \"" + info.Name + "\" (" + (info.PlanLabel ?? info.Plan) + " plan). Settings saved" + (string.IsNullOrEmpty(info.ConfigPublicKeyXml) ? "; the server has no Remote Config signing key yet." : " with the Remote Config public key.");
                _statusType = MessageType.Info;
                Debug.Log("[Majacloud] " + _status);
            });
        }

        private void SaveSettings(MajacloudProjectInfo info)
        {
            var settings = LoadSettings();
            if (settings == null)
            {
                MajacloudEditorPaths.EnsureFolder("Assets/Resources");
                settings = ScriptableObject.CreateInstance<MajacloudSettings>();
                AssetDatabase.CreateAsset(settings, MajacloudEditorPaths.SettingsAssetPath);
            }
            settings.Configure(NormalizeBaseUrl(_baseUrl), _projectId.Trim(), _clientKey.Trim());
            if (info != null) settings.SetProjectInfo(info.Name, info.PlanLabel ?? info.Plan, info.ConfigPublicKeyXml, info.ConfigSigningKeyId);
            EditorUtility.SetDirty(settings);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            if (info == null)
            {
                _status = "Settings saved to " + MajacloudEditorPaths.SettingsAssetPath + ".";
                _statusType = MessageType.Info;
            }
        }

        public static string NormalizeBaseUrl(string value)
        {
            var url = (value ?? string.Empty).Trim().TrimEnd('/');
            if (url.EndsWith("/v1")) url = url.Substring(0, url.Length - 3);
            return url;
        }

        public static void OpenStarterScene()
        {
            var path = MajacloudEditorPaths.HomeScenePath;
            if (!File.Exists(path))
            {
                if (EditorUtility.DisplayDialog("Majacloud", "The demo scenes have not been generated in this project yet. Build them now?", "Build", "Cancel")) StarterSampleBuilder.Build(true);
                return;
            }
            if (StarterSampleBuilder.ScenesNeedRebuildForThisUnity())
            {
                if (EditorUtility.DisplayDialog("Majacloud", "The demo scenes were saved with a newer Unity. Rebuild them for Unity " + Application.unityVersion + "? It takes a few seconds.", "Rebuild", "Open as is"))
                {
                    StarterSampleBuilder.Build(true, false);
                    return;
                }
            }
            if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) EditorSceneManager.OpenScene(path);
        }
    }
}
