using UnityEngine;

namespace eagle {
    /// <summary>
    /// Creates an epidemic particle effect with skulls rising and green haze.
    /// </summary>
    [RequireComponent(typeof(RectTransform))]
    public class EpidemicEffect : MonoBehaviour {
        [Header("Skull Settings")]
        public Material skullMaterial;
        public float skullEmitRate = 1.5f;
        public float skullRiseSpeed = 25f;
        public float skullLifetime = 3f;
        public float skullSize = 12f;
        public float skullSway = 8f;
        public Color skullColor = Color.white;

        [Header("Haze Settings")]
        public Material hazeMaterial;
        public float hazeEmitRate = 5f;
        public float hazeSpeed = 8f;
        public float hazeLifetime = 4f;
        public float hazeSize = 40f;
        public Color hazeColor = new Color(0.4f, 0.55f, 0.35f, 0.25f);

        private ParticleSystem _skullSystem;
        private ParticleSystem _hazeSystem;
        private Material _skullMatInstance;
        private Material _hazeMatInstance;

        void Awake() { SetupParticleSystems(); }

        private void SetupParticleSystems() {
            // Create haze first (renders behind skulls)
            var hazeObj = new GameObject("HazeEffect");
            hazeObj.transform.SetParent(transform, false);
            _hazeSystem = hazeObj.AddComponent<ParticleSystem>();
            SetupHazeSystem();

            // Create skull particle system
            var skullObj = new GameObject("SkullEffect");
            skullObj.transform.SetParent(transform, false);
            _skullSystem = skullObj.AddComponent<ParticleSystem>();
            SetupSkullSystem();
        }

        private void SetupSkullSystem() {
            var main = _skullSystem.main;
            main.playOnAwake = true;
            main.loop = true;
            main.startLifetime = skullLifetime;
            main.startSpeed = 0f;
            main.startSize = skullSize;
            main.startColor = skullColor;
            main.startRotation = new ParticleSystem.MinMaxCurve(-0.2f, 0.2f);  // Slight random tilt
            main.simulationSpace = ParticleSystemSimulationSpace.Local;
            main.scalingMode = ParticleSystemScalingMode.Hierarchy;
            main.maxParticles = 20;

            var emission = _skullSystem.emission;
            emission.enabled = true;
            emission.rateOverTime = skullEmitRate;

            // Emit from a small area at the base with random direction for sway
            var shape = _skullSystem.shape;
            shape.enabled = true;
            shape.shapeType = ParticleSystemShapeType.Circle;
            shape.radius = 15f;
            shape.rotation = new Vector3(-90f, 0f, 0f);
            shape.randomDirectionAmount = 0.3f;  // Add horizontal sway variation

            // Rise upward with horizontal drift for swaying motion
            var velocityOverLifetime = _skullSystem.velocityOverLifetime;
            velocityOverLifetime.enabled = true;
            velocityOverLifetime.space = ParticleSystemSimulationSpace.Local;
            // Use constant mode for all axes to avoid mode mismatch
            velocityOverLifetime.x = skullSway;  // More horizontal drift
            velocityOverLifetime.y = skullRiseSpeed;
            velocityOverLifetime.z = 0f;

            // Grow as they rise (start at 1/4 size, end at full size)
            var sizeOverLifetime = _skullSystem.sizeOverLifetime;
            sizeOverLifetime.enabled = true;
            sizeOverLifetime.size = new ParticleSystem.MinMaxCurve(
                    1f,
                    new AnimationCurve(new Keyframe(0f, 0.25f), new Keyframe(1f, 1f)));

            // Fade out as they rise
            var colorOverLifetime = _skullSystem.colorOverLifetime;
            colorOverLifetime.enabled = true;
            var gradient = new Gradient();
            gradient.SetKeys(
                    new GradientColorKey[] {
                        new GradientColorKey(Color.white, 0f),
                        new GradientColorKey(Color.white, 0.7f),
                        new GradientColorKey(Color.white, 1f)
                    },
                    new GradientAlphaKey[] {
                        new GradientAlphaKey(0f, 0f),
                        new GradientAlphaKey(1f, 0.1f),
                        new GradientAlphaKey(1f, 0.6f),
                        new GradientAlphaKey(0f, 1f)
                    });
            colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient);

            // Disable rotation over lifetime (causes spinning)
            var rotationOverLifetime = _skullSystem.rotationOverLifetime;
            rotationOverLifetime.enabled = false;

            // Use noise module for gentle rocking/swaying rotation
            var noise = _skullSystem.noise;
            noise.enabled = true;
            noise.separateAxes = true;
            noise.strengthX = 0f;  // No position noise
            noise.strengthY = 0f;
            noise.strengthZ = 0f;
            noise.rotationAmount = 0.2f;  // ~11 degrees of rotation sway
            noise.frequency = 0.5f;       // Slow oscillation
            noise.scrollSpeed = 0f;
            noise.damping = false;
            noise.octaveCount = 1;

            var renderer = _skullSystem.GetComponent<ParticleSystemRenderer>();
            if (renderer != null) {
                if (skullMaterial == null) {
                    Debug.LogError("[EpidemicEffect] skullMaterial is not assigned!");
                    return;
                }
                _skullMatInstance = new Material(skullMaterial);
                renderer.material = _skullMatInstance;
                renderer.sortingOrder = 101;
            }
        }

        private void SetupHazeSystem() {
            var main = _hazeSystem.main;
            main.playOnAwake = true;
            main.loop = true;
            main.startLifetime = hazeLifetime;
            main.startSpeed = hazeSpeed;
            main.startSize = new ParticleSystem.MinMaxCurve(hazeSize * 0.5f, hazeSize);
            main.startColor = hazeColor;
            main.simulationSpace = ParticleSystemSimulationSpace.Local;
            main.scalingMode = ParticleSystemScalingMode.Hierarchy;
            main.maxParticles = 30;

            var emission = _hazeSystem.emission;
            emission.enabled = true;
            emission.rateOverTime = hazeEmitRate;

            // Emit from ground area, spread outward and up
            var shape = _hazeSystem.shape;
            shape.enabled = true;
            shape.shapeType = ParticleSystemShapeType.Cone;
            shape.angle = 40f;
            shape.radius = 10f;
            shape.rotation = new Vector3(-90f, 0f, 0f);

            // Slow down over time
            var velocityOverLifetime = _hazeSystem.velocityOverLifetime;
            velocityOverLifetime.enabled = true;
            velocityOverLifetime.speedModifier = new ParticleSystem.MinMaxCurve(
                    1f,
                    new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0.2f)));

            // Grow and fade
            var sizeOverLifetime = _hazeSystem.sizeOverLifetime;
            sizeOverLifetime.enabled = true;
            sizeOverLifetime.size = new ParticleSystem.MinMaxCurve(
                    1f,
                    new AnimationCurve(new Keyframe(0f, 0.5f), new Keyframe(1f, 2f)));

            var colorOverLifetime = _hazeSystem.colorOverLifetime;
            colorOverLifetime.enabled = true;
            var gradient = new Gradient();
            gradient.SetKeys(
                    new GradientColorKey[] {
                        new GradientColorKey(Color.white, 0f),
                        new GradientColorKey(Color.white, 1f)
                    },
                    new GradientAlphaKey[] {
                        new GradientAlphaKey(0f, 0f),
                        new GradientAlphaKey(0.6f, 0.2f),
                        new GradientAlphaKey(0.6f, 0.5f),
                        new GradientAlphaKey(0f, 1f)
                    });
            colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient);

            var renderer = _hazeSystem.GetComponent<ParticleSystemRenderer>();
            if (renderer != null) {
                if (hazeMaterial == null) {
                    Debug.LogError("[EpidemicEffect] hazeMaterial is not assigned!");
                    return;
                }
                _hazeMatInstance = new Material(hazeMaterial);
                renderer.material = _hazeMatInstance;
                renderer.sortingOrder = 100;
            }
        }

        void OnDestroy() {
            if (_skullMatInstance != null) { Destroy(_skullMatInstance); }
            if (_hazeMatInstance != null) { Destroy(_hazeMatInstance); }
        }
    }
}
