using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace Davanci.Nexus.Editor
{
    // Live view of DavanciNexus.* events fired during play mode, with test-fire buttons.
    public class NexusEventMonitor : EditorWindow
    {
        ScrollView _list;
        Label _status;
        Label _saveInfo;
        int _shownCount = -1;
        double _nextSizePoll;

        static readonly Color Bg     = new Color(0.10f, 0.11f, 0.14f);
        static readonly Color Panel  = new Color(0.13f, 0.14f, 0.18f);
        static readonly Color Accent = new Color(1f, 0.42f, 0.42f);
        static readonly Color Muted  = new Color(0.62f, 0.64f, 0.70f);
        static readonly Color OkGreen= new Color(0.40f, 0.80f, 0.45f);

        [MenuItem("Davanci Nexus/Nexus Event Monitor")]
        public static void Open()
        {
            var w = GetWindow<NexusEventMonitor>();
            w.titleContent = new GUIContent("Nexus Events",
                AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/DavanciNexus/Art/logo-icon-cube.png"));
            w.minSize = new Vector2(420, 360);
            w.Show();
        }

        void OnEnable()
        {
            BuildUI();
            EditorApplication.update += Poll;
        }

        void OnDisable()
        {
            EditorApplication.update -= Poll;
        }

        void BuildUI()
        {
            var root = rootVisualElement;
            root.Clear();
            root.style.backgroundColor = Bg;

            var header = new VisualElement();
            header.style.paddingLeft = 14; header.style.paddingRight = 14;
            header.style.paddingTop = 12; header.style.paddingBottom = 8;

            var title = new Label("Nexus Event Monitor");
            title.style.fontSize = 16;
            title.style.unityFontStyleAndWeight = FontStyle.Bold;
            title.style.color = Accent;
            header.Add(title);

            _status = new Label();
            _status.style.fontSize = 10;
            _status.style.color = Muted;
            _status.style.marginTop = 2;
            header.Add(_status);

            _saveInfo = new Label();
            _saveInfo.style.fontSize = 10;
            _saveInfo.style.color = Muted;
            _saveInfo.style.marginTop = 2;
            header.Add(_saveInfo);
            root.Add(header);

            var tools = new VisualElement();
            tools.style.flexDirection = FlexDirection.Row;
            tools.style.flexWrap = Wrap.Wrap;
            tools.style.paddingLeft = 14; tools.style.paddingRight = 14;
            tools.Add(TestBtn("tutorial_step", () => DavanciNexus.TutorialStep(0, "tap_to_start")));
            tools.Add(TestBtn("tutorial_step_done", () => DavanciNexus.TutorialStepDone(0)));
            tools.Add(TestBtn("tutorial_complete", () => DavanciNexus.TutorialComplete()));
            tools.Add(TestBtn("progress_start", () => DavanciNexus.Progress.Start(NextIndex())));
            tools.Add(TestBtn("progress_fail", () => DavanciNexus.Progress.Fail(NextIndex(), "test")));
            tools.Add(TestBtn("progress_complete", () => DavanciNexus.Progress.Complete(NextIndex())));
            tools.Add(TestBtn("currency_earned", () => DavanciNexus.CurrencyEarned("coins", 1500, "gameplay")));
            tools.Add(TestBtn("currency_spent", () => DavanciNexus.CurrencySpent("coins", 800, "upgrade", "farm")));
            tools.Add(TestBtn("acquired", () => DavanciNexus.Acquired("business", "farm")));
            tools.Add(TestBtn("upgraded", () => DavanciNexus.Upgraded("business", "farm", 5)));
            tools.Add(TestBtn("offline_earnings", () => DavanciNexus.OfflineEarningsCollected(12000, 3600)));
            tools.Add(TestBtn("reset", () => DavanciNexus.Reset("prestige", 2, 50)));
            tools.Add(TestBtn("checkpoint", () => DavanciNexus.Checkpoint("world2_after_first_prestige")));
            tools.Add(TestBtn("ad_watched", () => DavanciNexus.AdWatched("rewarded")));
            tools.Add(TestBtn("custom", () => DavanciNexus.Custom("debug_ping", ("from", "monitor"))));
            tools.Add(TestBtn("Clear", () => { DavanciNexus.Clear(); _shownCount = -1; Refresh(); }));
            tools.Add(TestBtn("Reset event guards", ResetGuards, needsPlayMode: false));
            root.Add(tools);

            _list = new ScrollView();
            _list.style.flexGrow = 1;
            _list.style.marginTop = 8;
            _list.style.paddingLeft = 14; _list.style.paddingRight = 14;
            _list.style.paddingBottom = 12;
            root.Add(_list);

            Refresh();
            UpdateSaveSize();
        }

        // Size of the cloud-save blob on disk (the GZip'd envelope that gets pushed to
        // iCloud), shown against the ~1 MB Key-Value Store budget.
        void UpdateSaveSize()
        {
            if (_saveInfo == null) return;
            int bytes = 0;
            try { bytes = new FileLocalStore().Read()?.Length ?? 0; } catch { }

            if (bytes == 0)
            {
                _saveInfo.text = "Cloud save: nothing written yet";
                _saveInfo.style.color = Muted;
                return;
            }

            float pct = bytes / (1024f * 1024f) * 100f;
            _saveInfo.text = $"Cloud save: {bytes / 1024f:0.0} KB ({pct:0.0}% of 1 MB iCloud limit)";
            _saveInfo.style.color = pct > 90f ? new Color(0.90f, 0.65f, 0.30f) : OkGreen;
        }

        // The level after the highest completed one (NexusEventGuards' key), so the progress
        // buttons are never replays.
        static int NextIndex() => PlayerPrefs.GetInt("nexus.evt.p.level.max", 0) + 1;

        void ResetGuards()
        {
            DavanciNexus.ResetEventGuards();
            _status.text = "Event guards reset: tutorial and progress events will send again.";
            _status.style.color = OkGreen;
        }

        Button TestBtn(string label, System.Action action, bool needsPlayMode = true)
        {
            var b = new Button(() =>
            {
                if (needsPlayMode && !Application.isPlaying)
                {
                    _status.text = "Enter Play Mode to fire test events.";
                    _status.style.color = new Color(0.90f, 0.65f, 0.30f);
                    return;
                }
                action();
            }) { text = label };
            b.style.height = 24;
            b.style.marginRight = 6;
            b.style.marginTop = 4;
            b.style.fontSize = 10;
            b.style.color = Color.white;
            b.style.backgroundColor = Panel;
            b.style.borderTopLeftRadius = 5; b.style.borderTopRightRadius = 5;
            b.style.borderBottomLeftRadius = 5; b.style.borderBottomRightRadius = 5;
            return b;
        }

        void Poll()
        {
            if (DavanciNexus.Recent.Count != _shownCount)
                Refresh();

            if (EditorApplication.timeSinceStartup >= _nextSizePoll)
            {
                _nextSizePoll = EditorApplication.timeSinceStartup + 0.5;
                UpdateSaveSize();
            }
        }

        void Refresh()
        {
            if (_list == null) return;
            _shownCount = DavanciNexus.Recent.Count;

            string mode = Application.isPlaying ? "Play Mode (live)" : "Not playing (events appear when running)";
            _status.text = $"{mode} · {_shownCount} event(s) captured";
            _status.style.color = Application.isPlaying ? OkGreen : Muted;

            _list.Clear();
            if (_shownCount == 0)
            {
                var empty = new Label("No events yet. Fire one from your game or the buttons above.");
                empty.style.color = Muted;
                empty.style.fontSize = 11;
                _list.Add(empty);
                return;
            }

            for (int i = DavanciNexus.Recent.Count - 1; i >= 0; i--)
            {
                var ev = DavanciNexus.Recent[i];
                var card = new VisualElement();
                card.style.backgroundColor = Panel;
                card.style.paddingLeft = 10; card.style.paddingRight = 10;
                card.style.paddingTop = 6; card.style.paddingBottom = 6;
                card.style.marginBottom = 4;
                card.style.borderTopLeftRadius = 6; card.style.borderTopRightRadius = 6;
                card.style.borderBottomLeftRadius = 6; card.style.borderBottomRightRadius = 6;

                var topRow = new VisualElement();
                topRow.style.flexDirection = FlexDirection.Row;
                topRow.style.justifyContent = Justify.SpaceBetween;

                var name = new Label(ev.Name);
                name.style.unityFontStyleAndWeight = FontStyle.Bold;
                name.style.fontSize = 12;
                name.style.color = ev.Skipped ? Muted : Color.white;
                topRow.Add(name);

                var prov = new Label(ev.Providers);
                prov.style.fontSize = 10;
                prov.style.color = ev.Skipped ? Muted : OkGreen;
                topRow.Add(prov);
                card.Add(topRow);

                if (!string.IsNullOrEmpty(ev.Parameters))
                {
                    var p = new Label(ev.Parameters);
                    p.style.fontSize = 10;
                    p.style.color = Muted;
                    p.style.whiteSpace = WhiteSpace.Normal;
                    card.Add(p);
                }

                var time = new Label(ev.Stamp.ToString("HH:mm:ss"));
                time.style.fontSize = 9;
                time.style.color = Muted;
                card.Add(time);

                _list.Add(card);
            }
        }
    }
}
