using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// Visualization component that displays a semi-transparent purple circle around the team marker
/// to represent the team's collective perception range. The radius is based on the highest
/// perception value among team members.
/// </summary>
public class TeamPerceptionVisualizer : MonoBehaviour
{
    [Header("Perception Circle Settings")]
    [SerializeField] private Material perceptionCircleMaterial;
    [SerializeField] private Color perceptionColor = new Color(0.5f, 0f, 1f, 0.5f); // 50% transparent purple
    [SerializeField] private float perceptionMultiplier = 1.0f; // Converts perception value to world units
    [SerializeField] private int circleSegments = 64; // Circle resolution
    [SerializeField] private float heightOffset = 0.1f; // How high above ground to place the circle

    [Header("Dynamic Updates")]
    [SerializeField] private bool updatePerceptionInRealTime = true;
    [SerializeField] private float updateInterval = 1f; // How often to check for perception changes (in seconds)

    [Header("Debug")]
    [SerializeField] private bool showDebugInfo = true;

    // Private variables
    private GameObject perceptionCircleObject;
    private LineRenderer circleRenderer;
    private SimpleTeamPlacement teamPlacement;
    private GameStateManager gameStateManager;
    private MainTeamSelectScript teamSelectScript;
    private int lastKnownMaxPerception = -1;
    private float lastUpdateTime = 0f;

    public static TeamPerceptionVisualizer Instance { get; private set; }

    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Debug.LogWarning("Multiple TeamPerceptionVisualizer instances found. Destroying this one.");
            Destroy(gameObject);
            return;
        }
    }

    void Start()
    {
        // Find required components
        teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
        gameStateManager = FindFirstObjectByType<GameStateManager>();
        teamSelectScript = FindFirstObjectByType<MainTeamSelectScript>();

        if (teamPlacement == null)
        {
            Debug.LogError("TeamPerceptionVisualizer: SimpleTeamPlacement component not found!");
            return;
        }

        // Create the perception circle
        CreatePerceptionCircle();

        // Initial position update with slight delay to ensure team marker is loaded
        StartCoroutine(DelayedInitialUpdate());
    }

    /// <summary>
    /// Performs initial updates with a small delay to ensure all components are loaded
    /// </summary>
    private System.Collections.IEnumerator DelayedInitialUpdate()
    {
        yield return new WaitForEndOfFrame();
        yield return new WaitForSeconds(0.1f); // Small delay

        UpdateCirclePosition();
        UpdatePerceptionVisualization();
    }

    void Update()
    {
        // Always update position to follow team marker
        UpdateCirclePosition();

        if (!updatePerceptionInRealTime || Time.time - lastUpdateTime < updateInterval)
            return;

        UpdatePerceptionVisualization();
        lastUpdateTime = Time.time;
    }

    /// <summary>
    /// Creates the visual circle GameObject and LineRenderer component
    /// </summary>
    private void CreatePerceptionCircle()
    {
        // Create the circle GameObject
        perceptionCircleObject = new GameObject("PerceptionCircle");
        perceptionCircleObject.transform.SetParent(this.transform);

        // Add and configure LineRenderer
        circleRenderer = perceptionCircleObject.AddComponent<LineRenderer>();
        circleRenderer.useWorldSpace = false;
        circleRenderer.loop = true;
        circleRenderer.startWidth = 0.3f;
        circleRenderer.endWidth = 0.3f;
        circleRenderer.positionCount = circleSegments;
        circleRenderer.startColor = perceptionColor;
        circleRenderer.endColor = perceptionColor;

        // Set material if provided, otherwise create a simple one
        if (perceptionCircleMaterial != null)
        {
            circleRenderer.material = perceptionCircleMaterial;
        }
        else
        {
            // Create a simple material with transparency support
            Material simpleMaterial = new Material(Shader.Find("Sprites/Default"));
            simpleMaterial.color = perceptionColor;
            circleRenderer.material = simpleMaterial;
        }

        // Initially hide the circle until we have valid data
        perceptionCircleObject.SetActive(false);
    }

    /// <summary>
    /// Updates the circle position to follow the team marker
    /// </summary>
    private void UpdateCirclePosition()
    {
        if (perceptionCircleObject == null || teamPlacement == null)
            return;

        Vector3 teamPosition = GetTeamMarkerPosition();
        if (teamPosition != Vector3.zero)
        {
            Vector3 newPosition = new Vector3(
                teamPosition.x,
                teamPosition.y + heightOffset,
                teamPosition.z
            );

            // Only move if the position actually changed (to avoid spam)
            if (Vector3.Distance(perceptionCircleObject.transform.position, newPosition) > 0.1f)
            {
                perceptionCircleObject.transform.position = newPosition;
                if (showDebugInfo)
                {
                    Debug.Log($"TeamPerceptionVisualizer: Updated circle position to {newPosition}");
                }
            }
        }
        else if (showDebugInfo)
        {
            Debug.LogWarning("TeamPerceptionVisualizer: Could not find team marker position");
        }
    }

    /// <summary>
    /// Updates the perception visualization based on current team data
    /// </summary>
    public void UpdatePerceptionVisualization()
    {
        if (circleRenderer == null)
            return;

        int maxPerception = GetHighestTeamPerception();

        // If no valid perception data, hide the circle
        if (maxPerception <= 0)
        {
            if (perceptionCircleObject.activeSelf)
            {
                perceptionCircleObject.SetActive(false);
                if (showDebugInfo)
                    Debug.Log("TeamPerceptionVisualizer: Hiding perception circle - no valid team data");
            }
            return;
        }

        // If perception hasn't changed, no need to update
        if (maxPerception == lastKnownMaxPerception && perceptionCircleObject.activeSelf)
            return;

        lastKnownMaxPerception = maxPerception;

        // Calculate radius based on perception
        float radius = maxPerception * perceptionMultiplier;

        // Generate circle points
        Vector3[] points = new Vector3[circleSegments];
        for (int i = 0; i < circleSegments; i++)
        {
            float angle = (float)i / circleSegments * 2f * Mathf.PI;
            points[i] = new Vector3(
                Mathf.Cos(angle) * radius,
                0f,
                Mathf.Sin(angle) * radius
            );
        }

        // Apply points to LineRenderer
        circleRenderer.positionCount = circleSegments;
        circleRenderer.SetPositions(points);

        // Show the circle
        if (!perceptionCircleObject.activeSelf)
        {
            perceptionCircleObject.SetActive(true);
        }

        if (showDebugInfo)
        {
            Debug.Log($"TeamPerceptionVisualizer: Updated perception circle - Max Perception: {maxPerception}, Radius: {radius:F1}");
        }
    }

    /// <summary>
    /// Gets the highest perception value among all team members
    /// </summary>
    /// <returns>The highest perception value, or 0 if no team data available</returns>
    private int GetHighestTeamPerception()
    {
        int maxPerception = 0;
        List<TeamCharacter> teamMembers = GetCurrentTeamMembers();

        if (teamMembers == null || teamMembers.Count == 0)
            return 0;

        foreach (TeamCharacter character in teamMembers)
        {
            if (character != null)
            {
                int characterPerception = character.FinalPerception; // Use final perception (includes equipment bonuses)
                if (characterPerception > maxPerception)
                {
                    maxPerception = characterPerception;
                }
            }
        }

        return maxPerception;
    }

    /// <summary>
    /// Gets the current team members from available sources
    /// </summary>
    /// <returns>List of team members or null if not available</returns>
    private List<TeamCharacter> GetCurrentTeamMembers()
    {
        // Try to get team from MainTeamSelectScript first (if in current scene)
        if (teamSelectScript != null)
        {
            var configuredCharacters = teamSelectScript.GetConfiguredCharacters();
            if (configuredCharacters != null && configuredCharacters.Count > 0)
            {
                if (showDebugInfo)
                    Debug.Log($"TeamPerceptionVisualizer: Found {configuredCharacters.Count} team members from MainTeamSelectScript");
                return configuredCharacters;
            }
        }

        // Fall back to GameStateManager saved data
        if (gameStateManager != null && gameStateManager.savedTeam != null)
        {
            var savedTeamList = new List<TeamCharacter>();
            foreach (var character in gameStateManager.savedTeam)
            {
                if (character != null)
                    savedTeamList.Add(character);
            }

            if (savedTeamList.Count > 0)
            {
                if (showDebugInfo)
                    Debug.Log($"TeamPerceptionVisualizer: Found {savedTeamList.Count} team members from GameStateManager");
                return savedTeamList;
            }
        }

        // Final fallback: Load directly from PlayerPrefs (same as TeamOverviewController)
        var playerPrefTeam = new List<TeamCharacter>();
        for (int i = 0; i < 4; i++)
        {
            string prefix = $"Character{i}_";
            if (PlayerPrefs.HasKey(prefix + "Exists") && PlayerPrefs.GetInt(prefix + "Exists") == 1)
            {
                var character = new TeamCharacter();
                character.name = PlayerPrefs.GetString(prefix + "Name", "");
                character.isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1;
                character.strength = PlayerPrefs.GetInt(prefix + "Strength", 10);
                character.dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10);
                character.constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10);
                character.wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10);
                character.perception = PlayerPrefs.GetInt(prefix + "Perception", 10);
                character.gold = PlayerPrefs.GetInt(prefix + "Gold", 25);

                playerPrefTeam.Add(character);
            }
        }

        if (playerPrefTeam.Count > 0)
        {
            if (showDebugInfo)
                Debug.Log($"TeamPerceptionVisualizer: Found {playerPrefTeam.Count} team members from PlayerPrefs");
            return playerPrefTeam;
        }

        if (showDebugInfo)
            Debug.Log("TeamPerceptionVisualizer: No team members found in any source");
        return null;
    }

    /// <summary>
    /// Gets the world position of the team marker
    /// </summary>
    /// <returns>World position of the team marker, or Vector3.zero if not found</returns>
    private Vector3 GetTeamMarkerPosition()
    {
        if (teamPlacement != null && teamPlacement.TeamMarkerInstance != null)
        {
            return teamPlacement.TeamMarkerWorldPosition;
        }

        // Fallback: try to find the marker by name or tag
        var teamMarker = GameObject.FindGameObjectWithTag("Player"); // The marker uses "Player" tag
        if (teamMarker != null && teamMarker.name == "TeamMarker")
        {
            return teamMarker.transform.position;
        }

        // Alternative: look for any GameObject with "TeamMarker" in the name
        var foundMarker = GameObject.Find("TeamMarker");
        if (foundMarker != null)
        {
            return foundMarker.transform.position;
        }

        // If we can't find the marker, return zero
        return Vector3.zero;
    }

    /// <summary>
    /// Call this method when team composition or equipment changes
    /// </summary>
    public void ForceUpdatePerception()
    {
        lastKnownMaxPerception = -1; // Force update on next check
        UpdatePerceptionVisualization();
    }

    /// <summary>
    /// Enables or disables the perception visualization
    /// </summary>
    /// <param name="enabled">Whether to show the perception circle</param>
    public void SetPerceptionVisualizationEnabled(bool enabled)
    {
        if (perceptionCircleObject != null)
        {
            perceptionCircleObject.SetActive(enabled && GetHighestTeamPerception() > 0);
        }
    }

    /// <summary>
    /// Updates the circle color
    /// </summary>
    /// <param name="newColor">New color for the perception circle</param>
    public void SetPerceptionColor(Color newColor)
    {
        perceptionColor = newColor;
        if (circleRenderer != null)
        {
            circleRenderer.startColor = newColor;
            circleRenderer.endColor = newColor;
            if (circleRenderer.material != null)
            {
                circleRenderer.material.color = newColor;
            }
        }
    }

    /// <summary>
    /// Updates the perception multiplier (how large the circle is relative to perception value)
    /// </summary>
    /// <param name="multiplier">New multiplier value</param>
    public void SetPerceptionMultiplier(float multiplier)
    {
        perceptionMultiplier = multiplier;
        ForceUpdatePerception(); // Update circle with new size
    }

    void OnDestroy()
    {
        if (Instance == this)
        {
            Instance = null;
        }
    }

    /// <summary>
    /// Debug method to show current perception info
    /// </summary>
    [ContextMenu("Show Perception Debug Info")]
    public void ShowPerceptionDebugInfo()
    {
        var teamMembers = GetCurrentTeamMembers();
        if (teamMembers == null || teamMembers.Count == 0)
        {
            Debug.Log("No team members found");
            return;
        }

        Debug.Log("=== Team Perception Debug Info ===");
        Debug.Log($"Team Members Count: {teamMembers.Count}");

        int maxPerception = 0;
        string bestCharacter = "";

        foreach (var character in teamMembers)
        {
            if (character != null)
            {
                int perception = character.FinalPerception;
                Debug.Log($"- {character.name}: Perception {perception} (Base: {character.perception}, Modifier: {character.perceptionModifier})");

                if (perception > maxPerception)
                {
                    maxPerception = perception;
                    bestCharacter = character.name;
                }
            }
        }

        Debug.Log($"Highest Perception: {maxPerception} ({bestCharacter})");
        Debug.Log($"Circle Radius: {maxPerception * perceptionMultiplier:F1} units");
        Debug.Log("=== End Debug Info ===");
    }

    /// <summary>
    /// Test method to force immediate visualization update
    /// </summary>
    [ContextMenu("Force Update Visualization Now")]
    public void ForceUpdateVisualizationNow()
    {
        Debug.Log("=== Forcing Perception Visualization Update ===");
        ForceUpdatePerception();

        var teamMembers = GetCurrentTeamMembers();
        if (teamMembers != null && teamMembers.Count > 0)
        {
            int maxPerception = GetHighestTeamPerception();
            Debug.Log($"Found {teamMembers.Count} team members, highest perception: {maxPerception}");

            if (perceptionCircleObject != null)
            {
                Debug.Log($"Circle active: {perceptionCircleObject.activeSelf}");
                Debug.Log($"Circle position: {perceptionCircleObject.transform.position}");
            }
            else
            {
                Debug.LogWarning("Perception circle object is null!");
            }
        }
        else
        {
            Debug.LogWarning("No team members found for visualization!");
        }
        Debug.Log("=== End Force Update ===");
    }
}
