#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using YachtDice.Modifiers.Definition;

namespace YachtDice.Modifiers.Editor
{
    public static class ModifierDefinitionValidator
    {
        [MenuItem("YachtDice/Validate All Modifier Definitions")]
        public static void ValidateAll()
        {
            string[] guids = AssetDatabase.FindAssets("t:ModifierDefinitionSO");

            if (guids.Length == 0)
            {
                Debug.Log("[ModifierValidator] No ModifierDefinitionSO assets found.");
                return;
            }

            int errorCount = 0;
            int warnCount = 0;
            var usedIds = new Dictionary<string, string>(); // id -> asset path

            for (int i = 0; i < guids.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(guids[i]);
                var def = AssetDatabase.LoadAssetAtPath<ModifierDefinition>(path);

                if (def == null)
                {
                    Debug.LogError($"[ModifierValidator] Failed to load asset at {path}");
                    errorCount++;
                    continue;
                }

                // ── Id checks ────────────────────────────────────────

                if (string.IsNullOrWhiteSpace(def.Id))
                {
                    Debug.LogError($"[ModifierValidator] {path}: Id is empty.", def);
                    errorCount++;
                }
                else if (usedIds.TryGetValue(def.Id, out string existingPath))
                {
                    Debug.LogError($"[ModifierValidator] {path}: Duplicate Id '{def.Id}' (also used by {existingPath}).", def);
                    errorCount++;
                }
                else
                {
                    usedIds[def.Id] = path;
                }

                // ── Economy checks ───────────────────────────────────

                if (def.ShopPrice < 0)
                {
                    Debug.LogError($"[ModifierValidator] {path}: ShopPrice is negative ({def.ShopPrice}).", def);
                    errorCount++;
                }

                if (def.SellPrice < 0)
                {
                    Debug.LogError($"[ModifierValidator] {path}: SellPrice is negative ({def.SellPrice}).", def);
                    errorCount++;
                }

                if (def.SellPrice > def.ShopPrice && def.ShopPrice > 0)
                {
                    Debug.LogWarning($"[ModifierValidator] {path}: SellPrice ({def.SellPrice}) > ShopPrice ({def.ShopPrice}). Infinite money exploit?", def);
                    warnCount++;
                }

                // ── Durability checks ────────────────────────────────

                if (def.HasLimitedUses && def.MaxUses <= 0)
                {
                    Debug.LogError($"[ModifierValidator] {path}: HasLimitedUses is true but MaxUses is {def.MaxUses}.", def);
                    errorCount++;
                }

                if (!def.HasLimitedUses && def.MaxUses > 0)
                {
                    Debug.LogWarning($"[ModifierValidator] {path}: HasLimitedUses is false but MaxUses is {def.MaxUses}. Ignored at runtime.", def);
                    warnCount++;
                }

                if (def.MaxStacks < 1)
                {
                    Debug.LogError($"[ModifierValidator] {path}: MaxStacks must be >= 1 (is {def.MaxStacks}).", def);
                    errorCount++;
                }

                // ── Behavior checks ──────────────────────────────────

                if (def.Behaviors == null || def.Behaviors.Count == 0)
                {
                    Debug.LogWarning($"[ModifierValidator] {path}: No behaviors assigned. Modifier will do nothing.", def);
                    warnCount++;
                    continue;
                }

                for (int b = 0; b < def.Behaviors.Count; b++)
                {
                    var behavior = def.Behaviors[b];

                    if (behavior == null)
                    {
                        Debug.LogError($"[ModifierValidator] {path}: Behavior slot [{b}] is null.", def);
                        errorCount++;
                        continue;
                    }

                    // Check for null conditions
                    if (behavior.Conditions != null)
                    {
                        for (int c = 0; c < behavior.Conditions.Count; c++)
                        {
                            if (behavior.Conditions[c] == null)
                            {
                                Debug.LogWarning($"[ModifierValidator] {path}: Behavior '{behavior.name}' has null condition at slot [{c}].", behavior);
                                warnCount++;
                            }
                        }
                    }

                    // Check for null or empty effects
                    if (behavior.Effects == null || behavior.Effects.Count == 0)
                    {
                        Debug.LogWarning($"[ModifierValidator] {path}: Behavior '{behavior.name}' has no effects.", behavior);
                        warnCount++;
                    }
                    else
                    {
                        for (int e = 0; e < behavior.Effects.Count; e++)
                        {
                            if (behavior.Effects[e] == null)
                            {
                                Debug.LogError($"[ModifierValidator] {path}: Behavior '{behavior.name}' has null effect at slot [{e}].", behavior);
                                errorCount++;
                            }
                        }
                    }
                }

                // ── Display checks ───────────────────────────────────

                if (string.IsNullOrWhiteSpace(def.DisplayName))
                {
                    Debug.LogWarning($"[ModifierValidator] {path}: DisplayName is empty.", def);
                    warnCount++;
                }

                if (string.IsNullOrWhiteSpace(def.Description))
                {
                    Debug.LogWarning($"[ModifierValidator] {path}: Description is empty.", def);
                    warnCount++;
                }
            }

            string summary = $"[ModifierValidator] Validated {guids.Length} modifier(s): {errorCount} error(s), {warnCount} warning(s).";

            if (errorCount > 0)
                Debug.LogError(summary);
            else if (warnCount > 0)
                Debug.LogWarning(summary);
            else
                Debug.Log(summary);
        }

        [MenuItem("YachtDice/Validate Modifier Catalog")]
        public static void ValidateCatalog()
        {
            string[] guids = AssetDatabase.FindAssets("t:ModifierCatalogSO");

            if (guids.Length == 0)
            {
                Debug.LogWarning("[ModifierValidator] No ModifierCatalogSO asset found. Create one via Create > YachtDice/Modifiers/Catalog.");
                return;
            }

            for (int i = 0; i < guids.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(guids[i]);
                var catalog = AssetDatabase.LoadAssetAtPath<ModifierCatalog>(path);

                if (catalog == null)
                {
                    Debug.LogError($"[ModifierValidator] Failed to load catalog at {path}");
                    continue;
                }

                if (catalog.All == null || catalog.All.Count == 0)
                {
                    Debug.LogWarning($"[ModifierValidator] Catalog at {path} is empty.");
                    continue;
                }

                int nullCount = 0;
                var catalogIds = new HashSet<string>();

                for (int j = 0; j < catalog.All.Count; j++)
                {
                    if (catalog.All[j] == null)
                    {
                        nullCount++;
                        Debug.LogError($"[ModifierValidator] Catalog {path}: Null entry at index [{j}].", catalog);
                        continue;
                    }

                    string id = catalog.All[j].Id;
                    if (!catalogIds.Add(id))
                    {
                        Debug.LogError($"[ModifierValidator] Catalog {path}: Duplicate modifier Id '{id}' in catalog.", catalog);
                    }
                }

                Debug.Log($"[ModifierValidator] Catalog {path}: {catalog.All.Count} entries, {nullCount} null.");
            }
        }
    }
}
#endif
