using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif

/// <summary>
/// Manages the Game Over screen with statistics and final results using UI Toolkit
/// Shows when all player characters die
/// </summary>
public class GameOverScreen : MonoBehaviour
{
    [Header("UI Toolkit Settings")]
    public UIDocument uiDocument;
    public VisualTreeAsset gameOverTemplate;
    public PanelSettings panelSettings;

    [Header("Statistics Settings")]
    public bool showDetailedStats = true;

    [Header("Audio")]
    public AudioClip gameOverMusic;
    public AudioClip defeatSound;

    private GameStatistics gameStats;
    private VisualElement rootElement;

    [System.Serializable]
    public class GameStatistics
    {
        [Header("Time & Travel")]
        public float totalPlayTime = 0f;
        public float totalTravelTime = 0f;
        public int daysTravaeled = 0;
        public int locationsVisited = 0;

        [Header("Combat")]
        public int battlesWon = 0;
        public int battlesLost = 0;
        public int enemiesSlain = 0;
        public int totalDamageDealt = 0;
        public int totalDamageTaken = 0;

        [Header("Social & Quests")]
        public int peopleHelped = 0;
        public int peopleSaved = 0;
        public int questsCompleted = 0;
        public int questsFailed = 0;

        [Header("Character Development")]
        public int finalFameLevel = 0;
        public int totalExperienceGained = 0;
        public int levelsGained = 0;

        [Header("Economic")]
        public int totalGoldEarned = 0;
        public int totalGoldSpent = 0;
        public int itemsBought = 0;
        public int itemsSold = 0;

        [Header("Survival")]
        public int charactersLost = 0;
        public int timesRested = 0;
        public int healthPotionsUsed = 0;

        public GameStatistics()
        {
            // Initialize with default values
        }

        /// <summary>
        /// Calculate derived statistics
        /// </summary>
        public int GetTotalBattles() => battlesWon + battlesLost;
        public float GetWinRate() => GetTotalBattles() > 0 ? (float)battlesWon / GetTotalBattles() * 100f : 0f;
        public int GetNetGold() => totalGoldEarned - totalGoldSpent;
        public float GetDamageRatio() => totalDamageTaken > 0 ? (float)totalDamageDealt / totalDamageTaken : 0f;
    }

    void Awake()
    {
        // Initialize game statistics
        gameStats = new GameStatistics();

        // Set up UI Document component
        SetupUIDocument();

        if (uiDocument != null && uiDocument.visualTreeAsset != null)
        {
            rootElement = uiDocument.rootVisualElement;

            // Hide game over panel initially
            if (rootElement != null)
                rootElement.style.display = DisplayStyle.None;

            // Set up button events
            SetupUICallbacks();
        }
    }

    /// <summary>
    /// Set up the UIDocument component with proper references
    /// </summary>
    private void SetupUIDocument()
    {
        // Get or create UIDocument component
        if (uiDocument == null)
            uiDocument = GetComponent<UIDocument>();

        if (uiDocument == null)
            uiDocument = gameObject.AddComponent<UIDocument>();

        // Load the UXML template if not assigned
        if (gameOverTemplate == null)
        {
            gameOverTemplate = Resources.Load<VisualTreeAsset>("UI/BattleSceneUI/GameOverScreen");
            if (gameOverTemplate == null)
            {
#if UNITY_EDITOR
                // Try alternative path in editor
                gameOverTemplate = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/UI/BattleSceneUI/GameOverScreen.uxml");
#endif
            }
        }

        // Load panel settings if not assigned
        if (panelSettings == null)
        {
            panelSettings = Resources.Load<PanelSettings>("MainSettings");
            if (panelSettings == null)
            {
                // Try alternative panel settings
                panelSettings = Resources.Load<PanelSettings>("UI/TravelPanelSettings");
                if (panelSettings == null)
                {
                    // Try to find any PanelSettings in the project
                    var allPanelSettings = Resources.FindObjectsOfTypeAll<PanelSettings>();
                    if (allPanelSettings.Length > 0)
                        panelSettings = allPanelSettings[0];
                }
            }
        }

        // Configure the UIDocument
        if (uiDocument != null)
        {
            uiDocument.visualTreeAsset = gameOverTemplate;
            uiDocument.panelSettings = panelSettings;

            // Load and apply stylesheet
            var stylesheet = Resources.Load<StyleSheet>("UI/BattleSceneUI/GameOverScreen");
            if (stylesheet == null)
            {
#if UNITY_EDITOR
                stylesheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/UI/BattleSceneUI/GameOverScreen.uss");
#endif
            }
            if (stylesheet != null && uiDocument.rootVisualElement != null)
            {
                uiDocument.rootVisualElement.styleSheets.Add(stylesheet);
            }

            if (gameOverTemplate == null)
            {
                Debug.LogError("GameOverScreen: Could not load GameOverScreen.uxml template!");
            }

            if (panelSettings == null)
            {
                Debug.LogWarning("GameOverScreen: No PanelSettings found. UI may not display correctly.");
            }
        }
    }

    /// <summary>
    /// Set up UI element callbacks for the game over interface
    /// </summary>
    private void SetupUICallbacks()
    {
        if (rootElement == null) return;

        // Set up Restart Game button
        var restartButton = rootElement.Q<Button>("RestartButton");
        if (restartButton != null)
        {
            restartButton.clicked += RestartGame;
        }

        // Set up Main Menu button
        var mainMenuButton = rootElement.Q<Button>("MainMenuButton");
        if (mainMenuButton != null)
        {
            mainMenuButton.clicked += ReturnToMainMenu;
        }

        // Set up keyboard input for space key (restart)
        rootElement.RegisterCallback<KeyDownEvent>(OnKeyDown);

        // Make sure the root element can receive focus for keyboard events
        rootElement.focusable = true;
    }

    /// <summary>
    /// Handle keyboard input for the game over UI
    /// </summary>
    private void OnKeyDown(KeyDownEvent evt)
    {
        if (evt.keyCode == KeyCode.Space || evt.keyCode == KeyCode.Return)
        {
            RestartGame();
        }
        else if (evt.keyCode == KeyCode.Escape)
        {
            ReturnToMainMenu();
        }
    }

    /// <summary>
    /// Show the game over screen with current statistics
    /// </summary>
    public void ShowGameOver(List<GameObject> defeatedPlayers = null)
    {
        // Calculate final statistics
        CalculateFinalStatistics(defeatedPlayers);

        // Show the panel
        if (rootElement != null)
        {
            rootElement.style.display = DisplayStyle.Flex;
            rootElement.Focus(); // Allow keyboard input
            Time.timeScale = 0f; // Pause the game
        }

        // Update UI elements
        UpdateGameOverUI();

        // Play audio
        PlayGameOverAudio();

        Debug.Log("💀 Game Over screen displayed");
    }

    /// <summary>
    /// Calculate final statistics before showing game over
    /// </summary>
    private void CalculateFinalStatistics(List<GameObject> defeatedPlayers)
    {
        // Calculate total play time
        gameStats.totalPlayTime = Time.time;

        // Calculate characters lost
        if (defeatedPlayers != null)
        {
            gameStats.charactersLost = defeatedPlayers.Count;
        }

        // Try to get additional stats from game systems
        GatherStatisticsFromSystems();

        Debug.Log($"💀 Final statistics calculated - {gameStats.enemiesSlain} enemies slain, {gameStats.battlesWon} battles won");
    }

    /// <summary>
    /// Gather statistics from various game systems
    /// </summary>
    private void GatherStatisticsFromSystems()
    {
        // Try to get stats from GameManager if available
        var gameManager = GameManager.Instance;
        if (gameManager != null)
        {
            // Count enemies slain (this battle)
            var allEnemies = gameManager.enemyCharacters;
            gameStats.enemiesSlain += allEnemies.Count(enemy =>
            {
                var character = enemy?.GetComponent<Character>();
                return character != null && character.IsDead;
            });
        }

        // Try to get travel statistics
        GatherTravelStatistics();

        // Try to get combat statistics
        GatherCombatStatistics();

        // Try to get social statistics
        GatherSocialStatistics();
    }

    /// <summary>
    /// Gather travel-related statistics
    /// </summary>
    private void GatherTravelStatistics()
    {
        // TODO: Integrate with travel system when available
        // For now, use placeholder values
        gameStats.daysTravaeled = Mathf.RoundToInt(gameStats.totalPlayTime / 60f); // Rough estimate
        gameStats.locationsVisited = Random.Range(5, 15); // Placeholder
    }

    /// <summary>
    /// Gather combat-related statistics
    /// </summary>
    private void GatherCombatStatistics()
    {
        // TODO: Integrate with combat statistics system when available
        // For now, estimate based on current battle
        gameStats.battlesLost = 1; // This battle was lost
        gameStats.totalDamageDealt = Random.Range(50, 200); // Placeholder
        gameStats.totalDamageTaken = Random.Range(100, 300); // Placeholder
    }

    /// <summary>
    /// Gather social and quest statistics
    /// </summary>
    private void GatherSocialStatistics()
    {
        // TODO: Integrate with quest and social systems when available
        gameStats.peopleHelped = Random.Range(0, 5); // Placeholder
        gameStats.questsCompleted = Random.Range(0, 3); // Placeholder
        gameStats.questsFailed = Random.Range(0, 2); // Placeholder
        gameStats.finalFameLevel = Random.Range(1, 5); // Placeholder
    }

    /// <summary>
    /// Update the game over UI with statistics using UI Toolkit
    /// </summary>
    private void UpdateGameOverUI()
    {
        if (rootElement == null) return;

        // Update title
        var titleLabel = rootElement.Q<Label>("GameOverTitle");
        if (titleLabel != null)
        {
            titleLabel.text = "GAME OVER";
        }

        // Populate statistics sections
        PopulateStatisticsUI();
    }

    /// <summary>
    /// Populate all statistics sections in the UI
    /// </summary>
    private void PopulateStatisticsUI()
    {
        // Time & Travel Statistics
        PopulateTimeAndTravelStats();

        // Combat Statistics
        PopulateCombatStats();

        // Social & Quest Statistics
        PopulateSocialStats();

        // Assessment
        PopulateAssessment();
    }

    /// <summary>
    /// Populate time and travel statistics
    /// </summary>
    private void PopulateTimeAndTravelStats()
    {
        var playTimeLabel = rootElement.Q<Label>("PlayTimeValue");
        if (playTimeLabel != null)
            playTimeLabel.text = FormatTime(gameStats.totalPlayTime);

        var daysLabel = rootElement.Q<Label>("DaysTraveledValue");
        if (daysLabel != null)
            daysLabel.text = gameStats.daysTravaeled.ToString();

        var locationsLabel = rootElement.Q<Label>("LocationsVisitedValue");
        if (locationsLabel != null)
            locationsLabel.text = gameStats.locationsVisited.ToString();
    }

    /// <summary>
    /// Populate combat statistics
    /// </summary>
    private void PopulateCombatStats()
    {
        var battlesWonLabel = rootElement.Q<Label>("BattlesWonValue");
        if (battlesWonLabel != null)
            battlesWonLabel.text = gameStats.battlesWon.ToString();

        var battlesLostLabel = rootElement.Q<Label>("BattlesLostValue");
        if (battlesLostLabel != null)
            battlesLostLabel.text = gameStats.battlesLost.ToString();

        var winRateLabel = rootElement.Q<Label>("WinRateValue");
        if (winRateLabel != null)
            winRateLabel.text = $"{gameStats.GetWinRate():F1}%";

        var enemiesSlainLabel = rootElement.Q<Label>("EnemiesSlainValue");
        if (enemiesSlainLabel != null)
            enemiesSlainLabel.text = gameStats.enemiesSlain.ToString();

        var damageDealtLabel = rootElement.Q<Label>("DamageDealtValue");
        if (damageDealtLabel != null)
            damageDealtLabel.text = gameStats.totalDamageDealt.ToString();

        var damageTakenLabel = rootElement.Q<Label>("DamageTakenValue");
        if (damageTakenLabel != null)
            damageTakenLabel.text = gameStats.totalDamageTaken.ToString();

        var charactersLostLabel = rootElement.Q<Label>("CharactersLostValue");
        if (charactersLostLabel != null)
            charactersLostLabel.text = gameStats.charactersLost.ToString();
    }

    /// <summary>
    /// Populate social and quest statistics
    /// </summary>
    private void PopulateSocialStats()
    {
        var peopleHelpedLabel = rootElement.Q<Label>("PeopleHelpedValue");
        if (peopleHelpedLabel != null)
            peopleHelpedLabel.text = gameStats.peopleHelped.ToString();

        var livesSavedLabel = rootElement.Q<Label>("LivesSavedValue");
        if (livesSavedLabel != null)
            livesSavedLabel.text = gameStats.peopleSaved.ToString();

        var questsCompletedLabel = rootElement.Q<Label>("QuestsCompletedValue");
        if (questsCompletedLabel != null)
            questsCompletedLabel.text = gameStats.questsCompleted.ToString();

        var questsFailedLabel = rootElement.Q<Label>("QuestsFailedValue");
        if (questsFailedLabel != null)
            questsFailedLabel.text = gameStats.questsFailed.ToString();

        var fameLevelLabel = rootElement.Q<Label>("FameLevelValue");
        if (fameLevelLabel != null)
            fameLevelLabel.text = gameStats.finalFameLevel.ToString();

        var goldEarnedLabel = rootElement.Q<Label>("GoldEarnedValue");
        if (goldEarnedLabel != null)
            goldEarnedLabel.text = gameStats.totalGoldEarned.ToString();

        var goldSpentLabel = rootElement.Q<Label>("GoldSpentValue");
        if (goldSpentLabel != null)
            goldSpentLabel.text = gameStats.totalGoldSpent.ToString();

        var netWorthLabel = rootElement.Q<Label>("NetWorthValue");
        if (netWorthLabel != null)
            netWorthLabel.text = gameStats.GetNetGold().ToString();
    }

    /// <summary>
    /// Populate the final assessment section
    /// </summary>
    private void PopulateAssessment()
    {
        var assessmentLabel = rootElement.Q<Label>("AssessmentText");
        if (assessmentLabel != null)
            assessmentLabel.text = GetFinalMessage();
    }

    /// <summary>
    /// Generate the statistics text for display
    /// </summary>
    private string GenerateStatisticsText()
    {
        var stats = new System.Text.StringBuilder();

        stats.AppendLine("=== FINAL STATISTICS ===\n");

        // Time & Travel
        stats.AppendLine("📅 JOURNEY SUMMARY");
        stats.AppendLine($"Total Play Time: {FormatTime(gameStats.totalPlayTime)}");
        stats.AppendLine($"Days Traveled: {gameStats.daysTravaeled}");
        stats.AppendLine($"Locations Visited: {gameStats.locationsVisited}");
        stats.AppendLine();

        // Combat
        stats.AppendLine("⚔️ COMBAT RECORD");
        stats.AppendLine($"Battles Won: {gameStats.battlesWon}");
        stats.AppendLine($"Battles Lost: {gameStats.battlesLost}");
        stats.AppendLine($"Win Rate: {gameStats.GetWinRate():F1}%");
        stats.AppendLine($"Enemies Slain: {gameStats.enemiesSlain}");
        if (showDetailedStats)
        {
            stats.AppendLine($"Damage Dealt: {gameStats.totalDamageDealt}");
            stats.AppendLine($"Damage Taken: {gameStats.totalDamageTaken}");
        }
        stats.AppendLine();

        // Social & Quests
        stats.AppendLine("🤝 SOCIAL IMPACT");
        stats.AppendLine($"People Helped: {gameStats.peopleHelped}");
        stats.AppendLine($"Lives Saved: {gameStats.peopleSaved}");
        stats.AppendLine($"Quests Completed: {gameStats.questsCompleted}");
        stats.AppendLine($"Quests Failed: {gameStats.questsFailed}");
        stats.AppendLine($"Final Fame Level: {gameStats.finalFameLevel}");
        stats.AppendLine();

        // Character Development
        if (showDetailedStats)
        {
            stats.AppendLine("📈 CHARACTER GROWTH");
            stats.AppendLine($"Experience Gained: {gameStats.totalExperienceGained}");
            stats.AppendLine($"Levels Gained: {gameStats.levelsGained}");
            stats.AppendLine($"Characters Lost: {gameStats.charactersLost}");
            stats.AppendLine();
        }

        // Economic
        stats.AppendLine("💰 ECONOMIC SUMMARY");
        stats.AppendLine($"Gold Earned: {gameStats.totalGoldEarned}");
        stats.AppendLine($"Gold Spent: {gameStats.totalGoldSpent}");
        stats.AppendLine($"Net Worth: {gameStats.GetNetGold()}");

        // Final message
        stats.AppendLine();
        stats.AppendLine(GetFinalMessage());

        return stats.ToString();
    }

    /// <summary>
    /// Get a final message based on performance
    /// </summary>
    private string GetFinalMessage()
    {
        float winRate = gameStats.GetWinRate();
        int heroicScore = gameStats.peopleHelped + gameStats.peopleSaved + gameStats.questsCompleted;

        if (winRate >= 80f && heroicScore >= 10)
            return "You died as a legendary hero, remembered for ages!";
        else if (winRate >= 60f && heroicScore >= 5)
            return "You fought valiantly and helped many before falling.";
        else if (gameStats.enemiesSlain >= 10)
            return "Though you fell, your enemies remember your fierce combat.";
        else if (heroicScore >= 3)
            return "Your kind deeds will be remembered by those you helped.";
        else if (gameStats.daysTravaeled >= 10)
            return "You traveled far but met an unfortunate end.";
        else
            return "Your adventure was brief but not without purpose.";
    }

    /// <summary>
    /// Format time in minutes and seconds
    /// </summary>
    private string FormatTime(float timeInSeconds)
    {
        int minutes = Mathf.FloorToInt(timeInSeconds / 60f);
        int seconds = Mathf.FloorToInt(timeInSeconds % 60f);
        return $"{minutes:D2}:{seconds:D2}";
    }

    /// <summary>
    /// Play game over audio
    /// </summary>
    private void PlayGameOverAudio()
    {
        var audioSource = GetComponent<AudioSource>();
        if (audioSource != null)
        {
            if (defeatSound != null)
            {
                audioSource.PlayOneShot(defeatSound);
            }

            if (gameOverMusic != null)
            {
                audioSource.clip = gameOverMusic;
                audioSource.loop = true;
                audioSource.Play();
            }
        }
    }

    /// <summary>
    /// Restart the game
    /// </summary>
    private void RestartGame()
    {
        Time.timeScale = 1f; // Resume time
        Debug.Log("💀 Restarting game...");

        // TODO: Implement proper game restart logic
        // For now, reload the current scene
        UnityEngine.SceneManagement.SceneManager.LoadScene(
            UnityEngine.SceneManagement.SceneManager.GetActiveScene().name
        );
    }

    /// <summary>
    /// Return to main menu
    /// </summary>
    private void ReturnToMainMenu()
    {
        Time.timeScale = 1f; // Resume time
        Debug.Log("💀 Returning to main menu...");

        // TODO: Load main menu scene
        // For now, just hide the game over screen
        if (rootElement != null)
            rootElement.style.display = DisplayStyle.None;
    }

    /// <summary>
    /// Hide the game over screen (for testing)
    /// </summary>
    public void HideGameOver()
    {
        if (rootElement != null)
            rootElement.style.display = DisplayStyle.None;
        Time.timeScale = 1f;
    }

    /// <summary>
    /// Update a specific statistic
    /// </summary>
    public void UpdateStatistic(string statName, int value)
    {
        switch (statName.ToLower())
        {
            case "enemiesslain":
                gameStats.enemiesSlain += value;
                break;
            case "battlewon":
                gameStats.battlesWon += value;
                break;
            case "battleslost":
                gameStats.battlesLost += value;
                break;
            case "peoplehelped":
                gameStats.peopleHelped += value;
                break;
            case "questscompleted":
                gameStats.questsCompleted += value;
                break;
            case "goldearned":
                gameStats.totalGoldEarned += value;
                break;
            default:
                Debug.LogWarning($"Unknown statistic: {statName}");
                break;
        }
    }

    /// <summary>
    /// Get current statistics (for external access)
    /// </summary>
    public GameStatistics GetStatistics()
    {
        return gameStats;
    }
}
