using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// Composant UI qui crée une image avec des coins arrondis.
/// Utilise un shader personnalisé pour le rendu des coins arrondis.
/// </summary>
[RequireComponent(typeof(Image))]
[ExecuteAlways]
public class RoundedCornersImage : MonoBehaviour
{
    [Header("Corner Radius")]
    [SerializeField, Range(0f, 200f)]
    private float _cornerRadius = 40f;
    
    [Header("Individual Corner Radii (optionnel)")]
    [SerializeField] private bool useIndividualCorners = false;
    [SerializeField, Range(0f, 200f)] private float topLeftRadius = 40f;
    [SerializeField, Range(0f, 200f)] private float topRightRadius = 40f;
    [SerializeField, Range(0f, 200f)] private float bottomLeftRadius = 40f;
    [SerializeField, Range(0f, 200f)] private float bottomRightRadius = 40f;
    
    [Header("Shader (pour WebGL)")]
    [SerializeField] private Shader roundedCornersShader;
    
    private Image _image;
    private Material _material;
    private static Shader _cachedShader;
    private static readonly int RadiusProperty = Shader.PropertyToID("_Radius");
    private static readonly int SizeProperty = Shader.PropertyToID("_Size");
    private static readonly int CornersProperty = Shader.PropertyToID("_Corners");
    
    public float cornerRadius
    {
        get => _cornerRadius;
        set
        {
            _cornerRadius = Mathf.Max(0, value);
            UpdateCornerRadius();
        }
    }
    
    void OnEnable()
    {
        _image = GetComponent<Image>();
        SetupMaterial();
        UpdateCornerRadius();
    }
    
    void OnDisable()
    {
        CleanupMaterial();
    }
    
    void OnDestroy()
    {
        CleanupMaterial();
    }
    
    void OnRectTransformDimensionsChange()
    {
        UpdateCornerRadius();
    }
    
    void OnValidate()
    {
        if (_image == null) _image = GetComponent<Image>();
        UpdateCornerRadius();
    }
    
    void SetupMaterial()
    {
        if (_image == null) return;
        
        // Utiliser le shader référencé, sinon chercher dans le cache, sinon Shader.Find
        Shader roundedShader = roundedCornersShader;
        
        if (roundedShader == null && _cachedShader != null)
        {
            roundedShader = _cachedShader;
        }
        
        if (roundedShader == null)
        {
            // Chercher le shader par son nom
            roundedShader = Shader.Find("UI/RoundedCorners");
            if (roundedShader != null)
            {
                _cachedShader = roundedShader;
            }
        }
        
        if (roundedShader == null)
        {
            // Charger depuis Resources (fonctionne en WebGL car le shader est inclus)
            roundedShader = Resources.Load<Shader>("Shaders/RoundedCorners");
            if (roundedShader != null)
            {
                _cachedShader = roundedShader;
                Debug.Log("[RoundedCornersImage] Shader chargé depuis Resources");
            }
        }
        
        if (roundedShader == null)
        {
            Debug.LogWarning("[RoundedCornersImage] Shader UI/RoundedCorners introuvable!");
            return;
        }
        
        if (!roundedShader.isSupported)
        {
            // Le shader n'est pas disponible ou pas supporté (WebGL?)
            // Pas de warning pour éviter le spam dans la console
            return;
        }
        
        // Créer un matériau unique pour cette instance
        _material = new Material(roundedShader);
        _material.hideFlags = HideFlags.HideAndDontSave;
        _image.material = _material;
    }
    
    void CleanupMaterial()
    {
        if (_material != null)
        {
            if (Application.isPlaying)
                Destroy(_material);
            else
                DestroyImmediate(_material);
            _material = null;
        }
        
        if (_image != null)
        {
            _image.material = null;
        }
    }
    
    void UpdateCornerRadius()
    {
        if (_material == null || _image == null) return;
        
        RectTransform rectTransform = _image.rectTransform;
        Vector2 size = rectTransform.rect.size;
        
        // Limiter le rayon au maximum possible
        float maxRadius = Mathf.Min(size.x, size.y) / 2f;
        float clampedRadius = Mathf.Min(_cornerRadius, maxRadius);
        
        _material.SetFloat(RadiusProperty, clampedRadius);
        _material.SetVector(SizeProperty, new Vector4(size.x, size.y, 0, 0));
        
        if (useIndividualCorners)
        {
            _material.SetVector(CornersProperty, new Vector4(
                Mathf.Min(topLeftRadius, maxRadius),
                Mathf.Min(topRightRadius, maxRadius),
                Mathf.Min(bottomRightRadius, maxRadius),
                Mathf.Min(bottomLeftRadius, maxRadius)
            ));
        }
        else
        {
            _material.SetVector(CornersProperty, new Vector4(
                clampedRadius, clampedRadius, clampedRadius, clampedRadius
            ));
        }
    }
    
    /// <summary>
    /// Définit les rayons individuels pour chaque coin
    /// </summary>
    public void SetCornerRadii(float topLeft, float topRight, float bottomRight, float bottomLeft)
    {
        useIndividualCorners = true;
        topLeftRadius = topLeft;
        topRightRadius = topRight;
        bottomRightRadius = bottomRight;
        bottomLeftRadius = bottomLeft;
        UpdateCornerRadius();
    }
    
    /// <summary>
    /// Définit un rayon uniforme pour tous les coins
    /// </summary>
    public void SetUniformRadius(float radius)
    {
        useIndividualCorners = false;
        _cornerRadius = radius;
        UpdateCornerRadius();
    }
}

