using UnityEngine;

/// <summary>
/// Combat encounter events - ambushes, bandits, wild animals, etc.
/// More likely in forests and mountains, less likely on roads
/// </summary>
[CreateAssetMenu(fileName = "New Combat Event", menuName = "RPG/Travel Events/Combat Event")]
public class CombatTravelEvent : TravelEvent
{
    [Header("Combat Event Settings")]
    public int minEnemies = 1;
    public int maxEnemies = 3;
    [Tooltip("Drag EnemyCharacterData assets here")]
    public EnemyCharacterData[] possibleEnemies = new EnemyCharacterData[0];

    [Header("Escape Configuration")]
    public bool allowRunningAway = true;
    [Range(0f, 1f)]
    public float runAwaySuccessChance = 0.75f;
    public int runAwayHealthPenalty = 5;

    [Header("Run Away Messages")]
    [TextArea(2, 4)]
    public string[] successfulRunAwayMessages = {
        "Your party successfully escapes from the enemies!",
        "Quick thinking allows your party to avoid the confrontation!",
        "Your party slips away unnoticed by the enemies."
    };

    [TextArea(2, 4)]
    public string[] failedRunAwayMessages = {
        "The enemies catch up to your party! You take {damage} damage while trying to escape.",
        "Your escape attempt fails! The enemies pursue and wound your party for {damage} damage.",
        "The enemies block your escape route! Your party suffers {damage} damage in the failed attempt."
    };

    [Header("Combat Event Descriptions")]
    [TextArea(2, 4)]
    public string[] encounterDescriptions = {
        "Your party is ambushed by {enemyType}s!",
        "A group of {enemyType}s blocks your path!",
        "You stumble upon a {enemyType} camp!"
    };

    public override EventResult ExecuteEvent(TravelEventContext context)
    {
        int enemyCount = Random.Range(minEnemies, maxEnemies + 1);

        // Ensure we have valid enemies configured
        if (possibleEnemies == null || possibleEnemies.Length == 0)
        {
            Debug.LogError($"No enemies configured for combat event: {eventName}");
            return EventResult.NoEvent();
        }

        // Filter out null entries
        var validEnemies = System.Array.FindAll(possibleEnemies, e => e != null);
        if (validEnemies.Length == 0)
        {
            Debug.LogError($"All enemy references are null for combat event: {eventName}");
            return EventResult.NoEvent();
        }

        // Select random enemy
        EnemyCharacterData selectedEnemy = validEnemies[Random.Range(0, validEnemies.Length)];
        string enemyType = selectedEnemy.enemyName;

        // Generate description
        string description = encounterDescriptions[Random.Range(0, encounterDescriptions.Length)];
        description = description.Replace("{enemyType}", enemyType);

        // Try to use combat event integration for popup choice
        Debug.Log("🔍 Looking for CombatEventIntegration component...");

        // First try to find it by component type
        var integrationComponents = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
        var combatIntegration = System.Array.Find(integrationComponents,
            comp => comp.GetType().Name == "CombatEventIntegration");

        if (combatIntegration == null)
        {
            // Try the reflection approach as fallback
            var type = System.Type.GetType("CombatEventIntegration");
            if (type != null)
            {
                combatIntegration = FindFirstObjectByType(type) as MonoBehaviour;
            }
        }

        if (combatIntegration != null)
        {
            Debug.Log($"✅ Found CombatEventIntegration: {combatIntegration.name}");

            // Create battle data for the popup
            var battleData = new BattleEventData
            {
                enemyCount = enemyCount,
                enemyType = enemyType,
                enemyCharacterData = selectedEnemy
            };

            // Use reflection to call ShowCombatChoicePopup with the new signature
            var method = combatIntegration.GetType().GetMethod("ShowCombatChoicePopup");
            if (method != null)
            {
                Debug.Log($"🎭 Calling ShowCombatChoicePopup with {enemyCount} {enemyType}(s) and combat event reference");
                method.Invoke(combatIntegration, new object[] { battleData, context, description, this });

                // Return a special result that indicates popup is handling the choice
                return new EventResult("Combat encounter detected...")
                {
                    shouldStopTravel = true, // Stop travel while popup is showing
                    startBattle = false, // Don't start battle yet - popup will handle it
                    suppressMessage = true, // Don't show default message - popup handles display
                    eventOccurred = true
                };
            }
            else
            {
                Debug.LogError("❌ ShowCombatChoicePopup method not found on CombatEventIntegration");
            }
        }
        else
        {
            Debug.LogWarning("⚠️ No CombatEventIntegration component found in scene");
        }

        // Fallback to immediate battle if no integration found
        Debug.LogWarning("⚠️ No CombatEventIntegration found, proceeding with immediate battle");
        var result = EventResult.SimpleBattle(description, enemyCount, enemyType);
        result.battleData.enemyCharacterData = selectedEnemy;

        return result;
    }

    /// <summary>
    /// Handle escape attempt for this specific combat event
    /// </summary>
    public EventResult HandleEscapeAttempt(TravelEventContext context)
    {
        if (!allowRunningAway)
        {
            Debug.LogWarning($"🚫 Running away is not allowed for this combat event: {eventName}");
            return null; // Force battle
        }

        Debug.Log($"🏃 Processing escape attempt for {eventName} (success chance: {runAwaySuccessChance:P})");

        // Roll for escape success
        bool escapeSuccessful = Random.value <= runAwaySuccessChance;

        if (escapeSuccessful)
        {
            return CreateSuccessfulEscapeResult();
        }
        else
        {
            return CreateFailedEscapeResult(context);
        }
    }

    /// <summary>
    /// Create result for successful escape
    /// </summary>
    private EventResult CreateSuccessfulEscapeResult()
    {
        string message = successfulRunAwayMessages[Random.Range(0, successfulRunAwayMessages.Length)];
        Debug.Log($"✅ Escape successful: {message}");

        return new EventResult(message)
        {
            shouldStopTravel = false, // Don't stop travel for successful escape
            startBattle = false,
            eventOccurred = true
        };
    }

    /// <summary>
    /// Create result for failed escape
    /// </summary>
    private EventResult CreateFailedEscapeResult(TravelEventContext context)
    {
        string message = failedRunAwayMessages[Random.Range(0, failedRunAwayMessages.Length)];
        message = message.Replace("{damage}", runAwayHealthPenalty.ToString());

        Debug.Log($"❌ Escape failed: {message}");

        var result = new EventResult(message)
        {
            shouldStopTravel = true, // Stop travel for failed escape
            startBattle = false, // Don't start battle, just apply penalty
            eventOccurred = true,
            healthChange = -runAwayHealthPenalty // Apply health penalty through EventResult system
        };

        return result;
    }

    void OnEnable()
    {
        // Set default values for combat events
        eventType = EventType.Combat;
        rarity = EventRarity.Common;

        // Combat events are more likely in dangerous terrain
        forestChance = 0.8f;
        mountainChance = 0.9f;
        plainsChance = 0.4f;
        roadChance = 0.2f; // Much less likely on roads
        townChance = 0.1f; // Very unlikely in towns
        villageChance = 0.3f;
    }
}

/// <summary>
/// Trading encounter events - merchants, traders, caravans
/// More likely on roads and near settlements
/// </summary>
[CreateAssetMenu(fileName = "New Trading Event", menuName = "RPG/Travel Events/Trading Event")]
public class TradingTravelEvent : TravelEvent
{
    [Header("Trading Event Settings")]
    public string[] merchantTypes = { "Traveling Merchant", "Caravan Trader", "Wandering Peddler" };
    public bool canHaveRareItems = true;
    [Range(0f, 1f)]
    public float rareItemChance = 0.3f;
    [Range(0.5f, 1.5f)]
    public float priceModifier = 1f;

    [Header("Trading Event Descriptions")]
    [TextArea(2, 4)]
    public string[] encounterDescriptions = {
        "You encounter a {merchantType} on the road.",
        "A {merchantType} approaches your party with goods to sell.",
        "You come across a {merchantType} resting by the roadside."
    };

    public override EventResult ExecuteEvent(TravelEventContext context)
    {
        string merchantType = merchantTypes[Random.Range(0, merchantTypes.Length)];
        string description = encounterDescriptions[Random.Range(0, encounterDescriptions.Length)];
        description = description.Replace("{merchantType}", merchantType);

        var result = EventResult.SimpleTrading(description, merchantType);
        result.tradingData.hasRareItems = canHaveRareItems && Random.value < rareItemChance;
        result.tradingData.priceModifier = priceModifier;

        return result;
    }

    void OnEnable()
    {
        // Set default values for trading events
        eventType = EventType.Trading;
        rarity = EventRarity.Common;

        // Trading events are more likely on roads and near settlements
        roadChance = 0.9f;
        townChance = 0.7f;
        villageChance = 0.8f;
        bridgeChance = 0.6f; // Common crossing points
        ferryChance = 0.5f;

        // Less likely in wilderness
        forestChance = 0.3f;
        mountainChance = 0.2f;
        plainsChance = 0.5f;
    }
}

/// <summary>
/// Discovery events - finding treasures, resources, or hidden locations
/// </summary>
[CreateAssetMenu(fileName = "New Discovery Event", menuName = "RPG/Travel Events/Discovery Event")]
public class DiscoveryTravelEvent : TravelEvent
{
    [Header("Discovery Settings")]
    public int minGoldFound = 10;
    public int maxGoldFound = 100;
    public bool canFindItems = true;

    [Header("Discovery Descriptions")]
    [TextArea(2, 4)]
    public string[] discoveryDescriptions = {
        "Your party discovers a hidden cache containing {amount} gold!",
        "While exploring, you find an abandoned stash with {amount} gold pieces.",
        "A keen-eyed party member spots something valuable - {amount} gold!"
    };

    public override EventResult ExecuteEvent(TravelEventContext context)
    {
        int goldFound = Random.Range(minGoldFound, maxGoldFound + 1);
        string description = discoveryDescriptions[Random.Range(0, discoveryDescriptions.Length)];
        description = description.Replace("{amount}", goldFound.ToString());

        return new EventResult(description)
        {
            goldChange = goldFound
        };
    }

    void OnEnable()
    {
        eventType = EventType.Discovery;
        rarity = EventRarity.Uncommon;

        // More likely in remote areas
        forestChance = 0.7f;
        mountainChance = 0.8f;
        plainsChance = 0.4f;
        roadChance = 0.3f;
        townChance = 0.1f;
    }
}

/// <summary>
/// Rest events - safe camping spots, inns, healing springs
/// </summary>
[CreateAssetMenu(fileName = "New Rest Event", menuName = "RPG/Travel Events/Rest Event")]
public class RestTravelEvent : TravelEvent
{
    [Header("Rest Settings")]
    public int healthRestored = 25;
    public bool restoresAllHealth = false;

    [Header("Rest Descriptions")]
    [TextArea(2, 4)]
    public string[] restDescriptions = {
        "Your party finds a peaceful grove perfect for resting and recovers {health} health.",
        "A natural spring provides refreshing water, restoring {health} health to your party.",
        "Your party discovers a safe camping spot and takes time to tend wounds, recovering {health} health."
    };

    public override EventResult ExecuteEvent(TravelEventContext context)
    {
        int actualHealing = restoresAllHealth ? 100 : healthRestored;
        string description = restDescriptions[Random.Range(0, restDescriptions.Length)];
        description = description.Replace("{health}", actualHealing.ToString());

        return new EventResult(description)
        {
            healthChange = actualHealing
        };
    }

    void OnEnable()
    {
        eventType = EventType.Rest;
        rarity = EventRarity.Common;

        // More likely in natural areas
        forestChance = 0.8f;
        riverChance = 0.9f;
        lakeChance = 0.9f;
        plainsChance = 0.6f;
        mountainChance = 0.5f;
        roadChance = 0.4f;
        townChance = 0.2f;
    }
}

/// <summary>
/// Hazard events - natural dangers, traps, environmental challenges
/// </summary>
[CreateAssetMenu(fileName = "New Hazard Event", menuName = "RPG/Travel Events/Hazard Event")]
public class HazardTravelEvent : TravelEvent
{
    [Header("Hazard Settings")]
    public int minHealthLoss = 5;
    public int maxHealthLoss = 20;
    public int goldCost = 0; // Cost to avoid the hazard

    [Header("Hazard Descriptions")]
    [TextArea(2, 4)]
    public string[] hazardDescriptions = {
        "Your party gets caught in a sudden rockslide, losing {damage} health.",
        "Treacherous terrain causes injuries to your party members, resulting in {damage} health loss.",
        "A hidden pit trap catches one of your party members, causing {damage} damage."
    };

    public override EventResult ExecuteEvent(TravelEventContext context)
    {
        int damage = Random.Range(minHealthLoss, maxHealthLoss + 1);
        string description = hazardDescriptions[Random.Range(0, hazardDescriptions.Length)];
        description = description.Replace("{damage}", damage.ToString());

        return new EventResult(description)
        {
            healthChange = -damage,
            goldChange = -goldCost
        };
    }

    void OnEnable()
    {
        eventType = EventType.Hazard;
        rarity = EventRarity.Common;

        // More likely in dangerous terrain
        mountainChance = 0.9f;
        forestChance = 0.6f;
        riverChance = 0.7f;
        oceanChance = 0.8f;

        // Less likely in safe areas
        roadChance = 0.2f;
        townChance = 0.1f;
        villageChance = 0.2f;
        plainsChance = 0.4f;
    }
}
