#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using IStalk.Data;
using IStalk.EditorTools.MapGen;

namespace IStalk.Editor.MapGen
{
    public class RoomValidator : EditorWindow
    {
        private Vector2 _scrollPos;
        private List<ValidationResult> _results = new();

        [MenuItem("IStalk/Room Validator")]
        public static void ShowWindow()
        {
            GetWindow<RoomValidator>("Room Validator");
        }

        private void OnGUI()
        {
            EditorGUILayout.LabelField("Room Validator", EditorStyles.boldLabel);
            EditorGUILayout.Space();

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Validate All Rooms"))
                ValidateAll();
            if (GUILayout.Button("Validate Selected Prefab"))
                ValidateSelected();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();
            DrawResults();
        }

        private void ValidateAll()
        {
            _results.Clear();
            var rooms = Resources.LoadAll<RoomNode_SO>("Items/Rooms");

            foreach (var room in rooms)
                _results.AddRange(ValidateRoom(room));

            int errors = _results.Count(r => r.Severity == MessageType.Error);
            int warnings = _results.Count(r => r.Severity == MessageType.Warning);
            Debug.Log($"[RoomValidator] Validated {rooms.Length} rooms: {errors} errors, {warnings} warnings");
        }

        private void ValidateSelected()
        {
            _results.Clear();
            var selected = Selection.activeObject as RoomNode_SO;
            if (selected == null)
            {
                EditorUtility.DisplayDialog("Room Validator", "Select a RoomNode_SO asset first.", "OK");
                return;
            }
            _results.AddRange(ValidateRoom(selected));
        }

        private List<ValidationResult> ValidateRoom(RoomNode_SO room)
        {
            var results = new List<ValidationResult>();
            string ctx = room.roomId ?? room.name;

            if (string.IsNullOrEmpty(room.roomId))
                results.Add(new ValidationResult(ctx, "Room ID is empty", MessageType.Error));

            if (room.roomPrefab == null)
            {
                results.Add(new ValidationResult(ctx, "No prefab assigned", MessageType.Error));
                return results;
            }

            var connectors = room.roomPrefab.GetComponentsInChildren<ConnectorMarker>(true);
            var slots = room.roomPrefab.GetComponentsInChildren<SpawnSlot>(true);
            var bounds = room.roomPrefab.GetComponentInChildren<RoomBounds>(true);

            if (connectors.Length == 0)
                results.Add(new ValidationResult(ctx, "Prefab has no ConnectorMarker components", MessageType.Error));

            if (bounds == null)
                results.Add(new ValidationResult(ctx, "Prefab has no RoomBounds component", MessageType.Warning));
            else if (bounds.gridSize != room.gridSize)
                results.Add(new ValidationResult(ctx, $"RoomBounds gridSize ({bounds.gridSize}) != SO gridSize ({room.gridSize})", MessageType.Warning));

            var soConnections = room.openConnections;
            var prefabConnections = connectors.Select(c => c.connectionDirection).Distinct().ToList();
            foreach (var dir in soConnections)
            {
                if (!prefabConnections.Contains(dir))
                    results.Add(new ValidationResult(ctx, $"SO declares {dir} connection but prefab has no marker for it", MessageType.Error));
            }
            foreach (var dir in prefabConnections)
            {
                if (!soConnections.Contains(dir))
                    results.Add(new ValidationResult(ctx, $"Prefab has {dir} marker but SO doesn't declare it", MessageType.Warning));
            }

            int lootSlots = slots.Count(s => s.slotType == SpawnSlotType.LootItem);
            if (lootSlots != room.lootSpawnSlots)
                results.Add(new ValidationResult(ctx, $"Loot slots mismatch: prefab={lootSlots}, SO={room.lootSpawnSlots}", MessageType.Warning));

            if (results.Count == 0)
                results.Add(new ValidationResult(ctx, "PASS — all checks OK", MessageType.Info));

            return results;
        }

        private void DrawResults()
        {
            _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
            foreach (var result in _results)
            {
                EditorGUILayout.HelpBox($"[{result.RoomId}] {result.Message}", result.Severity);
            }
            EditorGUILayout.EndScrollView();
        }

        private struct ValidationResult
        {
            public string RoomId;
            public string Message;
            public MessageType Severity;

            public ValidationResult(string roomId, string message, MessageType severity)
            {
                RoomId = roomId;
                Message = message;
                Severity = severity;
            }
        }
    }
}
#endif
