using UnityEngine;

/// <summary>
/// Integration manager that connects TravelEventSystem with CombatEventPopup
/// Handles the choice between battle and escape when combat events occur
/// </summary>
public class CombatEventIntegration : MonoBehaviour
{
    [Header("Combat Popup Integration")]
    [Tooltip("Use either the original CombatEventPopup or the new CombatEventPopupUXML")]
    public CombatEventPopup combatEventPopup; // Original popup (legacy)
    public CombatEventPopupUXML combatEventPopupUXML; // New UXML-based popup
    public GameObject combatPopupPrefab; // Optional: if popup component not already in scene

    // Component references
    private TravelEventSystem travelEventSystem;
    private TravelEventUI eventUI;
    private TeamTravelSystem teamTravelSystem;

    // Current combat state
    private bool isHandlingCombat = false;
    private CombatTravelEvent currentCombatEvent; // Store reference to the current combat event

    void Start()
    {
        Debug.Log("🔧 Combat Event Integration starting...");

        // Find required components - try same GameObject first, then search scene
        travelEventSystem = GetComponent<TravelEventSystem>();
        if (travelEventSystem == null)
            travelEventSystem = FindFirstObjectByType<TravelEventSystem>();

        eventUI = FindFirstObjectByType<TravelEventUI>();
        teamTravelSystem = FindFirstObjectByType<TeamTravelSystem>();

        if (travelEventSystem == null)
        {
            Debug.LogError("❌ Combat Event Integration requires TravelEventSystem in the scene!");
            Debug.LogError("   Please ensure you have a GameObject with TravelEventSystem component.");
            enabled = false;
            return;
        }
        else if (GetComponent<TravelEventSystem>() == null)
        {
            Debug.LogWarning("⚠️ CombatEventIntegration is not on the same GameObject as TravelEventSystem.");
            Debug.LogWarning("   Consider moving it to the TravelEventSystem GameObject for better organization.");
        }

        // Try to find existing popup components first
        if (combatEventPopup == null)
            combatEventPopup = FindFirstObjectByType<CombatEventPopup>();

        if (combatEventPopupUXML == null)
            combatEventPopupUXML = FindFirstObjectByType<CombatEventPopupUXML>();

        // If no popup component found and we have a prefab, instantiate it
        if (combatEventPopup == null && combatEventPopupUXML == null && combatPopupPrefab != null)
        {
            Debug.Log("📦 Instantiating combat popup from prefab...");
            GameObject popupInstance = Instantiate(combatPopupPrefab);
            combatEventPopup = popupInstance.GetComponent<CombatEventPopup>();
            combatEventPopupUXML = popupInstance.GetComponent<CombatEventPopupUXML>();

            if (combatEventPopup == null && combatEventPopupUXML == null)
            {
                Debug.LogError("❌ Combat popup prefab does not contain CombatEventPopup or CombatEventPopupUXML component!");
                enabled = false;
                return;
            }
        }

        if (combatEventPopup == null && combatEventPopupUXML == null)
        {
            Debug.LogError("❌ Combat Event Integration requires a CombatEventPopup or CombatEventPopupUXML component!");
            Debug.LogError("   Either add one of these components to a GameObject in the scene,");
            Debug.LogError("   or assign a prefab with one of these components to combatPopupPrefab field.");
            enabled = false;
            return;
        }

        // Setup combat popup callbacks
        if (combatEventPopup != null)
            combatEventPopup.OnCombatDecision += HandleCombatDecision;

        if (combatEventPopupUXML != null)
            combatEventPopupUXML.OnCombatDecision += HandleCombatDecision;

        Debug.Log("✅ Combat Event Integration initialized successfully");
    }

    void OnDestroy()
    {
        if (combatEventPopup != null)
            combatEventPopup.OnCombatDecision -= HandleCombatDecision;

        if (combatEventPopupUXML != null)
            combatEventPopupUXML.OnCombatDecision -= HandleCombatDecision;
    }

    /// <summary>
    /// Call this method when a combat event occurs to show the popup
    /// This should be called from TravelEventTypes.cs in the ExecuteEvent method
    /// </summary>
    public void ShowCombatChoicePopup(BattleEventData battleData, TravelEventContext context, string eventDescription, CombatTravelEvent combatEvent = null)
    {
        if (isHandlingCombat || battleData == null)
            return;

        Debug.Log($"🎭 Showing combat choice popup: {eventDescription}");

        isHandlingCombat = true;
        currentCombatEvent = combatEvent; // Store reference to the original combat event

        // Store battle data for later use
        currentBattleData = battleData;
        currentContext = context;

        // Show combat popup - try UXML version first, then fallback to original
        if (combatEventPopupUXML != null)
        {
            Debug.Log("Using UXML-based combat popup");
            combatEventPopupUXML.OnCombatDecision = HandleCombatDecision;
            combatEventPopupUXML.ShowCombatEncounter(battleData, context, eventDescription);
        }
        else if (combatEventPopup != null)
        {
            Debug.Log("Using original combat popup");
            combatEventPopup.OnCombatDecision = HandleCombatDecision;
            combatEventPopup.ShowCombatEncounter(battleData, context, eventDescription);
        }
        else
        {
            Debug.LogError("No combat popup component assigned! Please assign either CombatEventPopup or CombatEventPopupUXML.");
            isHandlingCombat = false;
        }
    }

    // Store current battle data
    private BattleEventData currentBattleData;
    private TravelEventContext currentContext;

    /// <summary>
    /// Handle the player's combat decision from the popup
    /// </summary>
    private void HandleCombatDecision(bool chooseToAttack)
    {
        if (!isHandlingCombat || currentBattleData == null)
            return;

        isHandlingCombat = false;

        if (chooseToAttack)
        {
            HandleAttackChoice();
        }
        else
        {
            HandleRunAwayChoice();
        }

        // Clear stored data
        currentBattleData = null;
        currentContext = null;
    }

    /// <summary>
    /// Handle when player chooses to attack
    /// </summary>
    private void HandleAttackChoice()
    {
        Debug.Log("⚔️ Player chose to fight! Setting up battle...");

        // Create and return the battle result that will start the battle
        var battleResult = EventResult.SimpleBattle(
            $"Your party prepares for battle against {currentBattleData.enemyCount} {currentBattleData.enemyType}!",
            currentBattleData.enemyCount,
            currentBattleData.enemyType
        );

        // Copy over the enemy character data
        battleResult.battleData.enemyCharacterData = currentBattleData.enemyCharacterData;

        // Apply the battle result through the travel event system
        ApplyBattleResult(battleResult);
    }

    /// <summary>
    /// Handle when player chooses to run away
    /// </summary>
    private void HandleRunAwayChoice()
    {
        Debug.Log("🏃 Player chose to run away!");

        EventResult escapeResult = null;

        // Use the combat event's escape handling if available
        if (currentCombatEvent != null)
        {
            Debug.Log($"🎯 Using escape configuration from {currentCombatEvent.eventName}");
            escapeResult = currentCombatEvent.HandleEscapeAttempt(currentContext);
        }
        else
        {
            Debug.LogWarning("⚠️ No combat event reference - using hardcoded fallback escape handling");

            // Hardcoded fallback values when no combat event is available
            const float fallbackSuccessChance = 0.75f;
            bool escapeSuccessful = Random.value <= fallbackSuccessChance;

            if (escapeSuccessful)
            {
                escapeResult = CreateFallbackSuccessfulEscape();
            }
            else
            {
                escapeResult = CreateFallbackFailedEscape();
            }
        }

        // Apply the escape result
        if (escapeResult != null)
        {
            ApplyBattleResult(escapeResult);
        }
        else
        {
            Debug.LogWarning("⚠️ Escape not allowed by combat event - forcing battle");
            HandleAttackChoice();
        }
    }

    /// <summary>
    /// Create fallback successful escape result when no combat event is available
    /// </summary>
    private EventResult CreateFallbackSuccessfulEscape()
    {
        string message = "Your party successfully escapes from the enemies!";
        Debug.Log($"✅ Fallback escape successful: {message}");

        return new EventResult(message)
        {
            shouldStopTravel = false,
            startBattle = false,
            eventOccurred = true,
            healthChange = 0
        };
    }

    /// <summary>
    /// Create fallback failed escape result when no combat event is available
    /// </summary>
    private EventResult CreateFallbackFailedEscape()
    {
        const int fallbackHealthPenalty = 5; // Hardcoded fallback value
        string message = $"The enemies catch up to your party! You take {fallbackHealthPenalty} damage while trying to escape.";

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

        return new EventResult(message)
        {
            shouldStopTravel = true,
            startBattle = false,
            eventOccurred = true,
            healthChange = -fallbackHealthPenalty
        };
    }    /// <summary>
         /// Apply battle result through the travel event system
         /// </summary>
    private void ApplyBattleResult(EventResult result)
    {
        // Apply resource changes
        if (result.healthChange != 0)
        {
            Debug.Log($"❤️ Health changed by {result.healthChange}");
            // TODO: Actually apply health changes to party
        }

        if (result.goldChange != 0)
        {
            Debug.Log($"💰 Gold changed by {result.goldChange}");
            // TODO: Actually apply gold changes to party
        }

        // Handle travel stopping
        if (result.shouldStopTravel && teamTravelSystem != null)
        {
            teamTravelSystem.CancelJourney();
            Debug.Log("🛑 Travel stopped due to event");
        }

        // Handle battle start
        if (result.startBattle)
        {
            Debug.Log($"⚔️ Starting battle: {result.battleData.enemyCount} {result.battleData.enemyType}(s)");

            // Use the new CombatSceneManager to handle battle transition
            MonoBehaviour combatSceneManager = FindCombatSceneManager();
            if (combatSceneManager != null)
            {
                Debug.Log("🎬 Transitioning to battle scene with CombatSceneManager...");

                // Use reflection to call StartCombatEncounter method
                var method = combatSceneManager.GetType().GetMethod("StartCombatEncounter");
                if (method != null)
                {
                    method.Invoke(combatSceneManager, new object[] { result.battleData, currentContext });
                }
                else
                {
                    Debug.LogError("❌ StartCombatEncounter method not found on CombatSceneManager");
                    HandleLegacyBattleStart(result.battleData);
                }
            }
            else
            {
                Debug.LogWarning("⚠️ CombatSceneManager not found! Looking for alternative battle systems...");

                // Fallback to legacy battle system if available
                HandleLegacyBattleStart(result.battleData);
            }

            if (result.battleData.enemyCharacterData != null)
            {
                Debug.Log($"🎯 Using enemy data: {result.battleData.enemyCharacterData.enemyName}");
                Debug.Log($"📊 Enemy stats: HP={result.battleData.enemyCharacterData.maxHealth}, " +
                         $"AC={result.battleData.enemyCharacterData.armorClass}, " +
                         $"Threat={result.battleData.enemyCharacterData.threatLevel}");
            }
        }
    }

    /// <summary>
    /// Check if the system is currently handling a combat choice
    /// </summary>
    public bool IsHandlingCombat => isHandlingCombat;

    /// <summary>
    /// Cancel current combat handling (for cleanup)
    /// </summary>
    public void CancelCombatHandling()
    {
        if (isHandlingCombat)
        {
            isHandlingCombat = false;
            currentBattleData = null;
            currentContext = null;

            if (combatEventPopup != null)
                combatEventPopup.ForceClose();
        }
    }

    /// <summary>
    /// Handle legacy battle start when CombatSceneManager is not available
    /// </summary>
    private void HandleLegacyBattleStart(BattleEventData battleData)
    {
        Debug.Log("🔧 Using legacy battle system...");

        // Try to find and use existing battle systems
        var enhancedEventSystem = FindFirstObjectByType<EnhancedTravelEventSystem>();
        if (enhancedEventSystem != null)
        {
            Debug.Log("📞 Delegating to EnhancedTravelEventSystem");
            // This system should have methods to handle battle setup
        }
        else
        {
            Debug.Log("📝 Logging battle setup for manual handling");
            Debug.Log($"⚔️ Battle Setup Required:");
            Debug.Log($"  - Enemies: {battleData.enemyCount}x {battleData.enemyType}");
            if (battleData.enemyCharacterData != null)
            {
                Debug.Log($"  - Enemy Data: {battleData.enemyCharacterData.enemyName}");
                Debug.Log($"  - Enemy HP: {battleData.enemyCharacterData.maxHealth}");
                Debug.Log($"  - Enemy AC: {battleData.enemyCharacterData.armorClass}");
            }
        }
    }

    /// <summary>
    /// Find CombatSceneManager using reflection to avoid compilation issues
    /// </summary>
    private MonoBehaviour FindCombatSceneManager()
    {
        // First try to find it by component type name
        var allComponents = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
        var combatSceneManager = System.Array.Find(allComponents,
            comp => comp.GetType().Name == "CombatSceneManager");

        return combatSceneManager;
    }
}
