using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// TeamIndicator - Creates an overhead team marker above characters to differentiate teammates from enemies.
/// Attach to character prefabs or add dynamically via TeamIndicatorManager.
/// </summary>
public class TeamIndicator : MonoBehaviour
{
    [Header("Indicator Settings")]
    [SerializeField] private float heightOffset = 2.5f;
    [SerializeField] private float indicatorSize = 0.3f;
    
    [Header("Team Colors")]
    [SerializeField] private Color allyColor = new Color(0.2f, 0.8f, 0.2f, 1f); // Green
    [SerializeField] private Color enemyColor = new Color(0.9f, 0.2f, 0.2f, 1f); // Red
    [SerializeField] private Color controlledColor = new Color(0.2f, 0.6f, 1f, 1f); // Blue for currently controlled
    
    [Header("Visual Options")]
    [SerializeField] private bool showOnAllies = true;
    [SerializeField] private bool showOnEnemies = true;
    [SerializeField] private bool hideWhenControlled = true;
    [SerializeField] private float fadeDistance = 50f; // Fade out at this distance
    
    private GameObject indicatorObject;
    private SpriteRenderer spriteRenderer;
    private Camera mainCamera;
    private TeamMember teamMember;
    private string myTeamTag;
    private bool isCurrentlyControlled = false;
    
    // Static reference to find the current player for team comparison
    private static Transform currentPlayerTransform;
    private static string currentPlayerTeamTag = "Player";
    
    private void Start()
    {
        // Only activate in Cash System mode
        if (SelectionOptions.Instance == null || !SelectionOptions.Instance.isCashSystemSelected)
        {
            enabled = false;
            return;
        }
        
        mainCamera = Camera.main;
        teamMember = GetComponent<TeamMember>();
        myTeamTag = gameObject.tag;
        
        CreateIndicator();
        UpdateIndicatorColor();
    }
    
    private void LateUpdate()
    {
        if (indicatorObject == null || mainCamera == null) return;
        
        // Update position to stay above character
        indicatorObject.transform.position = transform.position + Vector3.up * heightOffset;
        
        // Billboard effect - always face camera
        indicatorObject.transform.rotation = Quaternion.LookRotation(
            indicatorObject.transform.position - mainCamera.transform.position
        );
        
        // Check if this character is currently controlled
        bool wasControlled = isCurrentlyControlled;
        isCurrentlyControlled = teamMember != null && teamMember.IsPlayerControlled;
        
        // Update static reference if we're the controlled character
        if (isCurrentlyControlled)
        {
            currentPlayerTransform = transform;
            currentPlayerTeamTag = myTeamTag;
        }
        
        // Update color if control status changed
        if (wasControlled != isCurrentlyControlled)
        {
            UpdateIndicatorColor();
        }
        
        // Handle visibility based on settings
        UpdateVisibility();
        
        // Fade based on distance from camera
        UpdateFade();
    }
    
    private void CreateIndicator()
    {
        // Create indicator game object
        indicatorObject = new GameObject($"{gameObject.name}_TeamIndicator");
        indicatorObject.transform.position = transform.position + Vector3.up * heightOffset;
        
        // Add sprite renderer for the indicator
        spriteRenderer = indicatorObject.AddComponent<SpriteRenderer>();
        spriteRenderer.sprite = CreateCircleSprite();
        spriteRenderer.sortingOrder = 100; // Ensure it renders on top
        
        // Set initial size
        indicatorObject.transform.localScale = Vector3.one * indicatorSize;
    }
    
    private Sprite CreateCircleSprite()
    {
        // Create a simple diamond/arrow shaped indicator texture
        int size = 64;
        Texture2D texture = new Texture2D(size, size);
        Color transparent = new Color(0, 0, 0, 0);
        
        // Fill with transparent
        for (int x = 0; x < size; x++)
        {
            for (int y = 0; y < size; y++)
            {
                texture.SetPixel(x, y, transparent);
            }
        }
        
        // Draw a downward pointing triangle/arrow
        int centerX = size / 2;
        int topY = size - 8;
        int bottomY = 8;
        
        for (int y = bottomY; y <= topY; y++)
        {
            float progress = (float)(y - bottomY) / (topY - bottomY);
            int halfWidth = (int)(progress * (size / 2 - 4));
            
            for (int x = centerX - halfWidth; x <= centerX + halfWidth; x++)
            {
                // Create a border effect
                bool isBorder = Mathf.Abs(x - (centerX - halfWidth)) < 3 || 
                               Mathf.Abs(x - (centerX + halfWidth)) < 3 ||
                               y == bottomY || y >= topY - 2;
                
                Color col = isBorder ? Color.white : Color.white;
                col.a = isBorder ? 1f : 0.8f;
                texture.SetPixel(x, y, col);
            }
        }
        
        texture.Apply();
        texture.filterMode = FilterMode.Bilinear;
        
        return Sprite.Create(texture, new Rect(0, 0, size, size), new Vector2(0.5f, 0f), size);
    }
    
    private void UpdateIndicatorColor()
    {
        if (spriteRenderer == null) return;
        
        // Currently controlled character
        if (isCurrentlyControlled)
        {
            spriteRenderer.color = controlledColor;
            return;
        }
        
        // Determine if ally or enemy relative to player
        bool isAlly = (myTeamTag == currentPlayerTeamTag);
        
        if (isAlly)
        {
            spriteRenderer.color = allyColor;
        }
        else
        {
            spriteRenderer.color = enemyColor;
        }
    }
    
    private void UpdateVisibility()
    {
        if (spriteRenderer == null) return;
        
        bool shouldShow = true;
        
        // Hide if this is the controlled character and setting is enabled
        if (hideWhenControlled && isCurrentlyControlled)
        {
            shouldShow = false;
        }
        
        // Check ally/enemy visibility settings
        bool isAlly = (myTeamTag == currentPlayerTeamTag);
        if (isAlly && !showOnAllies) shouldShow = false;
        if (!isAlly && !showOnEnemies) shouldShow = false;
        
        indicatorObject.SetActive(shouldShow);
    }
    
    private void UpdateFade()
    {
        if (spriteRenderer == null || mainCamera == null) return;
        
        float distance = Vector3.Distance(mainCamera.transform.position, transform.position);
        
        // Calculate alpha based on distance
        float alpha = Mathf.Clamp01(1f - (distance / fadeDistance));
        alpha = Mathf.Max(alpha, 0.3f); // Minimum alpha
        
        Color currentColor = spriteRenderer.color;
        currentColor.a = alpha;
        spriteRenderer.color = currentColor;
    }
    
    private void OnDestroy()
    {
        if (indicatorObject != null)
        {
            Destroy(indicatorObject);
        }
    }
    
    /// <summary>
    /// Force update the indicator color (call after team changes)
    /// </summary>
    public void RefreshIndicator()
    {
        myTeamTag = gameObject.tag;
        UpdateIndicatorColor();
        UpdateVisibility();
    }
    
    /// <summary>
    /// Set indicator visibility
    /// </summary>
    public void SetVisible(bool visible)
    {
        if (indicatorObject != null)
        {
            indicatorObject.SetActive(visible);
        }
    }
    
    /// <summary>
    /// Static method to update all indicators when player changes
    /// </summary>
    public static void RefreshAllIndicators()
    {
        foreach (var indicator in FindObjectsOfType<TeamIndicator>())
        {
            indicator.RefreshIndicator();
        }
    }
}
