using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Static data transfer class for passing combat-related data between scenes
/// Handles team data, enemy data, terrain information, and battle context
/// </summary>
public static class CombatDataTransfer
{
    [System.Serializable]
    public class CombatSessionData
    {
        [Header("Battle Context")]
        public string battleDescription = "";
        public Vector2Int battleLocation = Vector2Int.zero;
        public TerrainType battleTerrain = TerrainType.Plains;
        public FeatureType battleFeature = FeatureType.None;

        [Header("Team Data")]
        public List<TeamCharacterCombatData> playerTeam = new List<TeamCharacterCombatData>();

        [Header("Enemy Data")]
        public List<EnemyCombatData> enemies = new List<EnemyCombatData>();

        [Header("Environmental Settings")]
        public Weather weather = Weather.Clear;
        public float timeOfDay = 12f; // 0-24 hours

        public CombatSessionData()
        {
            playerTeam = new List<TeamCharacterCombatData>();
            enemies = new List<EnemyCombatData>();
        }
    }

    [System.Serializable]
    public class TeamCharacterCombatData
    {
        public string characterName = "";
        public bool isMale = true;

        // Core stats
        public int strength = 10;
        public int dexterity = 10;
        public int constitution = 10;
        public int wisdom = 10;
        public int perception = 10;

        // Combat stats
        public int maxHealth = 20;
        public int currentHealth = 20;
        public int armorClass = 10;

        // Equipment
        public string equippedWeapon = "Sword"; // Keep for backward compatibility
        public WeaponItem equippedWeaponItem = null; // NEW: Actual weapon item reference
        public string equippedArmor = "";
        public List<string> availableWeapons = new List<string>();
        public List<string> availableArmor = new List<string>();

        // Resources
        public int gold = 25;
        public int silver = 0;
        public int copper = 0;

        public TeamCharacterCombatData()
        {
            availableWeapons = new List<string>();
            availableArmor = new List<string>();
        }

        /// <summary>
        /// Create combat data from a TeamCharacter
        /// </summary>
        public static TeamCharacterCombatData FromTeamCharacter(TeamCharacter teamChar)
        {
            var combatData = new TeamCharacterCombatData();

            if (teamChar != null)
            {
                combatData.characterName = teamChar.name;
                combatData.isMale = teamChar.isMale;
                combatData.strength = teamChar.strength;
                combatData.dexterity = teamChar.dexterity;
                combatData.constitution = teamChar.constitution;
                combatData.wisdom = teamChar.wisdom;
                combatData.perception = teamChar.perception;
                combatData.gold = teamChar.gold;
                combatData.silver = teamChar.silver;
                combatData.copper = teamChar.copper;

                // Ensure equipped weapon is not empty, fallback to first available or "Fists"
                combatData.equippedWeapon = !string.IsNullOrEmpty(teamChar.equippedWeapon)
                    ? teamChar.equippedWeapon
                    : (teamChar.weapons != null && teamChar.weapons.Count > 0)
                        ? teamChar.weapons[0]
                        : "Fists";

                Debug.Log($"🔧 FromTeamCharacter: Character '{teamChar.name}' - equippedWeapon: '{teamChar.equippedWeapon}', weapons list: [{(teamChar.weapons != null ? string.Join(", ", teamChar.weapons) : "null")}], resolved to: '{combatData.equippedWeapon}'");

                // Try to find the actual WeaponItem for the equipped weapon
                combatData.equippedWeaponItem = FindWeaponItem(combatData.equippedWeapon);
                if (combatData.equippedWeaponItem != null)
                {
                    Debug.Log($"🔧 Team character {teamChar.name}: Found WeaponItem '{combatData.equippedWeaponItem.itemName}' for weapon '{combatData.equippedWeapon}'");
                }
                else if (combatData.equippedWeapon != "Fists")
                {
                    Debug.LogWarning($"⚠️ Team character {teamChar.name}: Could not find WeaponItem for '{combatData.equippedWeapon}' - will use string fallback");
                }

                combatData.equippedArmor = teamChar.equippedArmor;

                // Calculate derived stats
                combatData.maxHealth = 10 + (teamChar.constitution * 2); // HP formula
                combatData.currentHealth = combatData.maxHealth; // Start at full health
                combatData.armorClass = 10 + (teamChar.dexterity / 2 - 5); // AC formula

                // Copy equipment lists
                if (teamChar.weapons != null)
                    combatData.availableWeapons.AddRange(teamChar.weapons);
                if (teamChar.armor != null)
                    combatData.availableArmor.AddRange(teamChar.armor);
            }

            return combatData;
        }
    }

    [System.Serializable]
    public class EnemyCombatData
    {
        public string enemyName = "Bandit";
        public string enemyType = "Humanoid";
        public int maxHealth = 15;
        public int currentHealth = 15;
        public int armorClass = 12;
        public int threatLevel = 2;
        public string preferredWeapon = "Sword"; // Keep for backward compatibility
        public WeaponItem preferredWeaponItem = null; // NEW: Actual weapon item reference
        public EnemyCharacterData sourceData = null; // Reference to original data

        /// <summary>
        /// Create combat data from EnemyCharacterData
        /// </summary>
        public static EnemyCombatData FromEnemyData(EnemyCharacterData enemyData, int instanceNumber = 1)
        {
            var combatData = new EnemyCombatData();

            if (enemyData != null)
            {
                combatData.enemyName = $"{enemyData.enemyName}_{instanceNumber}";
                combatData.enemyType = enemyData.enemyName;
                combatData.maxHealth = enemyData.maxHealth;
                combatData.currentHealth = enemyData.maxHealth;
                combatData.armorClass = enemyData.armorClass;
                combatData.threatLevel = enemyData.threatLevel;

                // Extract weapon type properly from WeaponItem
                if (enemyData.preferredWeapon != null)
                {
                    combatData.preferredWeapon = enemyData.preferredWeapon.weaponType.ToString();
                    combatData.preferredWeaponItem = enemyData.preferredWeapon; // Store actual WeaponItem
                    Debug.Log($"🔧 Enemy {enemyData.enemyName}: WeaponItem.weaponType = {enemyData.preferredWeapon.weaponType} -> '{combatData.preferredWeapon}'");
                }
                else
                {
                    combatData.preferredWeapon = "Fists"; // Default fallback
                    combatData.preferredWeaponItem = null;
                    Debug.Log($"🔧 Enemy {enemyData.enemyName}: No preferredWeapon assigned -> defaulting to 'Fists'");
                }

                combatData.sourceData = enemyData;
            }

            return combatData;
        }
    }

    // Current combat session data
    private static CombatSessionData currentSession = null;

    /// <summary>
    /// Initialize a new combat session with the given data
    /// </summary>
    public static void InitializeCombatSession(BattleEventData battleData, TravelEventContext context, List<TeamCharacter> teamMembers)
    {
        currentSession = new CombatSessionData();

        // Set battle context
        if (context != null)
        {
            currentSession.battleLocation = context.currentPosition;
            currentSession.battleTerrain = context.currentTile?.terrainType ?? TerrainType.Plains;
            currentSession.battleFeature = context.currentTile?.featureType ?? FeatureType.None;
            currentSession.weather = context.currentWeather;
            currentSession.timeOfDay = context.timeOfDay;
        }

        // Set battle description
        if (battleData != null)
        {
            currentSession.battleDescription = battleData.battleDescription;
        }

        // Convert team members to combat data
        if (teamMembers != null)
        {
            foreach (var teamMember in teamMembers)
            {
                if (teamMember != null)
                {
                    currentSession.playerTeam.Add(TeamCharacterCombatData.FromTeamCharacter(teamMember));
                }
            }
        }

        // Create enemy combat data
        if (battleData != null && battleData.enemyCharacterData != null)
        {
            for (int i = 0; i < battleData.enemyCount; i++)
            {
                currentSession.enemies.Add(EnemyCombatData.FromEnemyData(battleData.enemyCharacterData, i + 1));
            }
        }

        Debug.Log($"🎯 Combat session initialized: {currentSession.playerTeam.Count} players vs {currentSession.enemies.Count} enemies on {currentSession.battleTerrain} terrain");
    }

    /// <summary>
    /// Get the current combat session data
    /// </summary>
    public static CombatSessionData GetCurrentSession()
    {
        return currentSession;
    }

    /// <summary>
    /// Check if there's a valid combat session
    /// </summary>
    public static bool HasValidSession()
    {
        return currentSession != null &&
               currentSession.playerTeam.Count > 0 &&
               currentSession.enemies.Count > 0;
    }

    /// <summary>
    /// Clear the current combat session (call after battle ends)
    /// </summary>
    public static void ClearSession()
    {
        currentSession = null;
        Debug.Log("🧹 Combat session cleared");
    }

    /// <summary>
    /// Get terrain-appropriate description for battle setup
    /// </summary>
    public static string GetTerrainDescription(TerrainType terrain, FeatureType feature)
    {
        string baseDescription = terrain switch
        {
            TerrainType.Plains => "open grasslands",
            TerrainType.Forest => "dense woodland",
            TerrainType.Mountain => "rocky mountain terrain",
            TerrainType.River => "along a flowing river",
            TerrainType.Lake => "near a peaceful lake",
            TerrainType.Ocean => "along the coastline",
            TerrainType.Shore => "on sandy shores",
            _ => "unknown terrain"
        };

        string featureDescription = feature switch
        {
            FeatureType.Road => "on a well-traveled road",
            FeatureType.Bridge => "at a stone bridge",
            FeatureType.Town => "within town limits",
            FeatureType.Village => "near a small village",
            FeatureType.Tunnel => "in a dark tunnel",
            FeatureType.Ferry => "at a ferry crossing",
            FeatureType.Harbour => "at a busy harbor",
            _ => ""
        };

        if (!string.IsNullOrEmpty(featureDescription))
        {
            return $"{featureDescription} in {baseDescription}";
        }

        return $"in {baseDescription}";
    }

    /// <summary>
    /// Create legacy BattleSetupData for compatibility with existing battle scene
    /// </summary>
    public static void PopulateLegacyBattleSetupData()
    {
        if (!HasValidSession())
        {
            Debug.LogError("❌ No valid combat session to populate legacy battle setup data");
            return;
        }

        // Clear existing data
        BattleSetupData.playerSelections.Clear();
        BattleSetupData.enemySelections.Clear();

        // Populate player selections
        foreach (var player in currentSession.playerTeam)
        {
            string weaponType = !string.IsNullOrEmpty(player.equippedWeapon) ? player.equippedWeapon : "Fists";
            Debug.Log($"🔧 Player {player.characterName}: equippedWeapon='{player.equippedWeapon}' -> weaponType='{weaponType}'");
            BattleSetupData.playerSelections.Add(new CharacterSelection
            {
                characterName = player.characterName,
                weaponType = weaponType
            });
        }

        // Populate enemy selections
        foreach (var enemy in currentSession.enemies)
        {
            string weaponType = !string.IsNullOrEmpty(enemy.preferredWeapon) ? enemy.preferredWeapon : "Fists";
            Debug.Log($"🔧 Enemy {enemy.enemyName}: preferredWeapon='{enemy.preferredWeapon}' -> weaponType='{weaponType}'");
            BattleSetupData.enemySelections.Add(new CharacterSelection
            {
                characterName = enemy.enemyName,
                weaponType = weaponType
            });
        }

        Debug.Log($"✅ Legacy battle setup data populated: {BattleSetupData.playerSelections.Count} players, {BattleSetupData.enemySelections.Count} enemies");
    }

    /// <summary>
    /// Debug method to log current session information
    /// </summary>
    [System.Diagnostics.Conditional("UNITY_EDITOR")]
    public static void DebugLogSession()
    {
        if (currentSession == null)
        {
            Debug.Log("🔍 No active combat session");
            return;
        }

        Debug.Log("=== COMBAT SESSION DEBUG ===");
        Debug.Log($"📍 Location: {currentSession.battleLocation}");
        Debug.Log($"🌍 Terrain: {currentSession.battleTerrain} / {currentSession.battleFeature}");
        Debug.Log($"🌤️ Weather: {currentSession.weather} at {currentSession.timeOfDay:F1}h");
        Debug.Log($"👥 Players: {currentSession.playerTeam.Count}");
        foreach (var player in currentSession.playerTeam)
        {
            Debug.Log($"  - {player.characterName} (HP: {player.currentHealth}/{player.maxHealth}, AC: {player.armorClass}, Weapon: {player.equippedWeapon})");
        }
        Debug.Log($"👹 Enemies: {currentSession.enemies.Count}");
        foreach (var enemy in currentSession.enemies)
        {
            Debug.Log($"  - {enemy.enemyName} (HP: {enemy.currentHealth}/{enemy.maxHealth}, AC: {enemy.armorClass}, Threat: {enemy.threatLevel})");
        }
        Debug.Log("=== END COMBAT SESSION ===");
    }

    /// <summary>
    /// Helper method to find a WeaponItem by name or type
    /// </summary>
    private static WeaponItem FindWeaponItem(string weaponIdentifier)
    {
        if (string.IsNullOrEmpty(weaponIdentifier) || weaponIdentifier == "Fists")
        {
            Debug.Log($"🔍 FindWeaponItem: Skipping '{weaponIdentifier}' (null/empty/Fists)");
            return null;
        }

        Debug.Log($"🔍 FindWeaponItem: Looking for weapon '{weaponIdentifier}'");

        // Load all WeaponItem assets from Resources folders
        WeaponItem[] allWeapons = Resources.LoadAll<WeaponItem>("");
        Debug.Log($"🔍 FindWeaponItem: Found {allWeapons.Length} WeaponItem assets in Resources");

        // Debug: List all available weapons
        foreach (var weapon in allWeapons)
        {
            if (weapon != null)
            {
                Debug.Log($"  📋 Available weapon: '{weapon.itemName}' (type: {weapon.weaponType})");
            }
        }

        // First try exact name match
        foreach (var weapon in allWeapons)
        {
            if (weapon != null && string.Equals(weapon.itemName, weaponIdentifier, System.StringComparison.OrdinalIgnoreCase))
            {
                Debug.Log($"✅ FindWeaponItem: Found exact match for '{weaponIdentifier}' -> '{weapon.itemName}'");
                return weapon;
            }
        }

        Debug.Log($"⚠️ FindWeaponItem: No exact name match for '{weaponIdentifier}', trying weapon type match...");

        // Then try weapon type match
        if (System.Enum.TryParse<WeaponType>(weaponIdentifier, true, out WeaponType weaponType))
        {
            Debug.Log($"🔍 FindWeaponItem: Parsed '{weaponIdentifier}' as WeaponType.{weaponType}");

            // Look for a weapon of this type, prefer "Simple" variants
            WeaponItem simpleWeapon = null;
            WeaponItem anyWeapon = null;

            foreach (var weapon in allWeapons)
            {
                if (weapon != null && weapon.weaponType == weaponType)
                {
                    anyWeapon = weapon; // Keep track of any weapon of this type
                    Debug.Log($"  🎯 Found weapon of type {weaponType}: '{weapon.itemName}'");

                    // Prefer simple/basic weapons
                    if (weapon.itemName.ToLower().Contains("simple") || weapon.itemName.ToLower().Contains("basic"))
                    {
                        simpleWeapon = weapon;
                        Debug.Log($"  ⭐ Preferred simple weapon: '{weapon.itemName}'");
                        break; // Found preferred weapon, stop searching
                    }
                }
            }

            WeaponItem result = simpleWeapon ?? anyWeapon;
            if (result != null)
            {
                Debug.Log($"✅ FindWeaponItem: Found weapon by type '{weaponIdentifier}' -> '{result.itemName}'");
            }
            else
            {
                Debug.LogWarning($"❌ FindWeaponItem: No weapon found for type '{weaponType}'");
            }
            return result;
        }
        else
        {
            Debug.LogWarning($"❌ FindWeaponItem: Could not parse '{weaponIdentifier}' as WeaponType enum");
        }

        Debug.LogError($"❌ FindWeaponItem: No weapon found for '{weaponIdentifier}'");
        return null;
    }
}
