using System.Collections;
using UnityEngine;

namespace eagle {
    /// <summary>
    /// Creates a fireworks particle effect for festival events.
    /// Rockets fly upward and burst into colorful explosions.
    /// </summary>
    [RequireComponent(typeof(RectTransform))]
    public class FireworksEffect : MonoBehaviour {
        [Header("Rocket Settings")]
        public float launchInterval = 2f;
        public float rocketSpeed = 80f;
        public float rocketLifetime = 0.8f;
        public float rocketSize = 6f;

        [Header("Burst Settings")]
        public int burstParticles = 40;
        public float burstSpeed = 50f;
        public float burstLifetime = 1.2f;
        public float burstGravity = 30f;

        [Header("Shader")]
        public Shader clipRectParticleShader;

        [Header("Colors")]
        public Color[] fireworkColors = {
            new Color(1f, 0.3f, 0.3f),  // Red
            new Color(1f, 0.8f, 0.2f),  // Gold
            new Color(0.3f, 0.8f, 1f),  // Blue
            new Color(0.3f, 1f, 0.3f),  // Green
            new Color(1f, 0.5f, 1f),    // Pink
            new Color(1f, 1f, 0.4f)     // Yellow
        };

        private ParticleSystem _rocketSystem;
        private ParticleSystem _burstSystem;
        private float _timer;

        void Awake() { SetupParticleSystems(); }

        private void SetupParticleSystems() {
            // Create rocket particle system on child GameObject (not on RectTransform)
            var rocketObj = new GameObject("RocketEffect");
            rocketObj.transform.SetParent(transform, false);
            _rocketSystem = rocketObj.AddComponent<ParticleSystem>();
            SetupRocketSystem();

            // Create burst particle system (separate, not sub-emitter)
            var burstObj = new GameObject("BurstEffect");
            burstObj.transform.SetParent(transform, false);
            _burstSystem = burstObj.AddComponent<ParticleSystem>();
            SetupBurstSystem();

            StartCoroutine(LaunchSequence());
        }

        private void SetupRocketSystem() {
            var main = _rocketSystem.main;
            main.playOnAwake = false;
            main.loop = false;
            main.startLifetime = rocketLifetime;
            main.startSpeed = 0f;  // We set velocity explicitly in EmitParams
            main.startSize = rocketSize;
            main.simulationSpace = ParticleSystemSimulationSpace.Local;
            main.scalingMode = ParticleSystemScalingMode.Hierarchy;
            main.maxParticles = 10;
            main.startColor = new Color(1f, 0.9f, 0.6f);  // Bright orange/yellow

            var emission = _rocketSystem.emission;
            emission.enabled = false;

            // Disable shape - we set velocity explicitly in EmitParams to avoid Z movement
            var shape = _rocketSystem.shape;
            shape.enabled = false;

            // Add slight arc to rocket path (gravity slowing upward movement)
            var velocityOverLifetime = _rocketSystem.velocityOverLifetime;
            velocityOverLifetime.enabled = true;
            velocityOverLifetime.space = ParticleSystemSimulationSpace.Local;
            velocityOverLifetime.y = new ParticleSystem.MinMaxCurve(-20f);  // Slight downward pull

            // Rocket trail
            var trails = _rocketSystem.trails;
            trails.enabled = true;
            trails.ratio = 1f;
            trails.lifetime = new ParticleSystem.MinMaxCurve(0.4f);
            trails.minVertexDistance = 2f;
            trails.worldSpace = false;
            trails.dieWithParticles = true;
            trails.widthOverTrail = new ParticleSystem.MinMaxCurve(
                    1f,
                    new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0.3f)));
            trails.colorOverLifetime = new ParticleSystem.MinMaxGradient(
                    new Color(1f, 0.8f, 0.3f),
                    new Color(1f, 0.5f, 0.1f));

            var renderer = _rocketSystem.GetComponent<ParticleSystemRenderer>();
            if (renderer != null) {
                var shader = clipRectParticleShader != null
                                     ? clipRectParticleShader
                                     : Shader.Find("Particles/Standard Unlit");
                if (shader != null) {
                    var mat = new Material(shader);
                    renderer.material = mat;
                    renderer.trailMaterial = mat;
                }
                renderer.sortingOrder = 100;
            }
        }

        private void SetupBurstSystem() {
            var main = _burstSystem.main;
            main.playOnAwake = false;
            main.loop = false;
            main.startLifetime = burstLifetime;
            main.startSpeed = burstSpeed;
            main.startSize = new ParticleSystem.MinMaxCurve(4f, 7f);
            main.simulationSpace = ParticleSystemSimulationSpace.Local;
            main.scalingMode = ParticleSystemScalingMode.Hierarchy;
            main.maxParticles = 200;

            var emission = _burstSystem.emission;
            emission.enabled = false;

            var shape = _burstSystem.shape;
            shape.enabled = true;
            shape.shapeType = ParticleSystemShapeType.Sphere;
            shape.radius = 1f;

            // Gravity pulls burst particles down
            var velocityOverLifetime = _burstSystem.velocityOverLifetime;
            velocityOverLifetime.enabled = true;
            velocityOverLifetime.y = new ParticleSystem.MinMaxCurve(-burstGravity);

            // Disable colorOverLifetime to preserve startColor from EmitParams
            var colorOverLifetime = _burstSystem.colorOverLifetime;
            colorOverLifetime.enabled = false;

            // Shrink over lifetime
            var sizeOverLifetime = _burstSystem.sizeOverLifetime;
            sizeOverLifetime.enabled = true;
            sizeOverLifetime.size = new ParticleSystem.MinMaxCurve(
                    1f,
                    new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0.2f)));

            // Sparkle trails on burst particles
            var trails = _burstSystem.trails;
            trails.enabled = true;
            trails.ratio = 0.4f;
            trails.lifetime = new ParticleSystem.MinMaxCurve(0.2f);
            trails.minVertexDistance = 1f;
            trails.worldSpace = false;
            trails.dieWithParticles = true;
            trails.widthOverTrail = new ParticleSystem.MinMaxCurve(
                    1f,
                    new AnimationCurve(new Keyframe(0f, 0.6f), new Keyframe(1f, 0f)));
            trails.inheritParticleColor = true;

            var burstRenderer = _burstSystem.GetComponent<ParticleSystemRenderer>();
            if (burstRenderer != null) {
                var shader = clipRectParticleShader != null
                                     ? clipRectParticleShader
                                     : Shader.Find("Particles/Standard Unlit");
                if (shader != null) {
                    var mat = new Material(shader);
                    burstRenderer.material = mat;
                    burstRenderer.trailMaterial = mat;
                }
                burstRenderer.sortingOrder = 101;
            }
        }

        private IEnumerator LaunchSequence() {
            while (true) {
                LaunchRocket();
                yield return new WaitForSeconds(launchInterval);
            }
        }

        private void LaunchRocket() {
            if (_rocketSystem == null || _burstSystem == null) { return; }

            Color burstColor = fireworkColors[Random.Range(0, fireworkColors.Length)];

            // Launch rocket with explicit velocity and color
            // X: random variation for slight angle, Y: upward, Z: must be negative to render
            float xVariation = Random.Range(-15f, 15f);
            var rocketParams = new ParticleSystem.EmitParams();
            rocketParams.position = Vector3.zero;
            rocketParams.velocity = new Vector3(xVariation, rocketSpeed, -1f);
            rocketParams.startColor = new Color(1f, 0.9f, 0.5f);  // Bright yellow-orange
            _rocketSystem.Emit(rocketParams, 1);

            // Schedule burst at rocket death position
            StartCoroutine(EmitBurstAfterDelay(burstColor));
        }

        private IEnumerator EmitBurstAfterDelay(Color color) {
            // Wait for rocket to reach peak
            yield return new WaitForSeconds(rocketLifetime);

            // Calculate burst position (where rocket ended)
            Vector3 burstPosition = new Vector3(0f, rocketSpeed * rocketLifetime, 0f);

            // Move burst system to rocket's end position
            _burstSystem.transform.localPosition = burstPosition;

            // Emit particles with explicit color using EmitParams
            var emitParams = new ParticleSystem.EmitParams();
            emitParams.startColor = color;
            for (int i = 0; i < burstParticles; i++) { _burstSystem.Emit(emitParams, 1); }
        }
    }
}
