using UnityEngine;
using System.Collections;

namespace SpecialMoveCards
{
    /// <summary>
    /// Handles world pickup visuals and behavior for a card: hover, rotate, glow, and pickup.
    /// Expect a trigger collider and optionally a Rigidbody set to kinematic.
    /// </summary>
    [RequireComponent(typeof(Collider))]
    public class CardBehaviour : MonoBehaviour
    {
        [SerializeField] private CardData cardData;
        [Header("Visual References")]
        [Tooltip("Renderer(s) that should have emissive color applied.")]
        [SerializeField] private Renderer[] emissiveRenderers;
    [Tooltip("Optional glow mesh (cube/cylinder/etc) used for volumetric-looking glow.")]
    [SerializeField] private Transform glowCube; // kept for backward-compat; any mesh child works
    [Tooltip("Optional explicit renderer for the glow mesh. If assigned, takes priority over 'glowCube'.")]
    [SerializeField] private Renderer glowRenderer;
        [Tooltip("Optional light to boost bloom.")]
        [SerializeField] private Light glowLight;

    [Header("Glow Sync")]
    [Tooltip("If true, reads emission color from the first emissive renderer's material and uses it for glow, without overriding the material. If false, uses CardData color to set emission on the renderers.")]
    [SerializeField] private bool deriveGlowFromMaterial = true;
    [Tooltip("Scales the glow intensity derived from material or CardData.")]
    [SerializeField] private float glowIntensityMultiplier = 1f;

        [Header("Motion")]
        [SerializeField] private float defaultHoverAmplitude = 0.25f;
        [SerializeField] private float defaultHoverSpeed = 1.0f;
        [SerializeField] private float defaultRotationSpeed = 35f;

        private Vector3 basePos;
        private float hoverPhase;
        private MaterialPropertyBlock mpb;
        private Collider trigger;
    private Color baseEmissive = Color.white;

    [Header("Glow Pulse (Optional)")]
    [SerializeField] private bool pulseGlow = false;
    [SerializeField] private float pulseSpeed = 2f;
    [SerializeField, Range(0f, 2f)] private float pulseAmplitude = 0.25f;

        public CardData Data => cardData;

        private void Reset()
        {
            var col = GetComponent<Collider>();
            if (col) col.isTrigger = true;
        }

        private void Awake()
        {
            // Skip if card system is disabled globally - destroy this card
            if (CardSpawner.CARD_SYSTEM_DISABLED)
            {
                Destroy(gameObject);
                return;
            }
            
            trigger = GetComponent<Collider>();
            if (trigger) trigger.isTrigger = true;
            EnsureMaterialPropertyBlock();
            basePos = transform.position;
            ApplyVisuals();
        }

        private void OnValidate()
        {
            if (Application.isPlaying) return;
            EnsureMaterialPropertyBlock();
            ApplyVisuals();
        }

        private void Update()
        {
            float amp = (cardData && cardData.hoverAmplitude > 0f) ? cardData.hoverAmplitude : defaultHoverAmplitude;
            float spd = (cardData && cardData.hoverSpeed > 0f) ? cardData.hoverSpeed : defaultHoverSpeed;
            float rot = (cardData && cardData.rotationSpeed > 0f) ? cardData.rotationSpeed : defaultRotationSpeed;

            hoverPhase += spd * Time.deltaTime;
            float offset = Mathf.Sin(hoverPhase) * amp;
            transform.position = basePos + Vector3.up * offset;
            transform.Rotate(Vector3.up, rot * Time.deltaTime, Space.World);

            // Optional pulsing for volumetric glow look
            if (pulseGlow)
            {
                float f = 1f + Mathf.Sin(Time.time * pulseSpeed) * pulseAmplitude;
                Color current = baseEmissive * f;
                ApplyGlowOnly(current);
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            // Look for a PlayerPocket on the other object or its parents
            var pocket = other.GetComponentInParent<PlayerPocket>();
            if (pocket == null) return;

            if (pocket.TryAddCard(cardData))
            {
                if (cardData && cardData.particlePrefab)
                {
                    Instantiate(cardData.particlePrefab, transform.position, Quaternion.identity);
                }
                Destroy(gameObject);
            }
        }

        private void ApplyVisuals()
        {
            EnsureMaterialPropertyBlock();

            // Determine target emissive color
            Color emissive;
            if (deriveGlowFromMaterial && TryGetMaterialEmissionColor(out emissive))
            {
                emissive *= glowIntensityMultiplier;
            }
            else
            {
                Color c = cardData ? cardData.color : Color.white;
                float intensity = cardData ? cardData.emissionIntensity : 2.5f;
                emissive = c * Mathf.LinearToGammaSpace(intensity) * glowIntensityMultiplier;

                // Only in this branch we override renderer emission to match CardData
                if (emissiveRenderers != null)
                {
                    for (int i = 0; i < emissiveRenderers.Length; i++)
                    {
                        var r = emissiveRenderers[i];
                        if (r == null) continue;
                        r.GetPropertyBlock(mpb);
                        mpb.SetColor("_EmissionColor", emissive);
                        r.SetPropertyBlock(mpb);
                    }
                }
            }

            baseEmissive = emissive; // store for pulse updates
            ApplyGlowOnly(emissive);
        }

        private void ApplyGlowOnly(Color emissive)
        {
            EnsureMaterialPropertyBlock();

            // Prefer explicit glowRenderer if provided
            Renderer targetRend = glowRenderer;
            if (targetRend == null && glowCube != null)
                targetRend = glowCube.GetComponent<Renderer>();

            if (targetRend)
            {
                targetRend.GetPropertyBlock(mpb);
                mpb.SetColor("_EmissionColor", emissive);
                targetRend.SetPropertyBlock(mpb);
            }

            if (glowLight)
            {
                Color lightColor = new Color(Mathf.Clamp01(emissive.r), Mathf.Clamp01(emissive.g), Mathf.Clamp01(emissive.b));
                glowLight.color = lightColor;
                glowLight.intensity = Mathf.Max(1.5f, emissive.maxColorComponent * 2.5f);
                glowLight.range = 3f;
            }
        }

        private bool TryGetMaterialEmissionColor(out Color color)
        {
            color = Color.black;
            if (emissiveRenderers == null) return false;

            // Common property names across pipelines
            string[] props = { "_EmissionColor", "_EmissiveColor", "_EmissiveColorLDR" };

            for (int i = 0; i < emissiveRenderers.Length; i++)
            {
                var r = emissiveRenderers[i];
                if (r == null) continue;
                var mat = r.sharedMaterial != null ? r.sharedMaterial : r.material;
                if (mat == null) continue;
                for (int p = 0; p < props.Length; p++)
                {
                    string prop = props[p];
                    if (mat.HasProperty(prop))
                    {
                        color = mat.GetColor(prop);
                        return true;
                    }
                }
            }
            return false;
        }

        /// <summary>Assign the data at runtime for generic prefabs.</summary>
        public void SetData(CardData data)
        {
            cardData = data;
            ApplyVisuals();
        }

        private void EnsureMaterialPropertyBlock()
        {
            if (mpb == null)
            {
                mpb = new MaterialPropertyBlock();
            }
        }
    }
}
