using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// UI controller for the Adventurer's Guild interface
/// </summary>
public class AdventurersGuildUI : MonoBehaviour
{
    [Header("UI References")]
    [SerializeField] private UIDocument uiDocument;

    [Header("Guild Reference")]
    [SerializeField] private AdventurersGuild guild;

    private VisualElement root;
    private VisualElement questBoardPanel;
    private VisualElement activeQuestsPanel;
    private VisualElement questHistoryPanel;
    private VisualElement questDetailsPanel;

    private ScrollView questBoardList;
    private ScrollView activeQuestsList;
    private ScrollView questHistoryList;

    private Button questBoardTab;
    private Button activeQuestsTab;
    private Button questHistoryTab;

    private Label renownLabel;
    private Label questCountLabel;
    private Label historyStatsLabel;

    private Quest selectedQuest;
    private ActiveQuest selectedActiveQuest;

    private void Start()
    {
        InitializeUI();
        SetupEventListeners();
        ShowQuestBoard();
    }

    private void OnEnable()
    {
        if (QuestManager.Instance != null)
        {
            QuestManager.Instance.OnQuestAccepted += OnQuestAccepted;
            QuestManager.Instance.OnQuestCompleted += OnQuestCompleted;
            QuestManager.Instance.OnQuestFailed += OnQuestFailed;
            QuestManager.Instance.OnRenownChanged += OnRenownChanged;
        }
    }

    private void OnDisable()
    {
        if (QuestManager.Instance != null)
        {
            QuestManager.Instance.OnQuestAccepted -= OnQuestAccepted;
            QuestManager.Instance.OnQuestCompleted -= OnQuestCompleted;
            QuestManager.Instance.OnQuestFailed -= OnQuestFailed;
            QuestManager.Instance.OnRenownChanged -= OnRenownChanged;
        }
    }

    private void InitializeUI()
    {
        if (uiDocument == null)
            uiDocument = GetComponent<UIDocument>();

        root = uiDocument.rootVisualElement;

        // Get panel references
        questBoardPanel = root.Q("QuestBoardPanel");
        activeQuestsPanel = root.Q("ActiveQuestsPanel");
        questHistoryPanel = root.Q("QuestHistoryPanel");
        questDetailsPanel = root.Q("QuestDetailsPanel");

        // Get list references
        questBoardList = root.Q<ScrollView>("QuestBoardList");
        activeQuestsList = root.Q<ScrollView>("ActiveQuestsList");
        questHistoryList = root.Q<ScrollView>("QuestHistoryList");

        // Get tab references
        questBoardTab = root.Q<Button>("QuestBoardTab");
        activeQuestsTab = root.Q<Button>("ActiveQuestsTab");
        questHistoryTab = root.Q<Button>("QuestHistoryTab");

        // Get label references
        renownLabel = root.Q<Label>("RenownLabel");
        questCountLabel = root.Q<Label>("QuestCountLabel");
        historyStatsLabel = root.Q<Label>("HistoryStatsLabel");

        // Find guild if not assigned
        if (guild == null)
            guild = FindFirstObjectByType<AdventurersGuild>();

        UpdateRenownDisplay();
    }

    private void SetupEventListeners()
    {
        // Tab navigation
        questBoardTab?.RegisterCallback<ClickEvent>(evt => ShowTab("QuestBoard"));
        activeQuestsTab?.RegisterCallback<ClickEvent>(evt => ShowTab("ActiveQuests"));
        questHistoryTab?.RegisterCallback<ClickEvent>(evt => ShowTab("QuestHistory"));

        // Close button
        var closeButton = root.Q<Button>("CloseButton");
        closeButton?.RegisterCallback<ClickEvent>(evt => CloseGuild());

        // Action buttons
        var refreshButton = root.Q<Button>("RefreshBoardButton");
        refreshButton?.RegisterCallback<ClickEvent>(evt =>
        {
            // Refresh the guild board first, then the UI
            if (guild != null)
            {
                guild.RefreshQuestBoard();
            }
            RefreshQuestBoard();
        });

        var acceptButton = root.Q<Button>("AcceptQuestButton");
        acceptButton?.RegisterCallback<ClickEvent>(evt => AcceptSelectedQuest());

        var abandonButton = root.Q<Button>("AbandonQuestButton");
        abandonButton?.RegisterCallback<ClickEvent>(evt => AbandonSelectedQuest());
    }

    private void ShowTab(string tabName)
    {
        // Hide all panels
        questBoardPanel.AddToClassList("hidden");
        activeQuestsPanel.AddToClassList("hidden");
        questHistoryPanel.AddToClassList("hidden");

        // Remove active class from all tabs
        questBoardTab.RemoveFromClassList("active-tab");
        activeQuestsTab.RemoveFromClassList("active-tab");
        questHistoryTab.RemoveFromClassList("active-tab");

        // Show selected panel and mark tab as active
        switch (tabName)
        {
            case "QuestBoard":
                questBoardPanel.RemoveFromClassList("hidden");
                questBoardTab.AddToClassList("active-tab");
                RefreshQuestBoard();
                break;
            case "ActiveQuests":
                activeQuestsPanel.RemoveFromClassList("hidden");
                activeQuestsTab.AddToClassList("active-tab");
                RefreshActiveQuests();
                break;
            case "QuestHistory":
                questHistoryPanel.RemoveFromClassList("hidden");
                questHistoryTab.AddToClassList("active-tab");
                RefreshQuestHistory();
                break;
        }

        CloseQuestDetails();
    }

    private void RefreshQuestBoard()
    {
        if (guild == null || questBoardList == null) return;

        questBoardList.Clear();

        var questBoard = guild.GetQuestBoard();
        if (questBoard.Count == 0)
        {
            // Try to refresh the board first
            guild.RefreshQuestBoard();
            questBoard = guild.GetQuestBoard();
            
            if (questBoard.Count == 0)
            {
                var placeholder = new Label("No quests available. Check back later!");
                placeholder.AddToClassList("placeholder-text");
                questBoardList.Add(placeholder);
                
                // Add a button to create a test quest for debugging
                var debugButton = new Button(() => CreateDebugQuest()) { text = "🔧 Create Test Quest (Debug)" };
                debugButton.AddToClassList("debug-button");
                questBoardList.Add(debugButton);
                return;
            }
        }

        // Add helpful instructions at the top
        if (questBoard.Count > 0)
        {
            var instructions = new Label("💡 Click on any quest below to view details and accept it!");
            instructions.AddToClassList("instructions-text");
            questBoardList.Add(instructions);
        }

        foreach (var quest in questBoard)
        {
            var questEntry = CreateQuestEntry(quest);
            questBoardList.Add(questEntry);
        }
    }    private void CreateDebugQuest()
    {
        if (guild == null) return;

        var debugQuest = ScriptableObject.CreateInstance<Quest>();
        debugQuest.questTitle = "Test Quest - Goblin Patrol";
        debugQuest.questDescription = "A group of goblins has been spotted near the village. Clear them out to protect the trade routes.";
        debugQuest.questType = QuestType.Combat;
        debugQuest.difficulty = QuestDifficulty.Easy;
        debugQuest.timeLimitDays = 7;
        debugQuest.targetAreaName = "Forest Edge";
        debugQuest.targetMapPosition = new Vector2Int(45, 55);
        debugQuest.goldReward = 75;
        debugQuest.renownReward = 10;
        debugQuest.minimumRenown = 0; // No requirements for testing

        debugQuest.goals.Add(new QuestGoal
        {
            description = "Defeat 5 Goblins",
            goalType = QuestGoalType.KillEnemies,
            targetName = "Goblin",
            targetCount = 5
        });

        // Add to guild's available quests and refresh
        var availableQuests = new System.Collections.Generic.List<Quest>();
        var currentBoard = guild.GetQuestBoard();
        availableQuests.AddRange(currentBoard);
        availableQuests.Add(debugQuest);

        // Use reflection or a public method to add the quest
        // For now, just force it into the board via the guild's debug method
        Debug.Log("✅ Created debug quest. Use the guild's 'Create Simple Test Quest' context menu to add it properly.");

        // Refresh the UI
        RefreshQuestBoard();
    }

    private void RefreshActiveQuests()
    {
        if (QuestManager.Instance == null || activeQuestsList == null) return;

        activeQuestsList.Clear();

        var activeQuests = QuestManager.Instance.GetActiveQuests();
        questCountLabel.text = $"{activeQuests.Count}/{QuestManager.Instance.maxActiveQuests} Quests";

        if (activeQuests.Count == 0)
        {
            var placeholder = new Label("No active quests.");
            placeholder.AddToClassList("placeholder-text");
            activeQuestsList.Add(placeholder);
            return;
        }

        foreach (var activeQuest in activeQuests)
        {
            var questEntry = CreateActiveQuestEntry(activeQuest);
            activeQuestsList.Add(questEntry);
        }
    }

    private void RefreshQuestHistory()
    {
        // TODO: Implement quest history display
        questHistoryList.Clear();

        var placeholder = new Label("Quest history not yet implemented.");
        placeholder.AddToClassList("placeholder-text");
        questHistoryList.Add(placeholder);

        historyStatsLabel.text = "Completed: 0 | Failed: 0";
    }

    private VisualElement CreateQuestEntry(Quest quest)
    {
        var entry = new VisualElement();
        entry.AddToClassList("quest-list-item");
        entry.AddToClassList("clickable-quest"); // New class for better styling
        
        // Add a hover effect to make it clear it's clickable
        entry.RegisterCallback<MouseEnterEvent>(evt => entry.AddToClassList("quest-hover"));
        entry.RegisterCallback<MouseLeaveEvent>(evt => entry.RemoveFromClassList("quest-hover"));

        // Header with title and difficulty badge
        var header = new VisualElement();
        header.AddToClassList("quest-item-header");

        var titleContainer = new VisualElement();
        titleContainer.AddToClassList("quest-title-container");
        
        var title = new Label(quest.questTitle);
        title.AddToClassList("quest-item-title");
        
        var clickHint = new Label("📋 Click to view details");
        clickHint.AddToClassList("quest-click-hint");
        
        titleContainer.Add(title);
        titleContainer.Add(clickHint);

        var difficulty = new Label(quest.difficulty.ToString().ToUpper());
        difficulty.AddToClassList("quest-item-difficulty");
        difficulty.AddToClassList($"difficulty-{quest.difficulty.ToString().ToLower()}");

        header.Add(titleContainer);
        header.Add(difficulty);

        // Description (truncated)
        var description = new Label(TruncateText(quest.questDescription, 100));
        description.AddToClassList("quest-item-description");

        // Key info row
        var infoRow = new VisualElement();
        infoRow.AddToClassList("quest-info-row");
        
        var location = new Label($"📍 {quest.targetAreaName}");
        location.AddToClassList("quest-info-item");
        
        var timeLimit = new Label($"⏰ {quest.timeLimitDays}d {quest.timeLimitHours}h");
        timeLimit.AddToClassList("quest-info-item");
        
        infoRow.Add(location);
        infoRow.Add(timeLimit);

        // Rewards container - made more prominent
        var rewardsContainer = new VisualElement();
        rewardsContainer.AddToClassList("quest-item-rewards");
        
        var rewardsLabel = new Label("Rewards:");
        rewardsLabel.AddToClassList("rewards-label");
        rewardsContainer.Add(rewardsLabel);
        
        var rewardsContent = new VisualElement();
        rewardsContent.AddToClassList("rewards-content");

        if (quest.goldReward > 0)
        {
            var goldReward = new Label($"💰 {quest.goldReward} Gold");
            goldReward.AddToClassList("quest-item-reward");
            goldReward.AddToClassList("reward-gold");
            rewardsContent.Add(goldReward);
        }

        if (quest.renownReward > 0)
        {
            var renownReward = new Label($"⭐ +{quest.renownReward} Renown");
            renownReward.AddToClassList("quest-item-reward");
            renownReward.AddToClassList("reward-renown");
            rewardsContent.Add(renownReward);
        }
        
        rewardsContainer.Add(rewardsContent);

        // Requirements
        if (quest.minimumRenown > 0)
        {
            var requirements = new Label($"⚡ Requires {quest.minimumRenown} Renown");
            requirements.AddToClassList("quest-requirements");
            rewardsContainer.Add(requirements);
        }

        // Assemble the entry
        entry.Add(header);
        entry.Add(description);
        entry.Add(infoRow);
        entry.Add(rewardsContainer);

        // Click handler to select quest and show details
        entry.RegisterCallback<ClickEvent>(evt =>
        {
            // Remove selection from all quest items
            foreach (var child in questBoardList.Children())
            {
                child.RemoveFromClassList("selected");
            }

            // Select this item
            entry.AddToClassList("selected");
            ShowQuestDetails(quest);
        });

        return entry;
    }
    
    private string TruncateText(string text, int maxLength)
    {
        if (string.IsNullOrEmpty(text) || text.Length <= maxLength)
            return text;
        
        return text.Substring(0, maxLength - 3) + "...";
    }

    private VisualElement CreateActiveQuestEntry(ActiveQuest activeQuest)
    {
        var entry = CreateQuestEntry(activeQuest.questData);

        // Add urgency indicator
        var urgency = activeQuest.GetUrgency();
        entry.AddToClassList($"urgency-{urgency.ToString().ToLower()}");

        // Update time display to show remaining time
        var timeLabel = entry.Q<Label>(className: "quest-entry-time");
        if (timeLabel != null)
        {
            timeLabel.text = $"⏰ {activeQuest.GetTimeRemainingString()}";
        }

        // Add progress info
        var progressLabel = new Label($"Progress: {activeQuest.GetOverallProgress() * 100:F0}%");
        progressLabel.style.color = Color.cyan;
        progressLabel.style.fontSize = 12;
        entry.Add(progressLabel);

        // Click handler for active quest
        entry.RegisterCallback<ClickEvent>(evt => ShowActiveQuestDetails(activeQuest));

        return entry;
    }

    private void ShowQuestDetails(Quest quest)
    {
        selectedQuest = quest;
        selectedActiveQuest = null;

        // Show quest info container and hide placeholder
        var questInfoContainer = root.Q("QuestInfoContainer");
        var placeholder = root.Q("QuestDetailsText");

        questInfoContainer?.RemoveFromClassList("hidden");
        placeholder?.AddToClassList("hidden");

        // Populate the details with null checks
        try
        {
            PopulateQuestDetails(quest);
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"Error populating quest details: {ex.Message}");
            
            // Fallback - show basic info
            var title = root.Q<Label>("QuestTitle");
            if (title != null) title.text = quest?.questTitle ?? "Unknown Quest";
            
            var description = root.Q<Label>("QuestDescription");
            if (description != null) description.text = quest?.questDescription ?? "Quest details unavailable.";
        }

        // Show/hide appropriate buttons
        var acceptButton = root.Q<Button>("AcceptQuestButton");
        var abandonButton = root.Q<Button>("AbandonQuestButton");

        if (acceptButton != null)
        {
            acceptButton.RemoveFromClassList("hidden");
            acceptButton.AddToClassList("accept-button");
            acceptButton.AddToClassList("action-button");
        }
        
        if (abandonButton != null)
        {
            abandonButton.AddToClassList("hidden");
        }
    }

    private void CloseGuild()
    {
        // Destroy the guild UI GameObject
        if (gameObject != null)
        {
            Destroy(gameObject);
        }
    }

    private void ShowActiveQuestDetails(ActiveQuest activeQuest)
    {
        selectedQuest = null;
        selectedActiveQuest = activeQuest;

        questDetailsPanel.RemoveFromClassList("hidden");

        PopulateQuestDetails(activeQuest.questData, activeQuest);

        // Show/hide appropriate buttons
        root.Q<Button>("AcceptQuestButton").AddToClassList("hidden");
        root.Q<Button>("AbandonQuestButton").RemoveFromClassList("hidden");
        root.Q<Button>("TrackQuestButton").RemoveFromClassList("hidden");
    }

    private void PopulateQuestDetails(Quest quest, ActiveQuest activeQuest = null)
    {
        if (quest == null) return;

        // Basic info - with null checks
        var questTitle = root.Q<Label>("QuestTitle");
        if (questTitle != null) questTitle.text = quest.questTitle;
        
        var questDifficulty = root.Q<Label>("QuestDifficulty");
        if (questDifficulty != null) questDifficulty.text = $"Difficulty: {quest.difficulty}";

        var questTimeLimit = root.Q<Label>("QuestTimeLimit");
        if (questTimeLimit != null)
        {
            if (activeQuest != null)
            {
                questTimeLimit.text = $"Time Remaining: {activeQuest.GetTimeRemainingString()}";
            }
            else
            {
                questTimeLimit.text = $"Time Limit: {quest.timeLimitDays}d {quest.timeLimitHours}h";
            }
        }

        // Description
        var questDescription = root.Q<Label>("QuestDescription");
        if (questDescription != null) questDescription.text = quest.questDescription;

        // Objectives
        var objectivesList = root.Q("ObjectivesList");
        if (objectivesList != null)
        {
            objectivesList.Clear();

            var goalsToShow = activeQuest?.activeGoals ?? quest.goals;
            foreach (var goal in goalsToShow)
            {
                if (goal.isHidden && activeQuest == null) continue;

                var objectiveItem = new VisualElement();
                objectiveItem.AddToClassList("objective-item");

                var status = new VisualElement();
                status.AddToClassList("objective-status");
                if (goal.IsCompleted)
                    status.AddToClassList("objective-completed");

                var text = new Label(goal.description);
                text.AddToClassList("objective-text");

                if (activeQuest != null)
                {
                    text.text += $" ({goal.currentProgress}/{goal.targetCount})";
                }

                objectiveItem.Add(status);
                objectiveItem.Add(text);
                objectivesList.Add(objectiveItem);
            }
        }

        // Location
        var questLocation = root.Q<Label>("QuestLocation");
        if (questLocation != null) questLocation.text = $"Target Area: {quest.targetAreaName}";

        // Calculate travel time if we have current position
        var travelTime = quest.CalculateTravelTime(new Vector2Int(50, 50)); // Placeholder position
        var travelTimeLabel = root.Q<Label>("TravelTime");
        if (travelTimeLabel != null) travelTimeLabel.text = $"Travel Time: ~{travelTime:F1} hours";

        // Rewards
        var goldReward = root.Q<Label>("GoldReward");
        if (goldReward != null) goldReward.text = $"💰 Gold: {quest.goldReward}";
        
        var renownReward = root.Q<Label>("RenownReward");
        if (renownReward != null) renownReward.text = $"⭐ Renown: +{quest.renownReward}";

        var itemRewardsList = root.Q("ItemRewardsList");
        if (itemRewardsList != null)
        {
            itemRewardsList.Clear();
            foreach (var itemName in quest.itemRewards)
            {
                var itemLabel = new Label($"🎁 {itemName}");
                itemLabel.AddToClassList("reward-item");
                itemRewardsList.Add(itemLabel);
            }
        }
    }

    private void CloseQuestDetails()
    {
        questDetailsPanel.AddToClassList("hidden");
        selectedQuest = null;
        selectedActiveQuest = null;
    }

    private void AcceptSelectedQuest()
    {
        if (selectedQuest == null || guild == null) return;

        bool accepted = guild.AcceptQuest(selectedQuest);
        if (accepted)
        {
            CloseQuestDetails();
            RefreshQuestBoard();
            ShowTab("ActiveQuests");
        }
    }

    private void AbandonSelectedQuest()
    {
        if (selectedActiveQuest == null || QuestManager.Instance == null) return;

        bool abandoned = QuestManager.Instance.AbandonQuest(selectedActiveQuest.questId);
        if (abandoned)
        {
            CloseQuestDetails();
            RefreshActiveQuests();
        }
    }

    private void TrackSelectedQuest()
    {
        if (selectedActiveQuest == null) return;

        // TODO: Implement quest tracking on map
        Debug.Log($"Tracking quest: {selectedActiveQuest.questData.questTitle}");
        CloseQuestDetails();
    }

    private void UpdateRenownDisplay()
    {
        if (renownLabel != null && QuestManager.Instance != null)
        {
            renownLabel.text = $"Renown: {QuestManager.Instance.GetRenown()}";
        }
    }

    private void ShowQuestBoard()
    {
        ShowTab("QuestBoard");
    }

    // Event handlers
    private void OnQuestAccepted(ActiveQuest quest)
    {
        RefreshQuestBoard();
        RefreshActiveQuests();
    }

    private void OnQuestCompleted(ActiveQuest quest, List<QuestReward> rewards)
    {
        RefreshActiveQuests();
        RefreshQuestHistory();
    }

    private void OnQuestFailed(ActiveQuest quest)
    {
        RefreshActiveQuests();
        RefreshQuestHistory();
    }

    private void OnRenownChanged(int newRenown)
    {
        UpdateRenownDisplay();
    }

    // Debug methods
    [ContextMenu("Force Refresh UI")]
    private void DebugForceRefreshUI()
    {
        if (guild != null)
        {
            guild.RefreshQuestBoard();
        }
        RefreshQuestBoard();
        RefreshActiveQuests();
        RefreshQuestHistory();
        Debug.Log("🔄 Forced UI refresh complete");
    }

    [ContextMenu("Debug Guild Connection")]
    private void DebugGuildConnection()
    {
        Debug.Log($"Guild reference: {(guild != null ? "✅ Found" : "❌ NULL")}");
        Debug.Log($"QuestManager: {(QuestManager.Instance != null ? "✅ Found" : "❌ NULL")}");

        if (guild != null)
        {
            var questBoard = guild.GetQuestBoard();
            Debug.Log($"Quest Board: {questBoard.Count} quests");
        }
    }
}
