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

/// <summary>
/// Manages quest markers on the map - shows quest locations and handles completion detection
/// </summary>
public class QuestMapMarkerManager : MonoBehaviour
{
    [Header("Marker Prefabs")]
    [Tooltip("Prefab for quest objective markers")]
    public GameObject questMarkerPrefab;

    [Tooltip("Prefab for quest completion areas")]
    public GameObject questAreaPrefab;

    [Header("Marker Settings")]
    [Tooltip("Scale factor for quest markers")]
    public float markerScale = 0.5f;

    [Tooltip("How often to check for quest completion (seconds)")]
    public float completionCheckInterval = 1f;

    [Header("Marker Colors")]
    public Color easyQuestColor = Color.green;
    public Color normalQuestColor = Color.yellow;
    public Color hardQuestColor = Color.red;
    public Color legendaryQuestColor = Color.magenta;
    public Color completedQuestColor = Color.gray;

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

    private Dictionary<string, QuestMarker> activeQuestMarkers = new Dictionary<string, QuestMarker>();
    private Transform teamMarker;
    private float lastCompletionCheck = 0f;

    private void Start()
    {
        InitializeMarkerManager();

        // Subscribe to quest events
        if (QuestManager.Instance != null)
        {
            QuestManager.Instance.OnQuestAccepted += OnQuestAccepted;
            QuestManager.Instance.OnQuestCompleted += OnQuestCompleted;
            QuestManager.Instance.OnQuestFailed += OnQuestFailed;
            QuestManager.Instance.OnQuestAbandoned += OnQuestAbandoned;

            // Create markers for any existing active quests
            StartCoroutine(CreateMarkersForExistingQuests());
        }
    }

    private System.Collections.IEnumerator CreateMarkersForExistingQuests()
    {
        // Wait a frame to ensure all systems are initialized
        yield return null;

        RefreshAllMarkers();
        LogDebug("Created markers for existing active quests");
    }

    private void Update()
    {
        CheckQuestCompletion();
    }

    private void OnDestroy()
    {
        // Unsubscribe from quest events
        if (QuestManager.Instance != null)
        {
            QuestManager.Instance.OnQuestAccepted -= OnQuestAccepted;
            QuestManager.Instance.OnQuestCompleted -= OnQuestCompleted;
            QuestManager.Instance.OnQuestFailed -= OnQuestFailed;
            QuestManager.Instance.OnQuestAbandoned -= OnQuestAbandoned;
        }
    }

    private void InitializeMarkerManager()
    {
        // Find team marker
        var teamMarkerObject = GameObject.Find("TeamMarker");
        if (teamMarkerObject != null)
        {
            teamMarker = teamMarkerObject.transform;
            LogDebug("Found TeamMarker");
        }
        else
        {
            LogDebug("⚠️ TeamMarker not found");
        }

        // Create default marker prefabs if none assigned
        if (questMarkerPrefab == null)
        {
            questMarkerPrefab = CreateDefaultMarkerPrefab();
        }

        if (questAreaPrefab == null)
        {
            questAreaPrefab = CreateDefaultAreaPrefab();
        }

        LogDebug("QuestMapMarkerManager initialized");
    }

    private void CheckQuestCompletion()
    {
        if (Time.time < lastCompletionCheck + completionCheckInterval) return;
        if (teamMarker == null || QuestManager.Instance == null) return;

        lastCompletionCheck = Time.time;

        // Get current team position in map coordinates
        Vector2Int teamPosition = WorldToMapCoordinates(teamMarker.position);

        // Check if any quests can be completed at current position
        var completedQuests = QuestManager.Instance.TryCompleteQuestsAtPosition(teamPosition);

        if (completedQuests.Count > 0)
        {
            LogDebug($"Completed {completedQuests.Count} quests at position {teamPosition}");
        }
    }

    private Vector2Int WorldToMapCoordinates(Vector3 worldPosition)
    {
        // Convert world position to map tile coordinates
        // This should match the conversion used in other map systems
        float tileSize = 1f;
        var mapVisualizer = FindFirstObjectByType<MapVisualizer>();
        if (mapVisualizer != null && mapVisualizer.tileSize > 0)
        {
            tileSize = mapVisualizer.tileSize;
        }

        return new Vector2Int(
            Mathf.RoundToInt(worldPosition.x / tileSize),
            Mathf.RoundToInt(worldPosition.z / tileSize) // Use Z for 3D maps
        );
    }

    private Vector3 MapToWorldCoordinates(Vector2Int mapPosition)
    {
        // Convert map tile coordinates to world position
        float tileSize = 1f;
        var mapVisualizer = FindFirstObjectByType<MapVisualizer>();
        if (mapVisualizer != null && mapVisualizer.tileSize > 0)
        {
            tileSize = mapVisualizer.tileSize;
        }

        return new Vector3(
            mapPosition.x * tileSize,
            0f,
            mapPosition.y * tileSize
        );
    }

    private void OnQuestAccepted(ActiveQuest quest)
    {
        CreateQuestMarker(quest);
    }

    private void OnQuestCompleted(ActiveQuest quest, List<QuestReward> rewards)
    {
        RemoveQuestMarker(quest.questId);
    }

    private void OnQuestFailed(ActiveQuest quest)
    {
        RemoveQuestMarker(quest.questId);
    }

    private void OnQuestAbandoned(ActiveQuest quest)
    {
        RemoveQuestMarker(quest.questId);
    }

    private void CreateQuestMarker(ActiveQuest quest)
    {
        if (quest?.questData == null) return;

        // Remove existing marker if it exists
        RemoveQuestMarker(quest.questId);

        // Convert quest position to world coordinates
        Vector3 worldPosition = MapToWorldCoordinates(quest.questData.targetMapPosition);

        // Create marker GameObject
        GameObject markerObject = Instantiate(questMarkerPrefab, worldPosition, Quaternion.identity);
        markerObject.name = $"QuestMarker_{quest.questData.questTitle}";
        markerObject.transform.localScale = Vector3.one * markerScale;

        // Create completion area
        GameObject areaObject = Instantiate(questAreaPrefab, worldPosition, Quaternion.identity);
        areaObject.name = $"QuestArea_{quest.questData.questTitle}";
        areaObject.transform.localScale = Vector3.one * quest.questData.completionRadius;

        // Set up the quest marker component
        var questMarker = markerObject.GetComponent<QuestMarker>();
        if (questMarker == null)
        {
            questMarker = markerObject.AddComponent<QuestMarker>();
        }

        questMarker.Initialize(quest, areaObject);

        // Set marker color based on difficulty
        SetMarkerColor(questMarker, quest.questData.difficulty);

        // Store reference
        activeQuestMarkers[quest.questId] = questMarker;

        LogDebug($"Created quest marker for '{quest.questData.questTitle}' at {quest.questData.targetMapPosition}");
    }

    private void RemoveQuestMarker(string questId)
    {
        if (activeQuestMarkers.TryGetValue(questId, out QuestMarker marker))
        {
            if (marker != null && marker.gameObject != null)
            {
                Destroy(marker.gameObject);
            }
            activeQuestMarkers.Remove(questId);
            LogDebug($"Removed quest marker for quest {questId}");
        }
    }

    private void SetMarkerColor(QuestMarker marker, QuestDifficulty difficulty)
    {
        Color color = difficulty switch
        {
            QuestDifficulty.Easy => easyQuestColor,
            QuestDifficulty.Normal => normalQuestColor,
            QuestDifficulty.Hard => hardQuestColor,
            QuestDifficulty.Legendary => legendaryQuestColor,
            _ => normalQuestColor
        };

        marker.SetColor(color);
    }

    private GameObject CreateDefaultMarkerPrefab()
    {
        // Create a simple cube marker
        GameObject marker = GameObject.CreatePrimitive(PrimitiveType.Cube);
        marker.name = "DefaultQuestMarker";

        // Make it slightly elevated
        marker.transform.position = Vector3.up * 0.5f;

        // Add a distinctive material
        var renderer = marker.GetComponent<Renderer>();
        if (renderer != null)
        {
            renderer.material.color = Color.yellow;
        }

        // Remove collider to avoid interference
        var collider = marker.GetComponent<Collider>();
        if (collider != null)
        {
            DestroyImmediate(collider);
        }

        return marker;
    }

    private GameObject CreateDefaultAreaPrefab()
    {
        // Create a simple cylinder for the completion area
        GameObject area = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
        area.name = "DefaultQuestArea";

        // Make it flat and transparent
        area.transform.localScale = new Vector3(1f, 0.1f, 1f);

        var renderer = area.GetComponent<Renderer>();
        if (renderer != null)
        {
            // Make it semi-transparent
            var material = new Material(Shader.Find("Legacy Shaders/Transparent/Diffuse"));
            material.color = new Color(1f, 1f, 0f, 0.3f); // Semi-transparent yellow
            renderer.material = material;
        }

        // Remove collider
        var collider = area.GetComponent<Collider>();
        if (collider != null)
        {
            DestroyImmediate(collider);
        }

        return area;
    }

    /// <summary>
    /// Get all active quest markers
    /// </summary>
    public List<QuestMarker> GetActiveMarkers()
    {
        return activeQuestMarkers.Values.Where(m => m != null).ToList();
    }

    /// <summary>
    /// Get quest marker by quest ID
    /// </summary>
    public QuestMarker GetMarkerByQuestId(string questId)
    {
        activeQuestMarkers.TryGetValue(questId, out QuestMarker marker);
        return marker;
    }

    /// <summary>
    /// Refresh all quest markers (useful when loading a saved game)
    /// </summary>
    public void RefreshAllMarkers()
    {
        // Clear existing markers
        foreach (var marker in activeQuestMarkers.Values)
        {
            if (marker != null && marker.gameObject != null)
            {
                Destroy(marker.gameObject);
            }
        }
        activeQuestMarkers.Clear();

        // Recreate markers for all active quests
        if (QuestManager.Instance != null)
        {
            var activeQuests = QuestManager.Instance.GetActiveQuests();
            foreach (var quest in activeQuests)
            {
                CreateQuestMarker(quest);
            }
        }

        LogDebug("Refreshed all quest markers");
    }

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

    /// <summary>
    /// Focus the camera on a specific quest's marker
    /// </summary>
    public void FocusOnQuest(ActiveQuest quest)
    {
        if (quest == null || !activeQuestMarkers.ContainsKey(quest.questId))
        {
            LogDebug($"❌ Cannot focus on quest {quest?.questData?.questTitle} - marker not found");
            return;
        }

        var marker = activeQuestMarkers[quest.questId];
        if (marker != null)
        {
            var targetPosition = marker.transform.position;

            // Try to find a camera controller or similar component
            var cameraController = FindFirstObjectByType<CameraController>();
            if (cameraController != null)
            {
                // Assuming the camera controller has a method to focus on position
                // cameraController.FocusOnPosition(targetPosition);
                LogDebug($"✅ Focusing camera on quest: {quest.questData.questTitle}");
            }
            else
            {
                // Fallback: just move the main camera
                var mainCamera = Camera.main;
                if (mainCamera != null)
                {
                    var cameraPos = mainCamera.transform.position;
                    mainCamera.transform.position = new Vector3(targetPosition.x, targetPosition.y, cameraPos.z);
                    LogDebug($"✅ Moved camera to quest location: {quest.questData.questTitle}");
                }
            }
        }
    }

    /// <summary>
    /// Get the world position of a quest marker
    /// </summary>
    public Vector3? GetQuestMarkerPosition(ActiveQuest quest)
    {
        if (quest == null || !activeQuestMarkers.ContainsKey(quest.questId))
            return null;

        var marker = activeQuestMarkers[quest.questId];
        return marker?.transform.position;
    }

    #region Context Menu Debug Methods
    [ContextMenu("Refresh All Markers")]
    private void DebugRefreshAllMarkers()
    {
        RefreshAllMarkers();
    }

    [ContextMenu("List Active Markers")]
    private void DebugListActiveMarkers()
    {
        LogDebug($"Active Quest Markers ({activeQuestMarkers.Count}):");
        foreach (var kvp in activeQuestMarkers)
        {
            var marker = kvp.Value;
            if (marker != null)
            {
                LogDebug($"  - {marker.ActiveQuest.questData.questTitle} at {marker.transform.position}");
            }
        }
    }

    [ContextMenu("Force Create Test Marker")]
    private void DebugCreateTestMarker()
    {
        if (QuestManager.Instance == null)
        {
            LogDebug("❌ No QuestManager found!");
            return;
        }

        var activeQuests = QuestManager.Instance.GetActiveQuests();
        if (activeQuests.Count == 0)
        {
            LogDebug("❌ No active quests to create markers for!");
            return;
        }

        foreach (var quest in activeQuests)
        {
            CreateQuestMarker(quest);
            LogDebug($"✅ Created test marker for: {quest.questData.questTitle}");
        }
    }

    [ContextMenu("Check Quest System Status")]
    private void DebugQuestSystemStatus()
    {
        LogDebug("=== QUEST SYSTEM STATUS ===");
        LogDebug($"QuestManager exists: {QuestManager.Instance != null}");

        if (QuestManager.Instance != null)
        {
            var activeQuests = QuestManager.Instance.GetActiveQuests();
            LogDebug($"Active quests: {activeQuests.Count}");

            foreach (var quest in activeQuests)
            {
                LogDebug($"  - {quest.questData.questTitle} → {quest.questData.targetMapPosition}");
            }
        }

        LogDebug($"Active markers: {activeQuestMarkers.Count}");
        LogDebug($"Team marker found: {teamMarker != null}");
        LogDebug($"Marker prefabs: Marker={questMarkerPrefab != null}, Area={questAreaPrefab != null}");
    }
    #endregion
}
