using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/*
 Canvas (기존 InGameUI Canvas)
└── MinimapRoot (빈 오브젝트, MinimapManager 컴포넌트 부착)
    ├── MapMask (원형/사각형 마스크, Mask 컴포넌트)
    │   ├── MapImage (RawImage) ← _mapImage, _mapRect
    │   ├── PlayerIcon (Image) ← _playerIcon
    │   └── MarkerContainer (빈 오브젝트) ← _markerContainer
    └── MinimapFrame (Image) ← 테두리 장식 (선택)
 */

public class MinimapManager : MonoBehaviour
{
    [Header("미니맵 UI")]
    [SerializeField] private GameObject _minimapRoot;
    [SerializeField] private RawImage _mapImage;            // 맵 배경 (RenderTexture 또는 프리렌더 이미지)
    [SerializeField] private RectTransform _mapRect;        // 맵 이미지의 RectTransform
    [SerializeField] private RectTransform _playerIcon;     // 플레이어 아이콘
    [SerializeField] private RectTransform _markerContainer;// 마커 부모

    [Header("프리렌더 이미지")]
    [SerializeField] private Texture2D _bakedMapImage;

    [Header("월드 범위")]
    [SerializeField] private Vector2 _worldMin = new Vector2(-50, -50);
    [SerializeField] private Vector2 _worldMax = new Vector2(50, 50);

    [Header("모드")]
    [SerializeField] private bool _useRenderTexture = true; // true: 실시간(개발용), false: 프리렌더(출시용)

    //개발용 설정
    //----------------------------------------------------------
    [Header("미니맵 카메라")] 
    [SerializeField] private Camera _minimapCamera;
    [SerializeField] private RenderTexture _renderTexture;

    [Header("카메라 설정")] 
    [SerializeField] private float _cameraHeight = 50f;
    [SerializeField] private float _zoomLevel = 30f;
    [SerializeField] private float _minZoom = 15f;
    [SerializeField] private float _maxZoom = 80f;
    //----------------------------------------------------------

    private List<MinimapMarker> _markers = new List<MinimapMarker>();

    private void Start()
    {
        ApplyMode();
    }

    private void LateUpdate()
    {
        UpdateCamera();
        UpdatePlayerIcon();
        UpdateMarkers();
    }

    public void ApplyMode()
    {
        if (_useRenderTexture)
        {
            _mapImage.texture = _renderTexture;
            if (_minimapCamera != null) _minimapCamera.gameObject.SetActive(true);
        }
        else
        {
            _mapImage.texture = _bakedMapImage;
            if (_minimapCamera != null) _minimapCamera.gameObject.SetActive(false);
        }
    }

    private void UpdateCamera()
    {
        if (!_useRenderTexture || _minimapCamera == null) return;

        Vector3 pos = GameManager.Instance.Level.CurrentCharacter.transform.position;
        _minimapCamera.transform.position = new Vector3(pos.x, pos.y + _cameraHeight, pos.z);
        _minimapCamera.orthographicSize = _zoomLevel;
    }

    private void UpdatePlayerIcon()
    {
        if (_playerIcon == null) return;

        Transform player = GameManager.Instance.Level.CurrentCharacter.transform;

        if (_useRenderTexture)
        {
            _playerIcon.anchoredPosition = Vector2.zero;
        }
        else
        {
            _playerIcon.anchoredPosition = WorldToMapPos(player.position);
        }

        _playerIcon.localRotation = Quaternion.Euler(0, 0, -player.eulerAngles.y);
    }

    private void UpdateMarkers()
    {
        for (int i = _markers.Count - 1; i >= 0; i--)
        {
            if (_markers[i] == null)
            {
                _markers.RemoveAt(i);
                continue;
            }

            _markers[i].UpdatePosition(this);
        }
    }

    public Vector2 WorldToMapPos(Vector3 worldPos)
    {
        float ratioX = (worldPos.x - _worldMin.x) / (_worldMax.x - _worldMin.x);
        float ratioY = (worldPos.z - _worldMin.y) / (_worldMax.y - _worldMin.y);

        //sizeDelta는 앵커 영역과 실제 UI 크기의 차이값
        return new Vector2(
            ratioX * _mapRect.sizeDelta.x - _mapRect.sizeDelta.x * 0.5f,
            ratioY * _mapRect.sizeDelta.y - _mapRect.sizeDelta.y * 0.5f
        );
    }

    public RectTransform MarkerContainer => _markerContainer;

    public void RegisterMarker(MinimapMarker marker)
    {
        if (!_markers.Contains(marker))
            _markers.Add(marker);
    }

    public void UnregisterMarker(MinimapMarker marker)
    {
        _markers.Remove(marker);
    }

    public void SetZoom(float zoom)
    {
        _zoomLevel = Mathf.Clamp(zoom, _minZoom, _maxZoom);
    }

    public void ZoomIn(float amount) => SetZoom(_zoomLevel - amount);
    public void ZoomOut(float amount) => SetZoom(_zoomLevel + amount);
}
