using UnityEngine;
using UnityEngine.UI;

public class MinimapManager : MonoBehaviour
{
    [Header("Camera/RenderTexture Settings")]
    [Tooltip("Optional: If set, the minimap camera will render into this RenderTexture.")]
    public RenderTexture targetTexture;
    [Tooltip("Optional: If set, this RawImage's texture will be assigned to the target RenderTexture.")]
    public RawImage targetRawImage;
    [Tooltip("Layers rendered by the minimap camera (include 'Minimap' layer here).")]
    public LayerMask cullingMask = ~0;

    [Header("Follow Settings")]
    public Vector3 offset = new Vector3(0f, 50f, 0f);
    [Tooltip("GTA V style: map rotates with player heading, player icon stays centered pointing up.")]
    public bool rotateWithPlayer = true;
    [Tooltip("How fast the minimap rotation follows the player heading. Higher = snappier.")]
    public float rotationSmoothSpeed = 10f;

    [Header("Zoom Settings")]
    public float defaultZoom = 50f;
    public float zoomLerpSpeed = 5f;

    private Transform player;
    private Camera minimapCam;
    private float targetZoom;
    
    private bool isCashSystemMode = false;
    private float refreshTimer = 0f;
    private float refreshInterval = 1f;
    
    /// <summary>
    /// The camera's current smoothed Y heading angle.
    /// MinimapMarker reads this to match the player chevron rotation exactly.
    /// </summary>
    public static float SmoothedHeading { get; private set; }

    void Awake()
    {
        minimapCam = GetComponent<Camera>();
        if (minimapCam == null)
        {
            Debug.LogError("MinimapManager must be placed on a Camera object.");
            enabled = false;
            return;
        }

        minimapCam.orthographic = true;
        minimapCam.orthographicSize = defaultZoom;
        minimapCam.nearClipPlane = 0.01f;
        minimapCam.farClipPlane = 1000f;
        minimapCam.clearFlags = CameraClearFlags.SolidColor;
        minimapCam.backgroundColor = new Color(0, 0, 0, 0);
        
        // Ensure Minimap layer is visible
        int minimapLayer = LayerMask.NameToLayer("Minimap");
        if (minimapLayer >= 0)
        {
            cullingMask |= (1 << minimapLayer);
            Debug.Log($"[MinimapManager] Found Minimap layer: {minimapLayer}");
        }
        else
        {
            // FALLBACK: If Minimap layer doesn't exist, use layer 31 (where markers fall back to)
            cullingMask |= (1 << 31);
            Debug.LogWarning("[MinimapManager] 'Minimap' layer not found! Using layer 31 fallback. " +
                "Create 'Minimap' layer in Project Settings for best results.");
        }
        
        // Legacy layer support
        int iconsLayer = LayerMask.NameToLayer("minimapIcons");
        if (iconsLayer >= 0)
        {
            cullingMask |= (1 << iconsLayer);
        }
        
        minimapCam.cullingMask = cullingMask;

        if (targetTexture != null)
        {
            minimapCam.targetTexture = targetTexture;
            if (targetRawImage != null)
            {
                targetRawImage.texture = targetTexture;
            }
        }
        targetZoom = defaultZoom;
    }

    void Start()
    {
        // Check game mode
        isCashSystemMode = SelectionOptions.Instance != null && SelectionOptions.Instance.isCashSystemSelected;
        
        FindPlayer();
        
        // IMPORTANT: Ensure MinimapMarkerManager exists for markers in ALL modes
        MinimapMarkerManager.EnsureExists();
        
        // Create edge indicators for off-screen entities
        if (targetRawImage != null)
        {
            MinimapEdgeIndicator.AttachTo(targetRawImage.rectTransform);
            
            // Add click-to-expand controller
            if (targetRawImage.GetComponent<MinimapExpandController>() == null)
                targetRawImage.gameObject.AddComponent<MinimapExpandController>();
        }
        
        Debug.Log($"[MinimapManager] Initialized - Cash System Mode: {isCashSystemMode}. Using Markers Only.");
        Debug.Log("[MinimapManager] IMPORTANT: Main Camera must EXCLUDE 'Minimap' layer from Culling Mask!");
    }

    void LateUpdate()
    {
        if (player == null)
        {
            // Try to find player periodically
            FindPlayer();
            return;
        }

        // Periodic check to switch targets if control changed
        refreshTimer += Time.deltaTime;
        if (refreshTimer >= refreshInterval)
        {
            refreshTimer = 0f;
            FindPlayer();
        }

        // --- Camera follow ---
        transform.position = player.position + offset;

        if (rotateWithPlayer)
        {
            // Smooth rotation for GTA V feel — no jerky snapping
            Quaternion targetRotation = Quaternion.Euler(90f, player.eulerAngles.y, 0f);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSmoothSpeed);
            
            // Expose the ACTUAL smoothed angle so markers can match perfectly
            SmoothedHeading = transform.eulerAngles.y;
        }
        else
        {
            transform.rotation = Quaternion.Euler(90f, 0f, 0f);
            SmoothedHeading = 0f;
        }

        // Smooth zoom
        minimapCam.orthographicSize = Mathf.Lerp(
            minimapCam.orthographicSize,
            targetZoom,
            Time.deltaTime * zoomLerpSpeed
        );
    }

    private void FindPlayer()
    {
        // In Cash System mode, try to find current controlled character
        if (isCashSystemMode)
        {
            CashSystemManager csm = FindObjectOfType<CashSystemManager>();
            if (csm != null && csm.CurrentControlledCharacter != null)
            {
                player = csm.CurrentControlledCharacter.transform;
                return;
            }
        }
        
        // Fallback to Player tag
        if (player == null)
        {
            GameObject p = GameObject.FindGameObjectWithTag("Player");
            if (p != null)
            {
                player = p.transform;
            }
        }
    }

    // === Public APIs ===
    public void SetTarget(Transform newTarget)
    {
        player = newTarget;
    }

    public void SetZoom(float zoomSize)
    {
        targetZoom = Mathf.Max(1f, zoomSize);
    }

    public void ZoomIn(float amount = 5f)
    {
        SetZoom(targetZoom - amount);
    }

    public void ZoomOut(float amount = 5f)
    {
        SetZoom(targetZoom + amount);
    }
    
    // Kept for compatibility, but does nothing now as markers manage themselves
    public void ForceRefresh()
    {
        FindPlayer();
    }
}
