using UnityEngine;
using System;

/// <summary>
/// Base class for all travel events that can occur during journeys
/// </summary>
[Serializable]
public abstract class TravelEvent : ScriptableObject
{
    [Header("Basic Event Info")]
    public string eventName;
    [TextArea(3, 6)]
    public string eventDescription;
    public EventType eventType;
    public EventRarity rarity = EventRarity.Common;

    [Header("Trigger Behavior")]
    [Tooltip("How this event is triggered - automatically or as a spottable marker")]
    public EventTriggerType triggerType = EventTriggerType.Automatic;

    [Header("Terrain Preferences")]
    [Range(0f, 1f)]
    public float plainsChance = 0.5f;
    [Range(0f, 1f)]
    public float forestChance = 0.5f;
    [Range(0f, 1f)]
    public float mountainChance = 0.5f;
    [Range(0f, 1f)]
    public float roadChance = 0.5f;
    [Range(0f, 1f)]
    public float riverChance = 0.5f;
    [Range(0f, 1f)]
    public float lakeChance = 0.5f;
    [Range(0f, 1f)]
    public float oceanChance = 0.5f;

    [Header("Feature Preferences")]
    [Range(0f, 1f)]
    public float townChance = 0.5f;
    [Range(0f, 1f)]
    public float villageChance = 0.5f;
    [Range(0f, 1f)]
    public float bridgeChance = 0.5f;
    [Range(0f, 1f)]
    public float tunnelChance = 0.5f;
    [Range(0f, 1f)]
    public float ferryChance = 0.5f;

    [Header("Timing")]
    public bool canOccurMultipleTimes = true;
    public float cooldownDays = 0f; // Days before this event can occur again

    /// <summary>
    /// Calculate the chance of this event occurring on a specific tile
    /// </summary>
    public virtual float GetEventChance(MapTile tile)
    {
        float baseChance = GetBaseChanceForRarity();
        float terrainModifier = GetTerrainModifier(tile.terrainType);
        float featureModifier = GetFeatureModifier(tile.featureType);

        return baseChance * terrainModifier * featureModifier;
    }

    /// <summary>
    /// Execute the event - must be implemented by derived classes
    /// </summary>
    public abstract EventResult ExecuteEvent(TravelEventContext context);

    /// <summary>
    /// Check if this event can occur given the current context
    /// </summary>
    public virtual bool CanOccur(TravelEventContext context)
    {
        // Check cooldown
        if (!canOccurMultipleTimes && context.eventHistory.HasOccurred(this))
        {
            return false;
        }

        if (cooldownDays > 0f && context.eventHistory.GetTimeSinceLastOccurrence(this) < cooldownDays)
        {
            return false;
        }

        return true;
    }

    private float GetBaseChanceForRarity()
    {
        return rarity switch
        {
            EventRarity.VeryCommon => 0.25f,
            EventRarity.Common => 0.15f,
            EventRarity.Uncommon => 0.08f,
            EventRarity.Rare => 0.04f,
            EventRarity.VeryRare => 0.02f,
            EventRarity.Legendary => 0.005f,
            _ => 0.1f
        };
    }

    private float GetTerrainModifier(TerrainType terrain)
    {
        return terrain switch
        {
            TerrainType.Plains => plainsChance,
            TerrainType.Forest => forestChance,
            TerrainType.Mountain => mountainChance,
            TerrainType.River => riverChance,
            TerrainType.Lake => lakeChance,
            TerrainType.Ocean => oceanChance,
            TerrainType.ForestRiver => forestChance * riverChance, // Hybrid terrain
            _ => 0.5f
        };
    }

    private float GetFeatureModifier(FeatureType feature)
    {
        return feature switch
        {
            FeatureType.Road => roadChance,
            FeatureType.Town => townChance,
            FeatureType.Village => villageChance,
            FeatureType.Bridge => bridgeChance,
            FeatureType.Tunnel => tunnelChance,
            FeatureType.Ferry => ferryChance,
            FeatureType.None => 1f, // No modifier for no feature
            _ => 0.5f
        };
    }
}

[Serializable]
public enum EventType
{
    Combat,     // Battle encounters
    Trading,    // Merchant encounters
    Discovery,  // Finding items/resources
    Social,     // Meeting NPCs, getting information
    Hazard,     // Environmental dangers
    Rest,       // Camping, healing opportunities
    Mystery     // Strange occurrences, puzzles
}

[Serializable]
public enum EventRarity
{
    VeryCommon,  // 25% base chance
    Common,      // 15% base chance
    Uncommon,    // 8% base chance
    Rare,        // 4% base chance
    VeryRare,    // 2% base chance
    Legendary    // 0.5% base chance
}

/// <summary>
/// Result of executing a travel event
/// </summary>
[Serializable]
public class EventResult
{
    public bool eventOccurred = true;
    public bool shouldStopTravel = false;
    public bool startBattle = false;
    public bool openTrading = false;
    public bool suppressMessage = false; // Skip showing event message (used when popup handles display)
    public string resultMessage = "";

    // Resource changes
    public int goldChange = 0;
    public int foodChange = 0;
    public int healthChange = 0;

    // Battle setup (if startBattle is true)
    public BattleEventData battleData;

    // Trading setup (if openTrading is true)
    public TradingEventData tradingData;

    public EventResult(string message)
    {
        resultMessage = message;
    }

    public static EventResult NoEvent()
    {
        return new EventResult("") { eventOccurred = false };
    }

    public static EventResult SimpleBattle(string message, int enemyCount, string enemyType = "Bandit")
    {
        return new EventResult(message)
        {
            shouldStopTravel = true,
            startBattle = true,
            battleData = new BattleEventData
            {
                enemyCount = enemyCount,
                enemyType = enemyType
            }
        };
    }

    public static EventResult SimpleTrading(string message, string merchantType = "Traveling Merchant")
    {
        return new EventResult(message)
        {
            shouldStopTravel = true,
            openTrading = true,
            tradingData = new TradingEventData
            {
                merchantType = merchantType,
                hasRareItems = UnityEngine.Random.value < 0.3f
            }
        };
    }
}

[Serializable]
public class BattleEventData
{
    public int enemyCount = 1;
    public string enemyType = "Bandit";
    public string battleDescription = "";
    [Tooltip("Reference to the actual enemy data asset (safer than string names)")]
    public EnemyCharacterData enemyCharacterData = null;
}

[Serializable]
public class TradingEventData
{
    public string merchantType = "Traveling Merchant";
    public bool hasRareItems = false;
    public float priceModifier = 1f; // 1f = normal prices, 0.8f = 20% discount, etc.
}
