#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System.Diagnostics;
using IStalk.Core;
using IStalk.Data;
using IStalk.Network;

namespace IStalk.Editor.MapGen
{
    public class MapGenTestWindow : EditorWindow
    {
        private int _seed;
        private int _testCount = 100;
        private string _lastResult;
        private Vector2 _scrollPos;

        [MenuItem("IStalk/Map Generation Tester")]
        public static void ShowWindow()
        {
            GetWindow<MapGenTestWindow>("Map Gen Tester");
        }

        private void OnGUI()
        {
            EditorGUILayout.LabelField("Map Generation Tester", EditorStyles.boldLabel);
            EditorGUILayout.Space();

            _seed = EditorGUILayout.IntField("Seed", _seed);
            if (GUILayout.Button("Randomize Seed"))
                _seed = Random.Range(int.MinValue, int.MaxValue);

            EditorGUILayout.Space();

            if (GUILayout.Button("Generate Single Map (Preview)"))
                GenerateSingle();

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Stress Test", EditorStyles.boldLabel);
            _testCount = EditorGUILayout.IntSlider("Iterations", _testCount, 10, 1000);

            if (GUILayout.Button($"Run {_testCount} Generations"))
                StressTest();

            if (!string.IsNullOrEmpty(_lastResult))
            {
                EditorGUILayout.Space();
                _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, GUILayout.Height(200));
                EditorGUILayout.TextArea(_lastResult, GUILayout.ExpandHeight(true));
                EditorGUILayout.EndScrollView();
            }
        }

        private void GenerateSingle()
        {
            var rules = FindGlobalRules();
            if (rules == null) return;
            rules.Initialize();

            GameStartData.MapSeed = _seed;

            var go = new GameObject("_TestMapGenerator");
            var gen = go.AddComponent<MapGenerator>();

            var sw = Stopwatch.StartNew();
            gen.Generate();
            sw.Stop();

            _lastResult = $"Seed: {_seed}\n" +
                          $"Rooms placed: {gen.PlacedRooms.Count}\n" +
                          $"Altars: {gen.AltarPositions.Count}\n" +
                          $"Loot slots: {gen.LootSlotPositions.Count}\n" +
                          $"Time: {sw.ElapsedMilliseconds}ms\n" +
                          $"Bounds: {gen.GetMapBounds()}\n\n" +
                          "Room breakdown:\n";

            var categoryCounts = new System.Collections.Generic.Dictionary<RoomCategory, int>();
            foreach (var room in gen.PlacedRooms)
            {
                if (!categoryCounts.ContainsKey(room.Data.category))
                    categoryCounts[room.Data.category] = 0;
                categoryCounts[room.Data.category]++;
            }
            foreach (var kvp in categoryCounts)
                _lastResult += $"  {kvp.Key}: {kvp.Value}\n";

            DestroyImmediate(go);
            Repaint();
        }

        private void StressTest()
        {
            var rules = FindGlobalRules();
            if (rules == null) return;
            rules.Initialize();

            var go = new GameObject("_TestMapGenerator");
            var gen = go.AddComponent<MapGenerator>();

            int failures = 0;
            long totalMs = 0;
            int minRooms = int.MaxValue;
            int maxRooms = 0;

            for (int i = 0; i < _testCount; i++)
            {
                GameStartData.MapSeed = _seed + i;
                var sw = Stopwatch.StartNew();

                try
                {
                    gen.Generate();
                    sw.Stop();
                    totalMs += sw.ElapsedMilliseconds;

                    int count = gen.PlacedRooms.Count;
                    if (count < rules.minRoomsPerMap) failures++;
                    minRooms = Mathf.Min(minRooms, count);
                    maxRooms = Mathf.Max(maxRooms, count);
                }
                catch (System.Exception ex)
                {
                    failures++;
                    UnityEngine.Debug.LogError($"Seed {GameStartData.MapSeed} failed: {ex.Message}");
                }
            }

            DestroyImmediate(go);

            _lastResult = $"Stress Test Results ({_testCount} iterations)\n" +
                          $"─────────────────────────────\n" +
                          $"Failures: {failures}/{_testCount}\n" +
                          $"Avg time: {totalMs / _testCount}ms\n" +
                          $"Max time: {totalMs}ms total\n" +
                          $"Room range: {minRooms}–{maxRooms}\n" +
                          $"Success rate: {((_testCount - failures) * 100f / _testCount):F1}%";

            Repaint();
        }

        private GlobalRules_SO FindGlobalRules()
        {
            string[] guids = AssetDatabase.FindAssets("t:GlobalRules_SO");
            if (guids.Length == 0)
            {
                EditorUtility.DisplayDialog("Error", "No GlobalRules_SO asset found. Create one via Assets > Create > IStalk > Global Rules.", "OK");
                return null;
            }
            string path = AssetDatabase.GUIDToAssetPath(guids[0]);
            return AssetDatabase.LoadAssetAtPath<GlobalRules_SO>(path);
        }
    }
}
#endif
