using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;

namespace VibeCopilot.Editor
{
    // AUTO-UPDATER. La incarcarea plugin-ului verifica pe server daca exista o versiune mai
    // noua. Daca da, fereastra arata un banner "Update available" cu un buton care descarca
    // .unitypackage-ul nou si il importa automat (un click) — userul NU mai reinstaleaza manual.
    // Codul, prompturile si biblioteca se actualizeaza oricum de pe server, fara reinstalare;
    // asta acopera doar cazul cand se schimba chiar codul C# al plugin-ului (interfata etc.).
    [InitializeOnLoad]
    public static class VibeUpdater
    {
        // >>> CRESTE la fiecare release nou de plugin, impreuna cu `build` din api/version.js <<<
        public const int PluginBuild = 5;
        public const string PluginVersion = "1.5";

        private const string VersionUrl = "https://server-five-ebon-79.vercel.app/api/version";
        private const string LastCheckKey = "VibeCopilot.Update.LastCheck";
        private const string CacheBuildKey = "VibeCopilot.Update.Build";
        private const string CacheVerKey = "VibeCopilot.Update.Ver";
        private const string CacheUrlKey = "VibeCopilot.Update.Url";
        private const string CacheNotesKey = "VibeCopilot.Update.Notes";
        private const double CheckEverySeconds = 3600; // verificam la retea cel mult o data/ora

        public static int LatestBuild { get; private set; }
        public static string LatestVersion { get; private set; }
        public static string DownloadUrl { get; private set; }
        public static string Notes { get; private set; }
        public static bool UpdateAvailable
        {
            get { return LatestBuild > PluginBuild && !string.IsNullOrEmpty(DownloadUrl); }
        }
        public static event Action OnChecked;   // fereastra se aboneaza ca sa-si redeseneze bannerul

        static VibeUpdater()
        {
            // Aratam imediat rezultatul din cache (fara sa asteptam reteaua), apoi reimprospatam
            // in fundal daca a trecut destul timp de la ultima verificare.
            LatestBuild = EditorPrefs.GetInt(CacheBuildKey, 0);
            LatestVersion = EditorPrefs.GetString(CacheVerKey, "");
            DownloadUrl = EditorPrefs.GetString(CacheUrlKey, "");
            Notes = EditorPrefs.GetString(CacheNotesKey, "");
            EditorApplication.delayCall += MaybeCheck;
        }

        [Serializable] private class VersionResp { public int build; public string version; public string url; public string notes; }

        private static void MaybeCheck()
        {
            double last;
            double.TryParse(EditorPrefs.GetString(LastCheckKey, "0"), out last);
            double realNow = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
            if (realNow - last < CheckEverySeconds && LatestBuild > 0) { NotifyIfNeeded(); return; }
            Check();
        }

        public static void Check()
        {
            UnityWebRequest req = UnityWebRequest.Get(VersionUrl);
            req.SetRequestHeader("User-Agent", "vibecopilot-plugin/" + PluginBuild);
            UnityWebRequestAsyncOperation op = req.SendWebRequest();
            op.completed += _ =>
            {
                try
                {
                    if (req.result != UnityWebRequest.Result.Success || req.responseCode != 200)
                    { req.Dispose(); return; }
                    VersionResp v = JsonUtility.FromJson<VersionResp>(req.downloadHandler.text);
                    req.Dispose();
                    if (v == null || v.build <= 0) return;
                    LatestBuild = v.build; LatestVersion = v.version; DownloadUrl = v.url; Notes = v.notes;
                    EditorPrefs.SetInt(CacheBuildKey, v.build);
                    EditorPrefs.SetString(CacheVerKey, v.version ?? "");
                    EditorPrefs.SetString(CacheUrlKey, v.url ?? "");
                    EditorPrefs.SetString(CacheNotesKey, v.notes ?? "");
                    double realNow = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
                    EditorPrefs.SetString(LastCheckKey, realNow.ToString());
                    NotifyIfNeeded();
                }
                catch { try { req.Dispose(); } catch { } }
            };
        }

        private static void NotifyIfNeeded()
        {
            Action h = OnChecked;
            if (h != null) h();
        }

        private static bool _busy;
        // Descarca pachetul nou si il importa (importul recompileaza -> pluginul se inlocuieste).
        public static void DownloadAndImport(Action<bool, string> done)
        {
            if (_busy) { if (done != null) done(false, "busy"); return; }
            if (string.IsNullOrEmpty(DownloadUrl)) { if (done != null) done(false, "no url"); return; }
            _busy = true;
            UnityWebRequest req = UnityWebRequest.Get(DownloadUrl);
            req.SetRequestHeader("User-Agent", "vibecopilot-plugin/" + PluginBuild);
            UnityWebRequestAsyncOperation op = req.SendWebRequest();
            op.completed += _ =>
            {
                try
                {
                    if (req.result != UnityWebRequest.Result.Success || req.downloadHandler.data == null || req.downloadHandler.data.Length < 100)
                    { _busy = false; req.Dispose(); if (done != null) done(false, "download failed"); return; }
                    string tmp = FileUtil.GetUniqueTempPathInProject() + ".unitypackage";
                    System.IO.File.WriteAllBytes(tmp, req.downloadHandler.data);
                    req.Dispose();
                    _busy = false;
                    if (done != null) done(true, "");
                    // interactive=false => import silentios; declanseaza recompilarea plugin-ului.
                    AssetDatabase.ImportPackage(tmp, false);
                }
                catch (Exception e) { _busy = false; try { req.Dispose(); } catch { } if (done != null) done(false, e.Message); }
            };
        }
    }
}
