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

/// <summary>
/// Manages the Adventurer's Guild - quest board, quest generation, and guild services
/// </summary>
public class AdventurersGuild : MonoBehaviour
{
    [Header("Guild Configuration")]
    [Tooltip("Maximum number of quests on the board")]
    public int maxQuestBoardSize = 8;

    [Tooltip("How often new quests are added (in game hours)")]
    public float questRefreshRate = 24f;

    [Header("Available Quests")]
    [SerializeField] private List<Quest> availableQuests = new List<Quest>();
    [SerializeField] private List<Quest> questBoard = new List<Quest>();

    [Header("Guild Services")]
    [Tooltip("Can abandon quests here")]
    public bool allowQuestAbandonment = true;

    [Tooltip("Can view completed quest history")]
    public bool showQuestHistory = true;

    [Header("Debug")]
    public bool enableDebugLogs = true;

    private float timeSinceLastRefresh = 0f;

    private void Start()
    {
        // Wait a frame to ensure QuestManager is initialized
        StartCoroutine(InitializeGuild());
    }

    private System.Collections.IEnumerator InitializeGuild()
    {
        yield return null; // Wait one frame

        // Ensure QuestManager exists
        if (QuestManager.Instance == null)
        {
            var questManagerObject = new GameObject("QuestManager");
            questManagerObject.AddComponent<QuestManager>();
            if (enableDebugLogs)
                Debug.Log("✅ AdventurersGuild created QuestManager instance");
        }

        LoadAvailableQuests();
        RefreshQuestBoard();

        if (enableDebugLogs)
            Debug.Log($"🏛️ AdventurersGuild initialized with {availableQuests.Count} available quests");
    }

    private void Update()
    {
        // Auto-refresh quest board periodically
        if (QuestManager.Instance != null)
        {
            timeSinceLastRefresh += Time.deltaTime * QuestManager.Instance.gameTimeSpeed;
            if (timeSinceLastRefresh >= questRefreshRate)
            {
                RefreshQuestBoard();
                timeSinceLastRefresh = 0f;
            }
        }
    }

    /// <summary>
    /// Load all available quests from Resources folder
    /// </summary>
    private void LoadAvailableQuests()
    {
        availableQuests.Clear();
        LogDebug("🔍 Starting quest loading process...");

        // First, try to load quests from specific subfolders
        var combatQuests = Resources.LoadAll<Quest>("Quests/Combat");
        var rescueQuests = Resources.LoadAll<Quest>("Quests/Rescue");
        var retrievalQuests = Resources.LoadAll<Quest>("Quests/Retrieval");
        var explorationQuests = Resources.LoadAll<Quest>("Quests/Exploration");

        LogDebug($"📁 Found quests in subfolders: Combat={combatQuests.Length}, Rescue={rescueQuests.Length}, Retrieval={retrievalQuests.Length}, Exploration={explorationQuests.Length}");

        availableQuests.AddRange(combatQuests);
        availableQuests.AddRange(rescueQuests);
        availableQuests.AddRange(retrievalQuests);
        availableQuests.AddRange(explorationQuests);

        // Also load any quests directly in the Quests folder
        var allQuests = Resources.LoadAll<Quest>("Quests");
        LogDebug($"📁 Found {allQuests.Length} quests in main Quests folder");
        
        foreach (var quest in allQuests)
        {
            if (quest != null)
            {
                LogDebug($"  - Found quest: {quest.name} ({quest.questTitle})");
                if (!availableQuests.Contains(quest))
                {
                    availableQuests.Add(quest);
                    LogDebug($"    ✅ Added to available quests");
                }
                else
                {
                    LogDebug($"    ⚠️ Already in list, skipping");
                }
            }
            else
            {
                LogDebug($"  - ❌ Found NULL quest in Resources/Quests");
            }
        }

        // Finally, load any quests from the root Resources folder
        var rootQuests = Resources.LoadAll<Quest>("");
        foreach (var quest in rootQuests)
        {
            if (!availableQuests.Contains(quest))
            {
                availableQuests.Add(quest);
            }
        }

        LogDebug($"📚 Loaded {availableQuests.Count} available quests");

        // If no quests found, create some default ones
        if (availableQuests.Count == 0)
        {
            LogDebug("⚠️ No quests found in Resources. Creating default quests...");
            CreateDefaultQuests();
        }

        if (enableDebugLogs && availableQuests.Count > 0)
        {
            Debug.Log("📋 Available quests:");
            foreach (var quest in availableQuests)
            {
                Debug.Log($"  - {quest.questTitle} ({quest.name})");
            }
        }
    }

    /// <summary>
    /// Create default quests if none are found in Resources
    /// </summary>
    private void CreateDefaultQuests()
    {
        LogDebug("Creating default starter quests...");

        var starterQuest = ScriptableObject.CreateInstance<Quest>();
        starterQuest.questTitle = "Goblin Trouble";
        starterQuest.questDescription = "Goblins have been spotted near the village outskirts. Deal with them before they cause real trouble.";
        starterQuest.questType = QuestType.Combat;
        starterQuest.difficulty = QuestDifficulty.Easy;
        starterQuest.timeLimitDays = 7;
        starterQuest.targetAreaName = "Village Outskirts";
        starterQuest.targetMapPosition = new Vector2Int(45, 55);
        starterQuest.goldReward = 50;
        starterQuest.renownReward = 5;
        starterQuest.minimumRenown = 0; // Available to all players

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

        availableQuests.Add(starterQuest);

        var deliveryQuest = ScriptableObject.CreateInstance<Quest>();
        deliveryQuest.questTitle = "Message Delivery";
        deliveryQuest.questDescription = "The village elder needs an important message delivered to the neighboring settlement.";
        deliveryQuest.questType = QuestType.Delivery;
        deliveryQuest.difficulty = QuestDifficulty.Easy;
        deliveryQuest.timeLimitDays = 5;
        deliveryQuest.targetAreaName = "Nearby Settlement";
        deliveryQuest.targetMapPosition = new Vector2Int(60, 40);
        deliveryQuest.goldReward = 40;
        deliveryQuest.renownReward = 3;
        deliveryQuest.minimumRenown = 0;

        deliveryQuest.goals.Add(new QuestGoal
        {
            description = "Deliver message to Settlement Leader",
            goalType = QuestGoalType.ReachLocation,
            targetName = "Settlement",
            targetCount = 1
        });

        availableQuests.Add(deliveryQuest);

        LogDebug($"✅ Created {availableQuests.Count} default quests");
    }

    /// <summary>
    /// Refresh the quest board with new available quests
    /// </summary>
    public void RefreshQuestBoard()
    {
        questBoard.Clear();

        if (availableQuests.Count == 0)
        {
            LogDebug("⚠️ No available quests to populate quest board");
            return;
        }

        // Filter quests based on current renown and prerequisites
        var eligibleQuests = availableQuests.Where(q => IsQuestEligible(q)).ToList();

        // Randomly select quests for the board
        var questsToAdd = Mathf.Min(maxQuestBoardSize, eligibleQuests.Count);
        var selectedQuests = eligibleQuests.OrderBy(x => Random.value).Take(questsToAdd);

        questBoard.AddRange(selectedQuests);

        LogDebug($"🗂️ Quest board refreshed: {questBoard.Count} quests available");
    }

    /// <summary>
    /// Check if a quest is eligible for the current party
    /// </summary>
    private bool IsQuestEligible(Quest quest)
    {
        if (quest == null) return false;

        var questManager = QuestManager.Instance;
        if (questManager == null) return false;

        // Check renown requirement
        if (questManager.GetRenown() < quest.minimumRenown)
            return false;

        // Check if already have this quest active
        var activeQuests = questManager.GetActiveQuests();
        if (activeQuests.Any(aq => aq.questData == quest))
            return false;

        // Check prerequisites (simplified - just check if we've completed them)
        // In a full implementation, you'd check the QuestManager's completed quests

        return true;
    }

    /// <summary>
    /// Accept a quest from the guild board
    /// </summary>
    public bool AcceptQuest(Quest quest)
    {
        if (quest == null || !questBoard.Contains(quest))
        {
            LogDebug("❌ Cannot accept quest: not available on board");
            return false;
        }

        var questManager = QuestManager.Instance;
        if (questManager == null)
        {
            LogDebug("❌ QuestManager not found");
            return false;
        }

        if (!questManager.CanAcceptMoreQuests())
        {
            LogDebug("❌ Cannot accept more quests");
            return false;
        }

        bool accepted = questManager.AcceptQuest(quest);
        if (accepted)
        {
            // Remove from board (could be optional - some quests might be repeatable)
            questBoard.Remove(quest);
            LogDebug($"✅ Accepted quest from guild: {quest.questTitle}");
        }

        return accepted;
    }

    /// <summary>
    /// Get all quests currently on the board
    /// </summary>
    public List<Quest> GetQuestBoard() => new List<Quest>(questBoard);

    /// <summary>
    /// Generate a random quest based on current area/difficulty
    /// </summary>
    public Quest GenerateRandomQuest(Vector2Int nearPosition, QuestDifficulty targetDifficulty = QuestDifficulty.Normal)
    {
        // This would be used for dynamic quest generation
        // For now, just return a random quest from available ones
        var eligibleQuests = availableQuests.Where(q =>
            q.difficulty == targetDifficulty && IsQuestEligible(q)).ToList();

        if (eligibleQuests.Count == 0) return null;

        var randomQuest = eligibleQuests[Random.Range(0, eligibleQuests.Count)];

        // Modify the quest position to be near the requested position
        var questCopy = Object.Instantiate(randomQuest);
        questCopy.targetMapPosition = nearPosition + new Vector2Int(
            Random.Range(-10, 11), Random.Range(-10, 11));

        return questCopy;
    }

    /// <summary>
    /// Get quest recommendations based on party strength/renown
    /// </summary>
    public List<Quest> GetRecommendedQuests(int count = 3)
    {
        var questManager = QuestManager.Instance;
        if (questManager == null) return new List<Quest>();

        int renown = questManager.GetRenown();

        // Recommend quests slightly above and below current renown level
        var recommended = questBoard.Where(q =>
            q.minimumRenown <= renown + 10 && q.minimumRenown >= renown - 5)
            .OrderBy(q => Mathf.Abs(q.minimumRenown - renown))
            .Take(count)
            .ToList();

        return recommended;
    }

    /// <summary>
    /// Calculate travel time to quest location from current position
    /// </summary>
    public float CalculateTravelTimeToQuest(Quest quest, Vector2Int currentPosition)
    {
        if (quest == null) return 0f;

        return quest.CalculateTravelTime(currentPosition);
    }

    private void LogDebug(string message)
    {
        if (enableDebugLogs)
        {
            Debug.Log($"[AdventurersGuild] {message}");
        }
    }

    #region Context Menu Debug Methods
    [ContextMenu("Refresh Quest Board")]
    private void DebugRefreshQuestBoard()
    {
        RefreshQuestBoard();
    }

    [ContextMenu("List Available Quests")]
    private void DebugListAvailableQuests()
    {
        LogDebug($"Available Quests ({availableQuests.Count}):");
        foreach (var quest in availableQuests)
        {
            LogDebug($"  - {quest.questTitle} (Difficulty: {quest.difficulty}, Renown: {quest.minimumRenown})");
        }
    }

    [ContextMenu("List Quest Board")]
    private void DebugListQuestBoard()
    {
        LogDebug($"Quest Board ({questBoard.Count}):");
        foreach (var quest in questBoard)
        {
            LogDebug($"  - {quest.questTitle} (Reward: {quest.goldReward}g, Time: {quest.timeLimitDays}d)");
        }
    }

    [ContextMenu("Force Load Quests")]
    private void DebugForceLoadQuests()
    {
        LoadAvailableQuests();
        LogDebug($"Forced quest loading complete. Found {availableQuests.Count} quests.");
    }

    [ContextMenu("Check Quest Eligibility")]
    private void DebugCheckQuestEligibility()
    {
        LogDebug("Checking quest eligibility...");
        LogDebug($"Current Renown: {QuestManager.Instance?.GetRenown() ?? -1}");

        foreach (var quest in availableQuests)
        {
            bool eligible = IsQuestEligible(quest);
            LogDebug($"  - {quest.questTitle}: {(eligible ? "✅ ELIGIBLE" : "❌ NOT ELIGIBLE")} (Min Renown: {quest.minimumRenown})");
        }
    }

    [ContextMenu("Create Simple Test Quest")]
    private void DebugCreateSimpleQuest()
    {
        var simpleQuest = ScriptableObject.CreateInstance<Quest>();
        simpleQuest.questTitle = "Simple Test Quest";
        simpleQuest.questDescription = "A basic quest for testing the quest board display.";
        simpleQuest.questType = QuestType.Combat;
        simpleQuest.difficulty = QuestDifficulty.Easy;
        simpleQuest.timeLimitDays = 7;
        simpleQuest.targetAreaName = "Nearby Forest";
        simpleQuest.targetMapPosition = new Vector2Int(50, 50);
        simpleQuest.goldReward = 50;
        simpleQuest.renownReward = 5;
        simpleQuest.minimumRenown = 0; // No requirements

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

        // Add directly to available quests and quest board
        availableQuests.Add(simpleQuest);
        questBoard.Add(simpleQuest);

        LogDebug($"✅ Created and added simple test quest: {simpleQuest.questTitle}");
        LogDebug($"Quest Board now has {questBoard.Count} quests");
    }

    [ContextMenu("Force Reload Available Quests")]
    private void DebugReloadQuests()
    {
        LogDebug("🔄 Manually reloading available quests...");
        LoadAvailableQuests();
        RefreshQuestBoard();
    }

    [ContextMenu("List Resources/Quests Contents")]
    private void DebugListQuestResources()
    {
        LogDebug("🔍 Checking Resources/Quests folder contents...");
        
        var allQuests = Resources.LoadAll<Quest>("Quests");
        LogDebug($"Resources.LoadAll<Quest>(\"Quests\") returned {allQuests.Length} items");
        
        for (int i = 0; i < allQuests.Length; i++)
        {
            var quest = allQuests[i];
            if (quest != null)
            {
                LogDebug($"  {i}: {quest.name} - Title: '{quest.questTitle}' - Type: {quest.questType}");
            }
            else
            {
                LogDebug($"  {i}: NULL quest object");
            }
        }

        // Also check with UnityEngine.Object
        var allObjects = Resources.LoadAll("Quests");
        LogDebug($"Resources.LoadAll(\"Quests\") returned {allObjects.Length} objects of any type");
        
        for (int i = 0; i < allObjects.Length; i++)
        {
            var obj = allObjects[i];
            if (obj != null)
            {
                LogDebug($"  {i}: {obj.name} - Type: {obj.GetType().Name}");
            }
            else
            {
                LogDebug($"  {i}: NULL object");
            }
        }
    }

    [ContextMenu("Check Quest Board Eligibility")]
    private void DebugCheckQuestBoardEligibility()
    {
        LogDebug("🔍 Checking quest eligibility for quest board...");
        LogDebug($"Current Renown: {QuestManager.Instance?.GetRenown() ?? -1}");
        LogDebug($"Available Quests: {availableQuests.Count}");

        foreach (var quest in availableQuests)
        {
            if (quest != null)
            {
                bool eligible = IsQuestEligible(quest);
                LogDebug($"  - {quest.questTitle}:");
                LogDebug($"    Min Renown Required: {quest.minimumRenown}");
                LogDebug($"    Quest Type: {quest.questType}");
                LogDebug($"    Difficulty: {quest.difficulty}");
                LogDebug($"    Eligible: {(eligible ? "✅ YES" : "❌ NO")}");
                
                if (!eligible && QuestManager.Instance != null)
                {
                    // Check specific reasons
                    if (QuestManager.Instance.GetRenown() < quest.minimumRenown)
                    {
                        LogDebug($"    ❌ Reason: Not enough renown ({QuestManager.Instance.GetRenown()} < {quest.minimumRenown})");
                    }
                    
                    // Check if quest is already active
                    var activeQuests = QuestManager.Instance.GetActiveQuests();
                    bool alreadyActive = activeQuests.Any(aq => aq.questData.name == quest.name);
                    if (alreadyActive)
                    {
                        LogDebug($"    ❌ Reason: Quest already active");
                    }
                }
            }
        }
    }
    #endregion
}
