using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// Centralized system for managing character prefabs and names.
/// This singleton can be used across the entire game to load character prefabs
/// and translate between prefab names and character display names.
/// </summary>
public class CharacterPrefabManager : MonoBehaviour
{
    #region Singleton
    private static CharacterPrefabManager _instance;
    public static CharacterPrefabManager Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject go = new GameObject("CharacterPrefabManager");
                _instance = go.AddComponent<CharacterPrefabManager>();
                DontDestroyOnLoad(go);
                _instance.Initialize();
            }
            return _instance;
        }
    }
    #endregion

    // Character display names (uppercase for UI display)
    public enum CharacterName
    {
        WINDHAM,
        AMIRA,
        BAHMAN,
        ZIGGY,
        AMON,
        IMANI,
        ZIGGY_NEW
    }

    // Dictionary mapping character names to prefab resource paths
    private Dictionary<CharacterName, string> playerPrefabPaths = new Dictionary<CharacterName, string>();
    private Dictionary<CharacterName, string> aiPrefabPaths = new Dictionary<CharacterName, string>();
    
    // Dictionary mapping GameObject clone names to character names
    private Dictionary<string, CharacterName> gameObjectToCharacterName = new Dictionary<string, CharacterName>();

    private void Initialize()
    {
        // Setup player prefab paths
        playerPrefabPaths[CharacterName.WINDHAM] = "Rabbit";
        playerPrefabPaths[CharacterName.AMIRA] = "Cheetah";
        playerPrefabPaths[CharacterName.BAHMAN] = "Eagle";
        playerPrefabPaths[CharacterName.ZIGGY] = "Cat";
        playerPrefabPaths[CharacterName.AMON] = "HM";
        playerPrefabPaths[CharacterName.IMANI] = "Hyena";

        // Setup AI prefab paths - NOW USES SAME UNIFIED PREFABS AS PLAYER
        // The modular architecture means we use ONE prefab per character
        // and configure behavior (player vs AI) at runtime via component enable/disable
        aiPrefabPaths[CharacterName.WINDHAM] = "Rabbit";  // No longer "Rabbit Enemy"
        aiPrefabPaths[CharacterName.AMIRA] = "Cheetah";   // No longer "Cheetah Enemy"
        aiPrefabPaths[CharacterName.BAHMAN] = "Eagle";    // No longer "Eagle Enemy"
        aiPrefabPaths[CharacterName.ZIGGY] = "Cat";       // No longer "Cat Enemy"
        aiPrefabPaths[CharacterName.AMON] = "HM";         // No longer "HM Enemy"
        aiPrefabPaths[CharacterName.IMANI] = "Hyena";     // No longer "Hyena Enemy"

        // Setup GameObject name mapping
        MapCloneNamesToCharacters();
    }

    private void MapCloneNamesToCharacters()
    {
        // Player prefabs
        gameObjectToCharacterName["Rabbit(Clone)"] = CharacterName.WINDHAM;
        // gameObjectToCharacterName["Rabbit 2(Clone)"] = CharacterName.WINDHAM;
        gameObjectToCharacterName["Cheetah(Clone)"] = CharacterName.AMIRA;
        // gameObjectToCharacterName["Cheetah 2(Clone)"] = CharacterName.AMIRA;
        gameObjectToCharacterName["Eagle(Clone)"] = CharacterName.BAHMAN;
        gameObjectToCharacterName["Cat(Clone)"] = CharacterName.ZIGGY;
        gameObjectToCharacterName["HM(Clone)"] = CharacterName.AMON;
        gameObjectToCharacterName["Hyena(Clone)"] = CharacterName.IMANI;

        // AI prefabs
        gameObjectToCharacterName["Rabbit Enemy(Clone)"] = CharacterName.WINDHAM;
        // gameObjectToCharacterName["Rabbit Enemy 2(Clone)"] = CharacterName.WINDHAM;
        gameObjectToCharacterName["Cheetah Enemy(Clone)"] = CharacterName.AMIRA;
        // gameObjectToCharacterName["Cheetah Enemy 2(Clone)"] = CharacterName.AMIRA;
        gameObjectToCharacterName["Eagle Enemy(Clone)"] = CharacterName.BAHMAN;
        gameObjectToCharacterName["Cat Enemy(Clone)"] = CharacterName.ZIGGY;
        gameObjectToCharacterName["HM Enemy(Clone)"] = CharacterName.AMON;
        gameObjectToCharacterName["Hyena Enemy(Clone)"] = CharacterName.IMANI;
    }

    /// <summary>
    /// Get the prefab for a character based on name and mode
    /// </summary>
    /// <param name="characterName">The character to load</param>
    /// <param name="isAI">Whether to load the AI version</param>
    /// <returns>The loaded prefab GameObject</returns>
    public GameObject GetCharacterPrefab(CharacterName characterName, bool isAI = false)
    {
        string prefabPath = isAI ? aiPrefabPaths[characterName] : playerPrefabPaths[characterName];
        GameObject prefab = Resources.Load<GameObject>(prefabPath);
        
        if (prefab == null)
        {
            Debug.LogError($"Failed to load character prefab: {characterName} (AI: {isAI})");
        }
        
        return prefab;
    }

    /// <summary>
    /// Get the prefab for a character based on string name and mode
    /// </summary>
    /// <param name="characterName">The string name of the character</param>
    /// <param name="isAI">Whether to load the AI version</param>
    /// <returns>The loaded prefab GameObject</returns>
    public GameObject GetCharacterPrefab(string characterName, bool isAI = false)
    {
        if (TryParseCharacterName(characterName, out CharacterName parsedName))
        {
            return GetCharacterPrefab(parsedName, isAI);
        }
        
        Debug.LogError($"Invalid character name: {characterName}");
        return null;
    }

    /// <summary>
    /// Try to parse a string character name (case insensitive) to a CharacterName enum
    /// </summary>
    public bool TryParseCharacterName(string nameString, out CharacterName characterName)
    {
        // Normalize input to uppercase and remove spaces
        string normalizedName = nameString.ToUpper().Replace(" ", "_");
    
        
        // Try to parse as enum
        if (System.Enum.TryParse(normalizedName, out characterName))
        {
            return true;
        }
        
        characterName = CharacterName.WINDHAM; // Default
        return false;
    }

    /// <summary>
    /// Get the character name from a GameObject (useful for clones)
    /// </summary>
    /// <param name="gameObject">The GameObject to identify</param>
    /// <returns>The character's display name as a string</returns>
    public string GetCharacterDisplayName(GameObject gameObject)
    {
        if (gameObject == null) return string.Empty;
        
        if (gameObjectToCharacterName.TryGetValue(gameObject.name, out CharacterName characterName))
        {
            return characterName.ToString().Replace("_", " ");
        }
        
        // If we can't find it directly, try to be smarter about it by checking if it contains character names
        string objName = gameObject.name.ToUpper();
        
        foreach (CharacterName name in System.Enum.GetValues(typeof(CharacterName)))
        {
            string nameStr = name.ToString();
            if (objName.Contains(nameStr.Replace("_", " ")) || objName.Contains(nameStr))
            {
                return nameStr.Replace("_", " ");
            }
        }
        
        Debug.LogWarning($"Unknown character GameObject: {gameObject.name}");
        return gameObject.name;
    }

    /// <summary>
    /// Check if a GameObject is a valid character prefab
    /// </summary>
    public bool IsValidCharacter(GameObject gameObject)
    {
        if (gameObject == null) return false;
        return gameObjectToCharacterName.ContainsKey(gameObject.name) || 
               FindMatchingCharacterName(gameObject.name) != null;
    }

    private string FindMatchingCharacterName(string objectName)
    {
        string upperName = objectName.ToUpper();
        
        // Check each character name
        foreach (CharacterName name in System.Enum.GetValues(typeof(CharacterName)))
        {
            string nameStr = name.ToString();
            if (upperName.Contains(nameStr.Replace("_", " ")) || upperName.Contains(nameStr))
            {
                return nameStr;
            }
        }
        
        return null;
    }
} 